Theano中共享矩阵的元素更新

时间:2015-12-21 12:40:43

标签: theano

我试图计算能量函数的梯度E(phi,theta,psi),其中phi,theta,psi分别是Z,Y和X轴周围的欧拉角。 R是从欧拉角转换的旋转矩阵。 列是旋转矢量。 对于室内房间的点云,我对点云中的每个点都有法线N. N的形状为(numPoints x 3)

现在E = sum(1-max(N.dot(R))

我想找到E相对于欧拉角的梯度。

首先是问题我试图使用Theano从欧拉角计算旋转矩阵R. 请找到以下代码。

import theano
import theano.tensor as T
import numpy as np

phi = theano.shared(value=np.pi/3, name='phi')
theta = theano.shared(value=np.pi/3, name='theta')
psi = theano.shared(value=np.pi/3, name='psi')

# phi = T.dscalar(name='phi')
# theta = T.dscalar(name='theta')
# psi = T.dscalar(name='psi')

R = theano.shared(value=np.zeros([3, 3]), name='R')

R00 = T.set_subtensor(R[0, 0],  T.cos(theta)*T.cos(phi))
R10 = T.set_subtensor(R[1, 0],  T.cos(theta)*T.sin(phi))

R20 = T.set_subtensor(R[2, 0],  -T.sin(theta))

R01 = T.set_subtensor(R[0, 1],  T.sin(psi)*T.sin(theta)*T.cos(phi) - T.cos(psi)*T.sin(phi))
R11 = T.set_subtensor(R[1, 1],  T.sin(psi)*T.sin(theta)*T.sin(phi) + T.cos(psi)*T.cos(phi))
R21 = T.set_subtensor(R[2, 1],  T.sin(psi)*T.cos(theta))

R02 = T.set_subtensor(R[0, 2],  T.cos(psi)*T.sin(theta)*T.cos(phi) + T.sin(psi)*T.sin(phi))
R12 = T.set_subtensor(R[1, 2],  T.cos(psi)*T.sin(theta)*T.sin(phi) - T.sin(psi)*T.cos(phi))
R22 = T.set_subtensor(R[2, 2],  T.cos(psi)*T.cos(theta))

f = theano.function([phi, theta, psi], updates=[(R, R00, R10, R20, R01, R11, R21, R02, R12, R22)])

theano.printing.pydotprint(f, outfile="./test.png", var_with_name_simple=True)

但是这给了我两个不同阶段的错误,

Traceback (most recent call last):
  File "/theanotest.py", line 38, in <module>
    f = theano.function([phi, theta, psi], updates=[(R, R00, R10, R20, R01, R11, R21, R02, R12, R22)])
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function.py", line 266, in function
    profile=profile)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 489, in pfunc
    no_default_updates=no_default_updates)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 186, in rebuild_collect_shared
    ' variable via the `givens` parameter') % v)
TypeError: Cannot use a shared variable (phi) as explicit input. Consider substituting a non-shared variable via the `givens` parameter

如果我将Eurler角度变为标量值,我会得到如下错误

Traceback (most recent call last):
  File "/theanotest.py", line 38, in <module>
    f = theano.function([phi, theta, psi], updates=[(R, R00, R10, R20, R01, R11, R21, R02, R12, R22)])
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function.py", line 266, in function
    profile=profile)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 489, in pfunc
    no_default_updates=no_default_updates)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 191, in rebuild_collect_shared
    for (store_into, update_val) in iter_over_pairs(updates):
ValueError: too many values to unpack

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

第一个错误与消息指示完全一样:您无法提供共享变量作为Theano函数的输入。使用没有输入参数的共享变量或常规张量作为输入参数。

第二个错误是由于updates不正确造成的。更新应该是对的列表。每对应包含要更新的共享变量和描述如何计算更新的符号表达式。

在这种情况下,更新可能会像这样计算(未经测试):

Rnew = T.set_subtensor(R[0, 0],  T.cos(theta)*T.cos(phi))
Rnew = T.set_subtensor(Rnew[1, 0],  T.cos(theta)*T.sin(phi))
Rnew = T.set_subtensor(Rnew[2, 0],  -T.sin(theta))

Rnew = T.set_subtensor(Rnew[0, 1],  T.sin(psi)*T.sin(theta)*T.cos(phi) - T.cos(psi)*T.sin(phi))
Rnew = T.set_subtensor(Rnew[1, 1],  T.sin(psi)*T.sin(theta)*T.sin(phi) + T.cos(psi)*T.cos(phi))
Rnew = T.set_subtensor(Rnew[2, 1],  T.sin(psi)*T.cos(theta))

Rnew = T.set_subtensor(Rnew[0, 2],  T.cos(psi)*T.sin(theta)*T.cos(phi) + T.sin(psi)*T.sin(phi))
Rnew = T.set_subtensor(Rnew[1, 2],  T.cos(psi)*T.sin(theta)*T.sin(phi) - T.sin(psi)*T.cos(phi))
Rnew = T.set_subtensor(Rnew[2, 2],  T.cos(psi)*T.cos(theta))

f = theano.function([phi, theta, psi], updates=[(R, Rnew)])