关于在多维数组上执行数学运算时如何理解冒号运算符,我可能有一个简单的问题。
在下面两个例子中,我对实际发生的事情非常困惑:
dx[:,r:H,c:W] += dout[depth, r, c] * w[depth,:,:,:]
在此示例中,我们正在处理形状为dx
的数组(channels, height, width)
。例如RGB图像。 dout
与dx
类似,但通道,行和列的数量与w
不同。 (num, channels, height, width)
的形状为channels
,其中channels
等于dx
中的dout
。 channels
的{{1}}等于w
的{{1}}。
num
此处dw[depth,:,:,:] += dout[depth,r,c] * x[:,r:r+HH,c+WW]
的形状与上一个示例中的dw
相同。从上一个示例中也可以知道w
。 dout
与x
类似,但是dout
等于channels
的{{1}}。
我对执行此类操作时单个值发生什么感到好奇。我的意思是,这通常只是不同张量之间的卷积,但是我目前对如何使用for循环表达这一点感到困惑。
答案 0 :(得分:1)
假设depth
,r
和c
是标量,则
dout[depth, r, c]
是标量(如果dout
是3d)
dout[depth, r, c] * w[depth,:,:,:]
w[depth, :, :, :]
是从w
中切出的3d数组,即由depth
索引选择的子数组。这只是该子数组中每个元素的标量乘以一个新数组。
dx[:,r:H,c:W] += dout[depth, r, c] * w[depth,:,:,:]
有效:
dx[:,r:H,c:W] = dx[:, r:H, c:W] + dout[depth, r, c] * w[depth,:,:,:]
dx[:, r:H, c:W]
是dx
的一部分,像dx
一样是3d,但是沿第二和第三轴的子集。如果切片正确,则其形状应与w[depth, :,:,:]
我看不到任何广播或特殊操作。只是从每个数组中获取匹配的大小部分,将它们相加,然后将值放回到dx
中的正确块中。
颜色运算符只是基本的numpy索引运算符。
dx.shape (channels, height, width)
dout.shape (num, m , k)
w.shape (num, channels, height, width)
使用3维索引,dout[depth, r, c]
的形状dout
无关紧要。这只是一个值。
In [295]: 10 * np.arange(12).reshape(3,4)
Out[295]:
array([[ 0, 10, 20, 30],
[ 40, 50, 60, 70],
[ 80, 90, 100, 110]])
乘以标量可以认为是乘以充满该值的匹配数组
In [297]: np.full((3,4),10)
Out[297]:
array([[10, 10, 10, 10],
[10, 10, 10, 10],
[10, 10, 10, 10]])
通过广播规则,可以使用1d或2d或其他大小的数组执行相同的操作。但是我看不到您的示例中发生了这种情况,在这里我不会对此进行介绍。