【问题标题】:theano (python): elementwise gradienttheano(python):逐元素渐变
【发布时间】:2015-12-01 15:20:01
【问题描述】:

我正在尝试使用

执行逐元素渐变

例如,

输出-f(x):5乘1向量,

关于 输入-X:5 x 1 向量

我可以这样做,

 import theano
 import theano.tensor as T

 X = T.vector('X')   

 f = X*3    

 [rfrx, []] = theano.scan(lambda j, f,X : T.grad(f[j], X), sequences=T.arange(X.shape[0]), non_sequences=[f,X])

 fcn_rfrx = theano.function([X], rfrx)

 fcn_rfrx(np.ones(5,).astype(float32))

结果是

array([[ 3.,  0.,  0.,  0.,  0.],
       [ 0.,  3.,  0.,  0.,  0.],
       [ 0.,  0.,  3.,  0.,  0.],
       [ 0.,  0.,  0.,  3.,  0.],
       [ 0.,  0.,  0.,  0.,  3.]], dtype=float32)

但由于效率不高,因此我希望得到 5 x 1 的向量

通过做类似的事情..

 [rfrx, []] = theano.scan(lambda j, f,X : T.grad(f[j], X[j]), sequences=T.arange(X.shape[0]), non_sequences=[f,X])

这不起作用。

有没有办法做到这一点? (抱歉格式不好……我是新来的,正在学习)


(我添加了更清晰的示例):

给定输入向量:x[1], x[2], ..., x[n]

和输出向量:y[1], y[2], .., y[n],

其中 y[i] = f(x[i])。

我想要

的结果

仅df(x[i])/dx[i]

而不是

df(x[i])/dx[j] for (ij)

,为了计算效率(n是数据数> 10000)

【问题讨论】:

  • 你能对输出求和吗:f.sum() 并取梯度 w.r.t. X?
  • @Alleo 我添加了一个示例,以免混淆。这是否意味着 theano 不会自动尝试 df(x[i])/dx[j] for (ij)?
  • 给定您的附加公式 (y[i] = f(x[i])),求和然后计算梯度没有问题。 Theano 应该减少不必要的计算。
  • 好的,我已经检查了它在我的情况下可以接受的速度。

标签: python theano elementwise-operations


【解决方案1】:

您正在寻找theano.tensor.jacobian

import theano
import theano.tensor as T

x = T.fvector()
p = T.as_tensor_variable([(x ** i).sum() for i in range(5)])

j = T.jacobian(p, x)

f = theano.function([x], [p, j])

现在评估收益率

In [31]: f([1., 2., 3.])
Out[31]: 
[array([  3.,   6.,  14.,  36.,  98.], dtype=float32),
 array([[   0.,    0.,    0.],
        [   1.,    1.,    1.],
        [   2.,    4.,    6.],
        [   3.,   12.,   27.],
        [   4.,   32.,  108.]], dtype=float32)]

如果您只对一个或几个偏导数感兴趣,您也可以只获得它们。有必要仔细查看 theano 优化规则,以了解其效率提高了多少(基准测试是第一次测试)。 (可能已经对梯度进行了索引,使得 theano 清楚它不需要计算其余部分)。

x = T.fscalar()
y = T.fvector()
z = T.concatenate([x.reshape((1,)), y.reshape((-1,))])

e = (z ** 2).sum()
g = T.grad(e, wrt=x)

ff = theano.function([x, y], [e, g])

【讨论】:

  • 我想我的问题令人困惑,我又添加了一个示例。我的意思是,我不想对不需要的元素执行渐变,输入和输出的向量大小相同。
  • 那么,这是否意味着当我们使用 like 'f.sum()' 时,theano 将自动有效地不尝试 df(x[i])/dx[j] for (ij) ?
  • 我更新了我的答案。这是否符合您的问题?
  • 是的,我已经检查过,使用这种方式 ('f.sum()') 对我的情况来说速度可以接受,无需仔细观察。
猜你喜欢
  • 1970-01-01
  • 2017-06-01
  • 2015-05-30
  • 2021-09-23
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
相关资源
最近更新 更多