距离最小余弦

2024-05-16 03:06:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单和工作的多层感知器在Theano,有1个隐藏层和1个回归层,有2个输出。成本函数定义为均方误差函数。然而,在学习过程中,我现在想最小化两个向量之间的余弦距离,所以我想用余弦距离作为代价函数。下面是我当前实现的一些相关部分。在

import theano
import theano.tensor as T

class RegressionLayer(object):
    def __init__(self, input, n_in, n_out, W=None, b=None):
        # rest of __init__ left out for brevity

    def mse(self, y):
        return T.mean(T.sqr(y - self.y_pred))

    def cos(self, y):
        return 1. - (T.dot(y,self.y_pred) / (T.sqrt(T.sum(T.sqr(y)) * T.sum(T.sqr(self.y_pred)))))

如果将cost函数从mse(y)更改为cos(y),则会出现以下错误:

^{pr2}$

我不明白为什么成本(函数)不是标量的。只是为了测试我试过:

def cos(self, y):
    T.sum(1. - (T.dot(y,self.y_pred) / (T.sqrt(T.sum(T.sqr(y)) * T.sum(T.sqr(self.y_pred))))))

然后模型就建立起来了,但是我在训练中得到了一个尺寸不匹配的问题。在

ValueError: dimension mismatch in args to gemm (1,2)x(1,2)->(1,2)

我想问题是我看不出余弦距离函数和我的中误差函数有什么不同。我错过了什么?在


Tags: 函数inimportself距离initdeftheano
1条回答
网友
1楼 · 发布于 2024-05-16 03:06:51

不同之处在于,mse函数在不指定轴的情况下计算T.mean,因此给出了张量中所有项的平均值,不管张量是什么形状。相比之下,您的第一个cos函数根本没有聚合,因此返回值将具有与T.dot(y,self.y_pred)相同的形状,即不是标量。在cos函数的第二个版本中求和,该函数生成所需的标量,但这可能不是您希望它计算的内容,这取决于输入形状的语义。在

第二个错误可能是由于您的cos函数中的错误:您不希望在分子中执行点积,即T.dot(y,self.y_pred),而是希望进行元素乘法,例如y * self.y_pred

这是我在Theano跑不同距离的代码。请注意,_magnitudecosine函数包含有助于避免NaN或超出范围的值的调整。这类问题可能发生在向前传球或向后传球(坡度)中。在

import numpy
import theano.tensor as tt


def _squared_magnitude(x):
    return tt.sqr(x).sum(axis=-1)


def _magnitude(x):
    return tt.sqrt(tt.maximum(_squared_magnitude(x), numpy.finfo(x.dtype).tiny))


def cosine(x, y):
    return tt.clip((1 - (x * y).sum(axis=-1) / (_magnitude(x) * _magnitude(y))) / 2, 0, 1)


def euclidean(x, y):
    return _magnitude(x - y)


def squared_euclidean(x, y):
    return _squared_magnitude(x - y)

相关问题 更多 >