ahmedfgad/NumPyCNN

some bugs to fix in pooling() and relu()

JulyJohn opened this issue · 3 comments

@ahmedfgad

in the pooling()
change the "feature_map.shape[0]-size+1)/stride" to "feature_map.shape[0]-size)/stride+1"

NumPyCNN/NumPyCNN.py

Lines 85 to 87 in aac7afd

pool_out = numpy.zeros((numpy.uint16((feature_map.shape[0]-size+1)/stride),
numpy.uint16((feature_map.shape[1]-size+1)/stride),
feature_map.shape[-1]))

pool_out = numpy.zeros((numpy.uint16((feature_map.shape[0]-size)/stride+1), 
                         numpy.uint16((feature_map.shape[1]-size+1)/stride+1), 
                         feature_map.shape[-1])) 

in the relu()
change the "feature_map.shape[1]-size-1" to "feature_map.shape[1]-size+1" to arrive at the end.

for r in numpy.arange(0,feature_map.shape[0]-size-1, stride):

 for r in numpy.arange(0,feature_map.shape[0]-size+1, stride): 

for c in numpy.arange(0, feature_map.shape[1]-size-1, stride):

 for c in numpy.arange(0, feature_map.shape[1]-size+1, stride): 

Thanks @JulyJohn.
Your notes are so helpful. Pooling operation was not working correctly and now it is working fine.
But you said there is a suggested change in relu() but all of your comments are just relative to pooling().
Please let me know if there is something to do with pooling().

Sorry for the delay. @ahmedfgad
Yeah, the previous suggestions are all about pooling(), and my suggestion about rule() is that you should consider the situation when feature_map is less than 3 dims, here is my suggested code .(maybe there is a more beautiful writing

def relu(feature_map):
    # Preparing the output of the ReLU activation function.
    fp_shape = feature_map.shape
    fp_dims = len(fp_shape)
    relu_out = numpy.zeros(fp_shape)
    if fp_dims == 3:
        for map_num in range(feature_map.shape[-1]):
            for r in numpy.arange(0, feature_map.shape[0]):
                for c in numpy.arange(0, feature_map.shape[1]):
                    relu_out[r, c, map_num] = numpy.max([feature_map[r, c, map_num], 0])
    elif fp_dims == 2:
        for map_num in range(feature_map.shape[-1]):
            for r in numpy.arange(0, feature_map.shape[0]):
                relu_out[r, map_num] = numpy.max([feature_map[r, map_num], 0])
    elif fp_dims == 1:
        for map_num in range(feature_map.shape[-1]):
            relu_out[map_num] = numpy.max([feature_map[map_num], 0])

    return relu_out

:-) good luck

Thanks for your suggestion @JulyJohn.
The input to the relu() function is always 3D even if it consists of only a single matrix. For example, if the input image shape is (X, Y) and a single filter is used in a conv layer, the result will be of shape (X, Y, 1). Feeding it to relu() works well.

Your code will work well if the relu() function is called with an external matrix not produced by the conv() layer. In this case, we have to address the different possibilities of the input image shape.

Thanks for your suggestion 👍 :)