theano中的复数尚未完全实现,例如in this groups.google post和this question所讨论的。 但是,鉴于某些支持确实似乎存在,我试图了解目前实际可以做些什么。
考虑这个非常简单的代码:
x = T.dscalar('x')
y = 2j * x
gy = T.grad(y, x)
f = theano.function([x], gy)
f(1.234)
即x
a * x
a
的导数,其中Casting from complex to real is ambiguous: consider real(), imag(), angle() or abs()
为复数。
以上代码不会产生结果,抱怨
x = T.dscalar('x')
y_R = T.real(2j) * x
y_I = T.imag(2j) * x
gy_R = T.grad(y_R, x)
gy_I = T.grad(y_I, x)
gy = gy_R + 1j * gy_I
f = theano.function([x], gy)
f(1.234)
# array(2j)
如何使这些代码起作用?
以下是我设法开始工作的简单实现:
x
基本上,将复数常量分为实部和虚部,分别计算梯度,并且只在最后求它们得到复杂的结果。
这种方法的问题在于,如果我们尝试更复杂的示例,例如针对某些矩阵expm(1j * x * H)
计算H
x = T.dscalar('x')
expH = T.slinalg.expm(1j * x * H)
expH_flat = T.flatten(expH)
expH_flat_R = T.real(T.flatten(expH))
expH_flat_I = T.imag(T.flatten(expH))
def fn(i, mat, x):
return T.grad(mat[i], x)
J_R, updates = theano.scan(fn, sequences=T.arange(expH_flat_R.shape[0]), non_sequences=[expH_flat_R, x])
J_I, updates = theano.scan(fn, sequences=T.arange(expH_flat_I.shape[0]), non_sequences=[expH_flat_I, x])
expH_J_R = J_R.reshape(expH.shape)
expH_J_I = J_I.reshape(expH.shape)
expH_J = expH_J_R + 1j * expH_J_I
f = theano.function([x], expH_J)
f(2)
的渐变,它就无法工作:< / p>
TypeError: Elemwise{real,no_inplace}.grad illegally returned an integer-valued variable. (Input index 0, dtype complex128)
返回
var str = '<p class="post">Lorem ipsum dolor sit amet, <a href="http://website.com/link" target="_blank" title="hello">consectetur adipiscing elit</a>. Pellentesque vehicula tortor eget tortor fermentum bibendum. Duis mollis nisl et metus vulputate, a aliquam quam pharetra. <a href="http://website.com/link" target="_blank" title="hello">consectetur adipiscing elit</a> quis hendrerit nibh ultrices eget. <span class="highlight">Praesent</span> eu mollis lectus, sed convallis quam.</p>'
var allTheText = str.replace(/<[^>]*>/g,"")
console.log(allTheText.length)
如果使用theano无法实现这一点(例如this question似乎暗示),是否出于特殊原因,如排序的基本困难?
答案 0 :(得分:0)
这似乎根本不可能在本地实现(考虑到Theano的开发已于2017年停止,因此将来可能不会实现)。
解决该问题的一种方法是将每个复杂矩阵重新映射为更大的实数矩阵,然后对更大的矩阵执行所有操作(将需要重新定义各种操作)。
可能的映射是A -> [[A_R, -A_I], [A_I, A_R]]
。