【问题标题】:Theano gradient of subtensor子张量的 Theano 梯度
【发布时间】:2016-06-01 01:35:26
【问题描述】:

我尝试通过扫描操作手动计算标量成本对权重向量的梯度。然而,这不起作用,并且总是返回 SubTensor 不可微分的错误

为了确保可以计算梯度:

T.grad(cost, p2) 

完美运行。这意味着 p2 没有与成本脱节。但是,当我尝试以下操作时:

 def differentiate_element(i,p2,c):
            p2element=p2[i]
            return T.grad(c,p2element)
 h2, h2_updates = theano.scan(differentiate_element,
                  sequences=T.arange(p2.shape[0]), non_sequences=[p2, cost])

我收到错误'theano.gradient.DisconnectedInputError: grad 方法被要求计算一个变量的梯度,该变量不是成本计算图的一部分,或者仅由不可微的运算符使用:子张量{int64}.0'

之前已经有人问过这个问题:Defining a gradient with respect to a subtensor in Theano,但没有得到满意的回答。也就是说,如图所示将 p2[i] 分配给它自己的变量并不能解决问题。

将选项 disconnected_inputs='ignore' 添加到内部循环实际上会消除错误,但不再产生正确的输出,如下面的简短示例所示:

import numpy
import theano
import theano.tensor as T
p2=theano.shared(name="P2",value=numpy.zeros(100,dtype=theano.config.floatX),borrow=True)
x=T.scalar('x')
cost=T.sum(x*p2)

gradient=T.grad(cost,p2)

def differentiate_element(i, p2, c):
    p2element = p2[i]
    return T.grad(c, p2element, disconnected_inputs='ignore')

gradient2, grad2_updates = theano.scan(differentiate_element,
                 sequences=T.arange(p2.shape[0]),
                 non_sequences=[p2, cost])

f=theano.function([x],gradient)
g=theano.function([x],gradient2,updates=grad2_updates)

print(f(20))
print(g(20))

第一个,打印一个包含 20 的数组。第二个打印一个包含 0 的数组。

【问题讨论】:

  • 为什么你需要像这样计算梯度而不是在扫描函数之外?如果您有特定的理由这样做,请提供更广泛的代码示例
  • 这是一个例子。如果我能够计算粗麻布对角线,这是基本步骤之一。
  • 啊,好吧,我明白了,因为它有巨大的计算成本,你只想计算你需要的梯度而不是整个巨大的东西。

标签: theano


【解决方案1】:

与其尝试在扫描函数中为每个子张量计算梯度,不如只预先计算梯度,然后遍历所需的梯度

p2_grad = T.grad(cost,p2)

def differentiate_element(i,p2):
            p2element=p2[i]
            return p2element

p2elements_grads, h2_updates = theano.scan(differentiate_element,
                  sequences=T.arange(p2_grad.shape[0]), non_sequences=[p2_grad])

编辑

由于计算 Hessian 对角线的主要问题是您在任何情况下都不希望计算整个 Hessian 并浪费计算资源,因此您可以采取措施避免 Disconnected inputs 错误,将 disconnected_inputs='ignore' 关键字参数添加到T.grad

def differentiate_element(i, p2, c):
    p2element = p2[i]
    return T.grad(c, p2element, disconnected_inputs='ignore')

h2, h2_updates = theano.scan(differentiate_element,
                             sequences=T.arange(p2.shape[0]), non_sequences=[p2, cost])

【讨论】:

  • 但是为什么对 p2 的单个元素的扫描不起作用呢?
  • 但是即使没有 disconnected_inputs 这样的扫描也不起作用。它抱怨子张量不可微。
  • 您能否提供一个完整的代码示例来重现您的错误?因为就我而言,我没有收到任何错误。
  • 嘿,wtf。我也没有收到错误。让我进一步深入研究这一点。有没有什么简单的方法可以打印出东西的确切类型?
  • 您向所有输入添加一个测试值,然后在“图形构建”的每一步中,您都可以看到每个计算的值。阅读this 了解更多详细信息。
猜你喜欢
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 1970-01-01
相关资源
最近更新 更多