从3D Matrix中提取补丁

fab*_*789 6 python numpy tensorflow

我有一个A尺寸的3D矩阵h x w x c.我想ph x pw从每个"频道"中提取尺寸的片段c.ph划分hpw分裂w.在这个例子中,

h x w x c = 4 x 4 x 3
ph x pw = 2 x 2
Run Code Online (Sandbox Code Playgroud)

例

我知道如何在tensorflow中使用这个,gather_nd但是我希望在设置它时能有更高效的东西,因为维度很大而且我宁愿没有gather_nd内存中的indices数组.可能有一个聪明的重塑?numpy或tensorflow解决方案都非常好!

Div*_*kar 4

您可以使用一些轴的重塑和交换 -

A.reshape(h//ph,ph,w//pw,pw,-1).swapaxes(1,2)
Run Code Online (Sandbox Code Playgroud)

样本运行 -

In [46]: # Sample inputs
    ...: h,w,c = 10,12,3
    ...: ph, pw = 2,2
    ...: A = np.random.randint(0,9,(h,w,c))
    ...: 

In [47]: A.reshape(h//ph,ph,w//pw,pw,-1).swapaxes(1,2).shape
Out[47]: (5, 6, 2, 2, 3)
Run Code Online (Sandbox Code Playgroud)

前两个轴上的每个元素(作为块)代表补丁。因此。对于提供的示例,我们将提供5 x 6 = 30补丁。

如果您希望这些补丁沿着一个合并的第一轴,请再使用一个reshape-

In [85]: out = A.reshape(h//ph,ph,w//pw,pw,-1).swapaxes(1,2).reshape(-1,ph,pw,c)

In [86]: out.shape
Out[86]: (30, 2, 2, 3)
Run Code Online (Sandbox Code Playgroud)

让我们通过手动检查值本身来验证 -

In [81]: A[:ph,:pw] # First patch
Out[81]: 
array([[[6, 5, 2],
        [4, 0, 1]],

       [[0, 0, 4],
        [2, 3, 0]]])

In [82]: A[:ph,pw:2*pw] # Second patch
Out[82]: 
array([[[8, 3, 3],
        [0, 0, 2]],

       [[8, 5, 4],
        [3, 4, 6]]])

In [83]: out[0]
Out[83]: 
array([[[6, 5, 2],
        [4, 0, 1]],

       [[0, 0, 4],
        [2, 3, 0]]])

In [84]: out[1]
Out[84]: 
array([[[8, 3, 3],
        [0, 0, 2]],

       [[8, 5, 4],
        [3, 4, 6]]])
Run Code Online (Sandbox Code Playgroud)