未知维度张量的逐元素乘法
Elementwise multiplication of tensors of unknown dimension
如何对具有以下形状的张量进行元素乘法?这里的第二个数组总是假定为二维。
[x, y, ?, ?, ?, ...] * [x, y]
我想广播所有标记为 ? 的维度,我不知道其中的先验数字。我考虑过的可能解决方案(但不知道怎么做):
- 向第二个数组添加可变数量的轴
- 反转两个数组的轴顺序,然后再反转回来
任何指点都很好。
假设输入数组是 A
、B
,B
作为 2D
数组。首先,将 A
重塑为 3D
数组,并将尾部不匹配的维度合并为一维,然后与 B
执行广播元素乘法,最后将乘积重塑回原始状态A
的形状。实现看起来像这样 -
shp = A.shape # Get shape of A
out = (A.reshape(shp[0],shp[1],-1)*B[:,:,None]).reshape(shp)
验证输出 -
In [96]: A = np.random.rand(2,3,4,5,7,8,4)
In [97]: B = np.random.rand(2,3)
In [98]: shp = A.shape
...: out = (A.reshape(shp[0],shp[1],-1)*B[:,:,None]).reshape(shp)
...:
In [99]: direct_out = A*B[:,:,None,None,None,None,None]
In [100]: np.allclose(out,direct_out) # Verify
Out[100]: True
不漂亮,但它有效:
a = np.zeros((3, 4, 5, 6))
b = np.zeros((3, 4))
c = a*b[(slice(None), slice(None), )+(None, )*(a.ndim-2)]
问题中提到的备选方案(使用b
二维数组):
向第二个数组添加可变数量的轴
a * b.reshape(b.shape + (1,)*(a.ndim-b.ndim))
反转两个数组的轴顺序,然后再反转回来
(a.T * b.T).T
einsum 的另一种选择:
numpy.einsum('ij...,ij->ij...', a, b)
如何对具有以下形状的张量进行元素乘法?这里的第二个数组总是假定为二维。
[x, y, ?, ?, ?, ...] * [x, y]
我想广播所有标记为 ? 的维度,我不知道其中的先验数字。我考虑过的可能解决方案(但不知道怎么做):
- 向第二个数组添加可变数量的轴
- 反转两个数组的轴顺序,然后再反转回来
任何指点都很好。
假设输入数组是 A
、B
,B
作为 2D
数组。首先,将 A
重塑为 3D
数组,并将尾部不匹配的维度合并为一维,然后与 B
执行广播元素乘法,最后将乘积重塑回原始状态A
的形状。实现看起来像这样 -
shp = A.shape # Get shape of A
out = (A.reshape(shp[0],shp[1],-1)*B[:,:,None]).reshape(shp)
验证输出 -
In [96]: A = np.random.rand(2,3,4,5,7,8,4)
In [97]: B = np.random.rand(2,3)
In [98]: shp = A.shape
...: out = (A.reshape(shp[0],shp[1],-1)*B[:,:,None]).reshape(shp)
...:
In [99]: direct_out = A*B[:,:,None,None,None,None,None]
In [100]: np.allclose(out,direct_out) # Verify
Out[100]: True
不漂亮,但它有效:
a = np.zeros((3, 4, 5, 6))
b = np.zeros((3, 4))
c = a*b[(slice(None), slice(None), )+(None, )*(a.ndim-2)]
问题中提到的备选方案(使用b
二维数组):
向第二个数组添加可变数量的轴
a * b.reshape(b.shape + (1,)*(a.ndim-b.ndim))
反转两个数组的轴顺序,然后再反转回来
(a.T * b.T).T
einsum 的另一种选择:
numpy.einsum('ij...,ij->ij...', a, b)