Reputation: 171
I am trying to implement CNN using only numpy. I am getting the error of index out of bound in the max pooling layer.
The function takes the feature map array as the argument. Feature map array is an ndarray. Here is my function:
feature_map = np.array([[[4, 3, 4],[2, 4, 3],[2, 3, 4]],
[[3, 4, 2],[2, 4, 4],[2, 4, 2]],
[[5, 7, 6],[2, 1, 3],[3, 3, 8]],
[[3, 3, 2],[1, 3, 5],[7, 4, 9,]]])
def pool_forward(feature_map, mode = "max", size=2, stride=2):
f_num, f_row, f_col = feature_map.shape
#Preparing the output of the pooling operation.
pool_out = np.zeros((np.uint16((f_row-size+1)/stride+1),
np.uint16((f_col-size+1)/stride+1), f_num))
for map_num in range(f_num):
r2 = 0
for r in np.arange(0,f_row-size+1, stride):
c2 = 0
for c in np.arange(0, f_col-size+1, stride):
pool_out[r2, c2, map_num] = np.max([feature_map[r:r+size,
c:c+size, map_num]])
c2 = c2 + 1
r2 = r2 +1
return np.array(pool_res)
This is the error I get:
--------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-104-ccb65cb3a606> in <module>()
----> 1 feature_pool = pool_forward(features)
2 feature_pool.shape
<ipython-input-102-5d4c4e76f99a> in pool_forward(feature_map, mode,
filter_size, stride)
13 c2 = 0
14 for c in np.arange(0, f_col-filter_size+1, stride):
---> 15 pool_out[r2, c2, map_num] =
np.max([feature_map[r:r+filter_size, c:c+filter_size, map_num]])
16 c2 = c2 + 1
17 r2 = r2 +1
IndexError: index 3 is out of bounds for axis 2 with size 3
Help me out here.
Upvotes: 2
Views: 216
Reputation: 5515
Please check the update part of the answer:
The error lies in the line:
pool_out[r2, c2, map_num] = np.max([feature_map[r:r+size, c:c+size, map_num]])
It should be:
pool_out[r2, c2, map_num] = np.max([feature_map[map_num, r:r+size, c:c+size]])
Now:
def pool_forward(feature_map, mode = "max", size=2, stride=2):
f_num, f_row, f_col = feature_map.shape
#Preparing the output of the pooling operation.
pool_out = np.zeros((np.uint16((f_row-size+1)/stride+1),
np.uint16((f_col-size+1)/stride+1), f_num))
for map_num in range(f_num):
r2 = 0
for r in np.arange(0,f_row-size+1, stride):
c2 = 0
for c in np.arange(0, f_col-size+1, stride):
pool_out[r2, c2, map_num] = np.max([feature_map[map_num, r:r+size, c:c+size]])
c2 = c2 + 1
r2 = r2 +1
return np.array(pool_res)
feature_map = np.array([[[4, 3, 4],[2, 4, 3],[2, 3, 4]],
[[3, 4, 2],[2, 4, 4],[2, 4, 2]],
[[5, 7, 6],[2, 1, 3],[3, 3, 8]],
[[3, 3, 2],[1, 3, 5],[7, 4, 9,]]])
pool_forward(feature_map)
returns:
array([[[4., 4., 7., 3.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.]]])
Update: The premise of the question is incorrect. With an input of shape 3*3 You have a pooling window-size of 2*2 and a stride of 2 then you might want to look into fractional_max_pooling
. For regular max_pooling
you should choose a stride of 1.(ie the value (f_row-size)/stride
should be an integer). In this case check out the code below:
feature_map = np.array([[[4, 3, 4],[2, 4, 3],[2, 3, 4]],
[[3, 4, 2],[2, 4, 4],[2, 4, 2]],
[[5, 7, 6],[2, 1, 3],[3, 3, 8]],
[[3, 3, 2],[1, 3, 5],[7, 4, 9,]]])
def pool_forward(feature_map, mode = "max", size=2, stride=1):
f_num, f_row, f_col = feature_map.shape
pool_out = np.zeros((f_num,np.uint16((f_row-size)/stride+1),\
np.uint16((f_col-size)/stride+1)))
for z in range(f_num):
for r in np.arange(0,f_row-size+1, stride):
for c in np.arange(0, f_col-size+1, stride):
pool_out[z, r, c] = np.max(feature_map[z, r:r+size, c:c+size])
return pool_out
pool_forward(feature_map)
returns:
array([[[4., 4.],
[4., 4.]],
[[4., 4.],
[4., 4.]],
[[7., 7.],
[3., 8.]],
[[3., 5.],
[7., 9.]]])
This seems to be correct. Also I tossed variables c2 and r2 because they dont seem to be necessary.
Upvotes: 2