问题
I have a 8x8 matrix as follows:
[[ 0.3 0.3 0.3 0.3 0.3 0.5 0.1 -0.1]
[ 0.1 0.1 -0.1 0.3 0.3 -0.1 -0.1 -0.5]
[-0.1 0.1 0.3 -0.1 0.3 -0.1 -0.1 -0.1]
[-0.1 0.1 0.5 0.3 -0.3 -0.1 -0.3 -0.1]
[ 0.5 0.1 -0.1 0.1 -0.1 -0.1 -0.3 -0.5]
[ 0.1 -0.1 -0.3 -0.5 -0.5 -0.1 -0.1 -0.3]
[-0.5 -0.3 -0.3 -0.3 -0.1 -0.5 -0.1 -0.3]
[-0.3 -0.3 -0.3 -0.3 -0.1 -0.1 -0.5 -0.3]]
My window is 2x2. What I am trying to do is get four numbers together (up and down numbers) for pooling. Sample output looks like this:
[[0.3 0.3
0.1 0.1]
[0.3 0.3
-0.1 0.3]
.......
.......
[-0.1 -0.3
-0.5 -0.3]]
What I using is print arr.reshape(16,2,2)
What i can't understand is how to setup axis for this requirement. My output is:
[[[ 0.3 0.3]
[ 0.3 0.3]]
[[ 0.3 0.1]
[ 0.5 -0.1]]
[[ 0.1 -0.1]
[ 0.1 0.3]]
[[ 0.3 -0.1]
[-0.1 -0.5]]
[[-0.1 0.3]
[ 0.1 -0.1]]
[[ 0.3 -0.1]
[-0.1 -0.1]]
[[-0.1 0.5]
[ 0.1 0.3]]
[[-0.3 -0.3]
[-0.1 -0.1]]
[[ 0.5 -0.1]
[ 0.1 0.1]]
[[-0.1 -0.3]
[-0.1 -0.5]]
[[ 0.1 -0.3]
[-0.1 -0.5]]
[[-0.5 -0.1]
[-0.1 -0.3]]
[[-0.5 -0.3]
[-0.3 -0.3]]
[[-0.1 -0.1]
[-0.5 -0.3]]
[[-0.3 -0.3]
[-0.3 -0.3]]
[[-0.1 -0.5]
[-0.1 -0.3]]]
Please explain how would axis be applied on this type of situation. Or if their is a better way to get max-pooling do mention.
Note: All of this is for max-pooling. I am using NumPy, SciPy on python.
回答1:
Reshape splitting each of the two axes into two each such that the latter of the split axes is of the same length as the block size. This would give us a 4D
array. Then, perform maximum finding along those latter axes, which would be the second and fourth axes in that 4D
array.
Thus, simply do -
m,n = a.shape
out = a.reshape(m//2,2,n//2,2).max(axis=(1,3))
Sample run -
In [50]: a
Out[50]:
array([[87, 96, 46, 97, 25, 22, 13, 16],
[65, 62, 68, 87, 52, 80, 26, 82],
[27, 82, 50, 20, 11, 14, 94, 23],
[86, 44, 17, 97, 17, 57, 76, 42],
[47, 85, 30, 61, 55, 87, 11, 35],
[36, 11, 29, 45, 16, 54, 40, 77],
[38, 87, 94, 77, 53, 20, 46, 18],
[86, 50, 17, 23, 91, 23, 25, 11]])
In [51]: m,n = a.shape
In [52]: a.reshape(m//2,2,n//2,2).max(axis=(1,3))
Out[52]:
array([[96, 97, 80, 82],
[86, 97, 57, 94],
[85, 61, 87, 77],
[87, 94, 91, 46]])
回答2:
Does
arr.reshape((4, 2, 4, 2)).transpose((0, 2, 1, 3)).reshape((16, 2, 2))
do what you want?
Edit: A bit of explanation: The first reshape cuts up the x and y axes each into 4 blocks of 2. This is almost what you were asking for, only the blocks are on axis 1 and 3, not on the last two. That's where transpose comes in. It is a straightforward generalisation of the matrix transpose in maths (which swaps axes 0 and 1) to arbitrary dimensions. The argument (0, 2, 1, 3) asks it to leave the 0th and last axis in place and to swap axes 1 and 2.
At this point the shape is (4, 4, 2, 2). So the final reshape flattens out the first two axes. If you can instead live with 4 x 4 blocks of 2 x 2 then it is actually advisable to not do the second reshape because compared to the first two operations it is computationally expensive.
This is because the transpose creates a non-contiguous array. Now one difference between contiguous and non-contiguous arrays is the reshaping contiguous arrays costs next to nothing while reshaping a non-contiguous array will typically force a copy.
来源:https://stackoverflow.com/questions/41813722/numpy-array-reshaped-but-how-to-change-axis-for-pooling