Theano梯度与张量函数

4
我有一个函数,用于计算三维空间中标量场的值。我将x、y和z坐标的3D张量(通过numpy.meshgrid获得)传递给它,并在各处使用逐元素操作。这如预期一样工作。
现在我需要计算标量场的梯度。我一直在尝试使用theano.tensor.grad和theano.tensor.jacobian,并且我不明白逐元素操作的导数应该如何工作。
以下是我不理解的最小示例:
import theano.tensor as T 

x, y = T.matrices("xy")

expr = x**2 + y
grad = T.grad(expr[0, 0], x)
print(grad.eval({x: [[1, 2], [1, 2]], y: [[1, 1], [2, 2]]}))

它会打印出来。

[[ 2.  0.]
 [ 0.  0.]]

虽然我预期

[[ 2.  4.]
 [ 2.  4.]]

我也试过使用Jacobian:
import theano.tensor as T

x, y = T.matrices("xy")

expr = x**2 + y
grad = T.jacobian(expr.flatten(), x)
print(grad.eval({x: [[1, 2], [1, 2]], y: [[1, 1], [2, 2]]}))

这个函数返回

[[[ 2.  0.]
  [ 0.  0.]]

 [[ 0.  4.]
  [ 0.  0.]]

 [[ 0.  0.]
  [ 2.  0.]]

 [[ 0.  0.]
  [ 0.  4.]]]

非零元素加在一起,可以得到我之前例子中期望的矩阵。

有没有一种方法可以获得我需要的逐元素梯度?

例如,我是否可以将函数定义为标量(三个标量到一个标量),并在坐标张量上逐元素应用它?这样导数也将是一个简单的标量,一切都将运作顺利。

1个回答

3

第一个元素 expr[0,0] 关于 x 的代价仅与 x 的第一个元素有关,因此您收到的结果是正确的。

如果您对整个 expr 数组求和,则会得到您期望的结果。Theano 会负责通过 sum 向后传播梯度。

import theano.tensor as T 

x, y = T.matrices("xy")

expr = x**2 + y
grad = T.grad(expr.sum(), x)
print(grad.eval({x: [[1, 2], [1, 2]], y: [[1, 1], [2, 2]]}))

打印输出
[[ 2.  4.]
 [ 2.  4.]]

谢谢,这正是我所需要的。 - cube

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接