逐轴对连个ndarray进行操作的时候,会隐式的执行broadcast的动作,执行broadcast
的动作需要参与操作的两个轴至少满足如下一个条件:
1. 当前的各自轴(长度)相等,(其实无需进行broadcast了)
2. 其中一个轴的长度为1,因此可以进行拷贝扩展
例如:
>>> x = np.random.rand(8, 1, 6, 1)>>> y = np.random.rand(7, 1, 5)>>> (x*y).shape # 8, 1(拓展), 6, 1(拓展)# 7, 1(拓展), 5# 8, 7, 6, 5
更详尽的讨论参见之前的一篇文章numpy中的broadcasting机制。
theano variables vs shared variables
默认情况下,tensor
中的matrix/tensor3/tensor4
不可进行broadcast
的。theano的所有shared variable
也是不可进行broadcast
的,但可以改变它们的shape
。
也可以在创建shared variable
时显示指定其是否可以broadcastable。
xval = np.array([[1, 2, 3], [4, 5, 6]])# (2, 3), ndim = 2bval = np.array([[10, 20, 30]])# (1, 3), ndim = 2xshared = theano.shared(xval)bshared = theano.shared(bval)zval = xshared*1./bshared# numpy时,两者是可以进行broadcast的# 右前可知,shared变量不可进行broadcastprint zval.eval()
解决方案:
bshared = theano.shared(bval, broadcastable=(True, False))
此外还有一种特殊情况,一维数组(不论是否是shared类型)都可进行broadcast:
xval = np.array([[1, 2, 3], [4, 5, 6]])# (2, 3), ndim=2bval = np.array([10, 20, 30])# (3, ), ndim=1xshared = theano.shared(xval)bshared = theano.shared(bval)zval = xshared*1./bsharedzval.eval()
array([[ 0.1 , 0.1 , 0.1 ],[ 0.4 , 0.25, 0.2 ]])
references
[1]Theano and numpy broadcasting