【问题标题】:Theano With Python2.7: SGD with multiple lossesTheano 与 Python2.7:具有多重损失的 SGD
【发布时间】:2015-10-07 15:19:02
【问题描述】:

在 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 must be a scalar。所以我得到了这个丑陋的尝试:

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'

【问题讨论】:

  • 为什么要多亏?你可以有一个标量损失并导出 w.r.t.到 theta 的每个组成部分。
  • 所以你的意思是 d_loss = [T.grad(loss,theta[i]) for i in xrange(len(theta.get_value()))] ?或者我该怎么做?最初的想法是每个特征都有它自己的损失,我想捕捉它。

标签: python python-2.7 theano


【解决方案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] 的偏导数,我认为这正是您想要的。

【讨论】:

  • 这是有道理的。谢谢!
猜你喜欢
  • 2016-11-24
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 2016-03-04
  • 2017-10-28
  • 2021-02-26
  • 2019-09-07
相关资源
最近更新 更多