当输出的最后一个维度等于一时,Theano 中扫描的奇怪行为
Strange behavior of scan in Theano when outputs has last dimension equal to one
我在 Theano 中编译扫描运算符时遇到一个奇怪的错误,我无法理解。
当 outputs_info 初始化为最后一个维度等于一时,我得到这个错误:
TypeError: ('The following error happened while compiling the node', forall_inplace,cpu,
scan_fn}(TensorConstant{4}, IncSubtensor{InplaceSet;:int64:}.0, <TensorType(float32, vector)>),
'\n', "Inconsistency in the inner graph of scan 'scan_fn' : an input and an output are
associated with the same recurrent state and should have the same type but have type
'TensorType(float32, (True,))' and 'TensorType(float32, vector)' respectively.")
虽然如果此维度设置为大于一的任何值,我不会收到任何错误。
这个错误发生在 gpu 和 cpu 目标上,使用 theano 0.7、0.8.0 和 0.8.2。
这是一段重现错误的代码:
import theano
import theano.tensor as T
import numpy as np
def rec_fun( prev_output, bias):
return prev_output + bias
n_steps = 4
# with state_size>1, compilation runs smoothly
state_size = 2
bias = theano.shared(np.ones((state_size),dtype=theano.config.floatX))
(outputs, updates) = theano.scan( fn=rec_fun,
sequences=[],
outputs_info=T.zeros([state_size,]),
non_sequences=[bias],
n_steps=n_steps
)
print outputs.eval()
# with state_size==1, compilation fails
state_size = 1
bias = theano.shared(np.ones((state_size),dtype=theano.config.floatX))
(outputs, updates) = theano.scan( fn=rec_fun,
sequences=[],
outputs_info=T.zeros([state_size,]),
non_sequences=[bias],
n_steps=n_steps
)
# compilation fails here
print outputs.eval()
因此,编译具有不同的行为,具体取决于 "state_size"。
是否有解决方法来处理 state_size==1 和 state_size>1 两种情况?
改变
outputs_info=T.zeros([state_size,])
到
outputs_info=T.zeros_like(bias)
使其在 state_size == 1
的情况下正常工作。
次要解释和不同的解决方案
所以我注意到这两种情况之间的关键区别。
在这两种情况下,都将这些代码行添加到偏置声明行之后。
bias = ....
print bias.broadcastable
print T.zeros([state_size,]).broadcastable
结果是
对于您的代码有效的第一种情况
(False,)
(False,)
而对于第二种情况,它似乎崩溃了
(False,)
(True,)
所以发生的事情是,当您添加相同维度(偏差和 T.zeros)但具有不同广播模式的两个张量时,结果继承的模式是来自偏差的模式。这最终导致 theano 错误识别它们不是同一类型。
T.zeros_like 有效,因为它使用 bias
变量生成零张量。
另一种解决问题的方法是像这样更改广播模式
outputs_info=T.patternbroadcast(T.zeros([state_size,]), (False,)),
我在 Theano 中编译扫描运算符时遇到一个奇怪的错误,我无法理解。 当 outputs_info 初始化为最后一个维度等于一时,我得到这个错误:
TypeError: ('The following error happened while compiling the node', forall_inplace,cpu,
scan_fn}(TensorConstant{4}, IncSubtensor{InplaceSet;:int64:}.0, <TensorType(float32, vector)>),
'\n', "Inconsistency in the inner graph of scan 'scan_fn' : an input and an output are
associated with the same recurrent state and should have the same type but have type
'TensorType(float32, (True,))' and 'TensorType(float32, vector)' respectively.")
虽然如果此维度设置为大于一的任何值,我不会收到任何错误。
这个错误发生在 gpu 和 cpu 目标上,使用 theano 0.7、0.8.0 和 0.8.2。
这是一段重现错误的代码:
import theano
import theano.tensor as T
import numpy as np
def rec_fun( prev_output, bias):
return prev_output + bias
n_steps = 4
# with state_size>1, compilation runs smoothly
state_size = 2
bias = theano.shared(np.ones((state_size),dtype=theano.config.floatX))
(outputs, updates) = theano.scan( fn=rec_fun,
sequences=[],
outputs_info=T.zeros([state_size,]),
non_sequences=[bias],
n_steps=n_steps
)
print outputs.eval()
# with state_size==1, compilation fails
state_size = 1
bias = theano.shared(np.ones((state_size),dtype=theano.config.floatX))
(outputs, updates) = theano.scan( fn=rec_fun,
sequences=[],
outputs_info=T.zeros([state_size,]),
non_sequences=[bias],
n_steps=n_steps
)
# compilation fails here
print outputs.eval()
因此,编译具有不同的行为,具体取决于 "state_size"。 是否有解决方法来处理 state_size==1 和 state_size>1 两种情况?
改变
outputs_info=T.zeros([state_size,])
到
outputs_info=T.zeros_like(bias)
使其在 state_size == 1
的情况下正常工作。
次要解释和不同的解决方案
所以我注意到这两种情况之间的关键区别。 在这两种情况下,都将这些代码行添加到偏置声明行之后。
bias = ....
print bias.broadcastable
print T.zeros([state_size,]).broadcastable
结果是
对于您的代码有效的第一种情况
(False,)
(False,)
而对于第二种情况,它似乎崩溃了
(False,)
(True,)
所以发生的事情是,当您添加相同维度(偏差和 T.zeros)但具有不同广播模式的两个张量时,结果继承的模式是来自偏差的模式。这最终导致 theano 错误识别它们不是同一类型。
T.zeros_like 有效,因为它使用 bias
变量生成零张量。
另一种解决问题的方法是像这样更改广播模式
outputs_info=T.patternbroadcast(T.zeros([state_size,]), (False,)),