在Theano中定义相对于子张量的梯度

我有一个关于Theano的概念上简单的问题,但我一直找不到答案(我得承认,尽管花了很多时间在教程上,我仍然不太理解Theano中的共享变量是如何工作的)。

我正在尝试实现一个“反卷积网络”;具体来说,我有一个输入的3阶张量(每个输入是一个2D图像)和一个代码的4阶张量;对于第i个输入,codes[i]代表一组编码词,这些编码词共同编码输入i。

我一直在努力弄清楚如何对这些编码词进行梯度下降。以下是我代码的相关部分:

idx = T.lscalar()pre_loss_conv = conv2d(input = codes[idx].dimshuffle('x', 0, 1,2),                       filters = dicts.dimshuffle('x', 0,1, 2),                       border_mode = 'valid')loss_conv = pre_loss_conv.reshape((pre_loss_conv.shape[2], pre_loss_conv.shape[3]))loss_in = inputs[idx]loss = T.sum(1./2.*(loss_in - loss_conv)**2) del_codes = T.grad(loss, codes[idx])delc_fn = function([idx], del_codes)train_codes = function([input_index], loss, updates = [    [codes, T.set_subtensor(codes[input_index], codes[input_index] -                             learning_rate*del_codes[input_index])     ]])

(这里的codes和dicts是共享的张量变量)。Theano对这个不满意,特别是定义

del_codes = T.grad(loss, codes[idx])

我得到的错误信息是:theano.gradient.DisconnectedInputError: grad方法被要求计算相对于成本计算图中不存在的变量的梯度,或者仅被非可微算子使用:Subtensor{int64}.0

我猜它想要一个符号变量而不是codes[idx];但接下来我不确定如何连接所有部分以达到预期效果。我猜我需要将最后一行改为类似于

learning_rate*del_codes)     ]])

有人能给我一些关于如何正确定义这个函数的建议吗?我觉得我可能错过了关于使用Theano的一些基本知识,但我不确定是什么。

提前感谢!

-@

更新:Kyle的建议非常有效。这是我使用的具体代码

current_codes = T.tensor3('current_codes')current_codes = codes[input_index]pre_loss_conv = conv2d(input = current_codes.dimshuffle('x', 0, 1,2),                       filters = dicts.dimshuffle('x', 0,1, 2),                       border_mode = 'valid')loss_conv = pre_loss_conv.reshape((pre_loss_conv.shape[2], pre_loss_conv.shape[3]))loss_in = inputs[input_index]loss = T.sum(1./2.*(loss_in - loss_conv)**2)  del_codes = T.grad(loss, current_codes)train_codes = function([input_index], loss)train_dicts = theano.function([input_index], loss, updates = [[dicts, dicts - learning_rate*del_dicts]])codes_update = ( codes, T.set_subtensor(codes[input_index], codes[input_index] - learning_rate*del_codes) )codes_update_fn = function([input_index], updates = [codes_update])for i in xrange(num_inputs):     current_loss = train_codes(i)     codes_update_fn(i)

回答:

总结发现如下:

grad_var = codes[idx]赋值,然后创建一个新变量,例如:subgrad = T.set_subtensor(codes[input_index], codes[input_index] - learning_rate*del_codes[input_index])

然后调用train_codes = function([input_index], loss, updates = [[codes, subgrad]])

似乎解决了问题。一般来说,我尽量为尽可能多的东西创建变量。有时试图在一个语句中做太多事情会导致棘手的问题,而且以后也难以调试和理解!此外,在这种情况下,我认为theano需要一个共享变量,但如果共享变量是在需要它的函数内部创建的,则会出现问题。

很高兴这对你有用!

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注