【问题标题】:Combining scalars and vectors in Theano for computing Hessian在 Theano 中结合标量和向量来计算 Hessian
【发布时间】:2015-12-13 18:41:07
【问题描述】:

我正在尝试使用 Theano 来计算函数关于向量以及几个标量的粗麻布(编辑:也就是说,我本质上希望将标量附加到我正在计算粗麻布的向量上)尊重)。这是一个最小的例子:

import theano
import theano.tensor as T
A = T.vector('A')
b,c = T.scalars('b','c')
y = T.sum(A)*b*c

我的第一次尝试是:

hy = T.hessian(y,[A,b,c])

AssertionError: tensor.hessian expects a (list of) 1 dimensional variable as 'wrt' 失败

我的第二次尝试是将 A、b 和 c 与:

wrt = T.concatenate([A,T.stack(b,c)])
hy = T.hessian(y,[wrt])

DisconnectedInputError: grad method was asked to compute the gradient with respect to a variable that is not part of the computational graph of the cost, or is used only by a non-differentiable operator: Join.0 失败

在这种情况下计算粗麻布的正确方法是什么?

更新:为了澄清我在寻找什么,假设 A 是一个 2 元素向量。那么 Hessian 将是:

[[d2y/d2A1, d2y/dA1dA2, d2y/dA1dB, d2y/dA1dC],
[d2y/dA2dA1, d2y/d2A2, d2y/dA2dB, d2y/dA2dC],
[d2y/dBdA1, d2y/dBdA2, d2y/d2B, d2y/dABdC],
[d2y/dCdA1, d2y/dCdA2, d2y/dCdB, d2y/d2C]]

对于示例函数y 应该是:

[[0, 0, C, B],
[0, 0, C, B],
[C, C, 0, A1+A2],
[B, B, A1+A2, 0]]

如果我们要定义一个函数:

f = theano.function([A,b,c], hy)

那么,假设我们可以成功计算hy,我们会期望输出:

f([1,1], 4, 5) = 
    [[0, 0, 5, 4],
    [0, 0, 5, 4],
    [5, 5, 0, 2],
    [4, 4, 2, 0]]

在我的实际应用中,A有25个元素,y比较复杂,但是思路是一样的。

【问题讨论】:

  • hessian 只为标量变量定义,不为向量定义。您可能想要的是计算向量的每个元素的粗麻布。你知道A的长度吗?然后你可以尝试 hy = T.hessian(y,[A[0],A[1],A[2],b,c]) 如果 A 的长度为 3。
  • 是的,这正是我想要做的,不是计算关于标量的粗麻布,而是将这些标量连接到我用来计算粗麻布的向量上。您的示例不起作用,它与我第一次尝试的问题相同,hessian 期望所有 wrt 元素都是向量而不是标量,而我期望的行为是将标量视为向量的组件。跨度>
  • 也许你应该编写函数的全部代码。它可以帮助您弄清楚您想要做什么,并且一个最小的工作示例可以帮助其他人尝试解决方案。
  • 我添加了一些关于我期待什么样的结果的额外细节,希望这有助于澄清我的问题。

标签: python concatenation theano hessian-matrix


【解决方案1】:

如果您将b,c 作为向量传递,它应该可以工作。 hessian 运算符需要一维数组。尽管标量也应该可以工作,但提供它喜欢的输入类型可能是最简单的。

您的堆叠失败的原因是stack 操作在图的不同分支上产生了一个新的非端节点变量,您通常不能明确地对其进行导数。所以 theano 根本不允许这样做。

这对我有用:

import theano.tensor as T
A = T.vector('A')
b,c = T.vectors('b','c')
y = T.sum(A)*b[0]*c[0]

hy = T.hessian(y,[A,b,c])

【讨论】:

  • 感谢您的回复!不幸的是,这并不完全符合我的期望:f = theano.function([A,b,c], hy); f([1,1],[4],[5]) = [array([[ 0., 0.], [ 0., 0.]]), array([[ 0.]]), array([[ 0.]])] 不是用所有项计算一个粗麻布,而是计算 3 个粗麻布。
  • 嗯好的。并且在 numpy 级别连接输入是不可能的?
  • 嗯,这可能行得通,但会很尴尬。有没有办法连接变量而不将它们变成你不能衍生的新变量?
【解决方案2】:

根据@eickenberg 提出的在 numpy 级别组合输入的建议,我使用了以下解决方法:

import theano
import theano.tensor as T

A,temp = T.vectors('A','T')
b,c = T.scalars('b','c')

y = T.sum(A)*b*c
y2 = theano.clone(y,{A:temp[:-2],b:temp[-2],c:temp[-1]})

hy = T.hessian(y2,[temp])
f = theano.function([temp], hy)

f([1,1,4,5])

给出预期的输出:

> [array([[ 0.,  0.,  5.,  4.],
>         [ 0.,  0.,  5.,  4.],
>         [ 5.,  5.,  0.,  2.],
>         [ 4.,  4.,  2.,  0.]])]

这可行,但感觉很尴尬,如果有人知道更好(更通用)的解决方案,请告诉我。

【讨论】:

    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 2017-10-21
    • 2017-10-05
    相关资源
    最近更新 更多