Theano With Python2.7: SGD 多次损失
Theano With Python2.7: SGD with multiple losses
在 Theano 受到表扬后,我想我会用一种特定形式的 SGD 迈出我的第一步。我有一个我想优化的参数向量 theta 我的损失函数 return 一个包含矩阵 A 和 B 之间的平方损失的列和的向量。每个元素都是特定维度的独立损失使用广播的 theta。 Theta 应该更新,以便下一次迭代每个维度的损失更低。我选择这个是因为数据(X,Y)是这样给出的。
现在教程说 T.grad() 应该用于获取更新的梯度。但是 T.grad 不允许我计算非标量的梯度。教程 (http://deeplearning.net/software/theano/tutorial/gradients.html) 说 'Scalar costs only can be directly handled by grad. Arrays are handled through repeated applications.' 所以我尝试(不可否认是一个丑陋的尝试)计算每个损失的梯度。如何计算多重损失的梯度?是否有一种干净的最佳实践方法?那是正确的吗?还有什么我应该考虑的吗?
马丁
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'
正如 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]
的偏导数,我认为这正是你想要的。
在 Theano 受到表扬后,我想我会用一种特定形式的 SGD 迈出我的第一步。我有一个我想优化的参数向量 theta 我的损失函数 return 一个包含矩阵 A 和 B 之间的平方损失的列和的向量。每个元素都是特定维度的独立损失使用广播的 theta。 Theta 应该更新,以便下一次迭代每个维度的损失更低。我选择这个是因为数据(X,Y)是这样给出的。
现在教程说 T.grad() 应该用于获取更新的梯度。但是 T.grad 不允许我计算非标量的梯度。教程 (http://deeplearning.net/software/theano/tutorial/gradients.html) 说 'Scalar costs only can be directly handled by grad. Arrays are handled through repeated applications.' 所以我尝试(不可否认是一个丑陋的尝试)计算每个损失的梯度。如何计算多重损失的梯度?是否有一种干净的最佳实践方法?那是正确的吗?还有什么我应该考虑的吗?
马丁
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'
正如 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]
的偏导数,我认为这正是你想要的。