Theano With Python2.7:SGD多重损失

时间:2015-10-06 17:17:09

标签: python python-2.7 theano

在Theano被我称赞之后,我想我会用特定形式的SGD迈出第一步。我有一个参数向量theta,我想要优化我的损失函数返回一个向量,包含矩阵A和B之间的平方损失的列和。每个元素是一个特定维度的独立损失使用播放theta。应该更新Theta,以便下一次迭代每个维度的损失更低。我选择这个是因为数据(X,Y)是这样给出的。

现在教程说T.grad()应该用于获取更新的渐变。但T.grad不允许我计算非标量的梯度。教程(http://deeplearning.net/software/theano/tutorial/gradients.html)说'标量成本只能由毕业直接处理。阵列通过重复应用来处理。'所以我尝试(令人遗憾的是一个丑陋的尝试)来计算每个损失的梯度。如何计算多次损失的梯度?是否有一种干净,最佳实践方式?这是否正确?还有其他我应该考虑的事情吗?

马丁

import numpy
from theano import tensor as T
from theano import function
from theano import shared

alpha = 0.00001
theta = shared(numpy.random.rand(10), name='theta')
X = T.dmatrix(name='X')
Y = T.dmatrix(name='Y')
losses = T.sqr(theta * X - Y).sum(axis=0)

这就是它变得奇怪的地方: 因为T.grad(loss,theta)抛出TypeError:cost必须是标量。所以我得到了这个丑陋的尝试:

d_losses = [T.grad(losses[i], theta) for i in xrange(len(theta.get_value()))] 
updates = [(theta, theta - numpy.array(alpha) * d_losses)]

当我想编译它时,我得到了这个:

    >>> f = function(inputs=[A], outputs=loss, updates=updates)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/lib/python2.7/dist-packages/theano/compile/function.py", line 266, in function
    profile=profile)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 489, in pfunc
    no_default_updates=no_default_updates)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 202, in rebuild_collect_shared
    update_val = store_into.type.filter_variable(update_val)
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/type.py", line 206, in filter_variable
    other = self.Constant(type=self, data=other)
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/var.py", line 732, in __init__
    Constant.__init__(self, type, data, name)
  File "/usr/local/lib/python2.7/dist-packages/theano/gof/graph.py", line 443, in __init__
    self.data = type.filter(data)
  File "/usr/local/lib/python2.7/dist-packages/theano/tensor/type.py", line 115, in filter
    up_dtype = scal.upcast(self.dtype, data.dtype)
  File "/usr/local/lib/python2.7/dist-packages/theano/scalar/basic.py", line 67, in upcast
    rval = str(z.dtype)
AttributeError: 'float' object has no attribute 'dtype'

1 个答案:

答案 0 :(得分:1)

正如Mikael Rousson在评论中指出的那样,出于渐变的目的,您可能不需要处理单独的损失;只需将所有损失分量汇总到标量中,然后根据参数向量计算偏导数,得到梯度向量。

所以添加

loss = losses.sum()

或直接定义标量损失

loss = T.sqr(theta * X - Y).sum()

然后使用

d_losses = T.grad(loss, theta)
updates = [(theta, theta - alpha * d_losses)]

d_losses[0]等于loss相对于theta[0]的偏导数,但loss中涉及theta[0]的唯一项是总和的组成部分losses的第一个元素,所以它也等于losses[0]相对于theta[0]的偏导数,这正是你想要的,我想。