Theano 中共享矩阵的逐元素更新
Elementwise updates of shared matrix in 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
如果我将欧拉角更改为标量值,我会得到如下错误
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
谁能帮我解决这个问题?
第一个错误与消息所指示的完全相同:您不能提供共享变量作为 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)])
我正在尝试计算能量函数的梯度,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
如果我将欧拉角更改为标量值,我会得到如下错误
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
谁能帮我解决这个问题?
第一个错误与消息所指示的完全相同:您不能提供共享变量作为 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)])