【问题标题】:Defining a gradient with respect to a subtensor in Theano在 Theano 中定义相对于子张量的梯度
【发布时间】:2014-06-28 15:49:52
【问题描述】:

我有一个关于 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])     ]])

(这里的代码和字典是共享张量变量)。 Theano 对此很不满意,特别是定义

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

我得到的错误信息是:theano.gradient.DisconnectedInputError: grad 方法被要求计算一个变量的梯度,该变量不属于成本计算图的一部分,或者只被使用由不可微的运算符:Subtensor{int64}.0

我猜它想要一个符号变量而不是代码[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],然后区分 w.r.t. grad_var?
  • 感谢您的建议。问题是,如果 grad_var 是一个符号 var (T.tensor3),那么区分是有效的,但更新不起作用,因为更新需要共享变量。
  • 如果你保留 grad_var,并将 set_subtensor 设为一个单独的变量(根据stackoverflow.com/questions/15917849/…)而不是在更新函数中分配,这会导致同样的错误吗?
  • Kyle -- 谢谢似乎效果很好!一百万谢谢!!现在是一个 Stackoverflow 问题——我如何将问题标记为已解决并给予您信任?
  • 我添加了一个答案 - 如果这是一个正确的总结,请告诉我。如果您有更正的代码,最好发布它。

标签: python machine-learning theano


【解决方案1】:

总结调查结果:

分配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 需要一个共享变量,但如果共享变量是在需要它的函数中 创建 时会出现问题。

很高兴这对你有用!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-30
    • 2016-11-06
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 2014-11-11
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多