我有一个简单和工作的多层感知器在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)
,则会出现以下错误:
我不明白为什么成本(函数)不是标量的。只是为了测试我试过:
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)
我想问题是我看不出余弦距离函数和我的中误差函数有什么不同。我错过了什么?在
不同之处在于,
mse
函数在不指定轴的情况下计算T.mean
,因此给出了张量中所有项的平均值,不管张量是什么形状。相比之下,您的第一个cos
函数根本没有聚合,因此返回值将具有与T.dot(y,self.y_pred)
相同的形状,即不是标量。在cos
函数的第二个版本中求和,该函数生成所需的标量,但这可能不是您希望它计算的内容,这取决于输入形状的语义。在第二个错误可能是由于您的
cos
函数中的错误:您不希望在分子中执行点积,即T.dot(y,self.y_pred)
,而是希望进行元素乘法,例如y * self.y_pred
这是我在Theano跑不同距离的代码。请注意,
_magnitude
和cosine
函数包含有助于避免NaN
或超出范围的值的调整。这类问题可能发生在向前传球或向后传球(坡度)中。在相关问题 更多 >
编程相关推荐