【发布时间】:2021-11-24 15:47:48
【问题描述】:
假设我有一个名为 view 的数组:
array([[[[ 7, 9],
[10, 11]],
[[19, 18],
[20, 16]]],
[[[24, 5],
[ 6, 10]],
[[18, 11],
[45, 12]]]])
你可能从 maxpooling 中知道,这是原始输入的视图,内核大小为 2x2:
[[ 7, 9], [[19, 18],
[10, 11]], [20, 16]]], ....
目标是找到最大值及其索引。但是,argmax 只适用于单轴,所以我需要flatten view,即使用flatten=view.reshape(2,2,4):
array([[[ 7, 9, 10, 11], [19, 18, 20, 16]],
[[24, 5, 6, 10], [18, 11, 45, 12]]])
现在,在我的previous question 的帮助下,我可以使用inds = flatten.argmax(-1) 找到最大值索引:
array([[3, 2],
[0, 2]])
和最大值:
i, j = np.indices(flatten.shape[:-1])
flatten[i, j, inds]
>>> array([[11, 20],
[24, 45]])
问题
当我 展平 view 数组时,问题就出现了。由于view 数组是原始数组的视图,即view = as_strided(original, newshape, newstrides),所以view 和original 共享相同的数据。但是,reshape 会破坏它,因此view 上的任何更改都不会反映在original 上。这在反向传播期间是有问题的。
我的问题
给定数组view 和索引ind,我想将view 中的最大值更改为1000,而不使用整形或任何破坏view 和original 之间“键”的操作。感谢您的帮助!!!
可重现的例子
import numpy as np
from numpy.lib.stride_tricks import as_strided
original=np.array([[[7,9,19,18],[10,11,20,16]],[[24,5,18,11],[6,10,45,12]]],dtype=np.float64)
view=as_strided(original, shape=(2,1,2,2,2),strides=(64,32*2,8*2,32,8))
我想将view 中每个内核的最大值更改为 1000,这可以反映在original 上,即如果我运行view[0,0,0,0,0]=1000,那么视图和原始元素的第一个元素是 1000。
【问题讨论】:
-
您可以通过准备一个可运行的minimal reproducible example 来帮助那些试图回答您的问题的人:一个数组、一个视图以及您想用它做什么。
-
嗨,安德拉斯,我已经添加了一个示例 :)
-
如您所见,它有效 :P 再一次,您不需要(也不应该使用)
as_strided:view = original.reshape(2, 1, 2, 2, 2).transpose(0, 1, 3, 2, 4)。 -
是的,你是对的。虽然有时当涉及到步幅、膨胀和组时,比如在 pytorch conv2d 中,我不知道是否还有其他选择。我刚刚使用 numpy 完成了这个 maxpooling,不敢相信它比 conv2d 更难,索引让我非常头疼 smh。
标签: python arrays numpy indexing max-pooling