@@ -483,6 +483,10 @@ def conv_backward_naive(dout, cache):
483483 Inputs:
484484 - dout: Upstream derivatives.
485485 - cache: A tuple of (x, w, b, conv_param) as in conv_forward_naive
486+
487+ Some helpful explonation could be find there:
488+ - https://medium.com/@2017csm1006/forward-and-backpropagation-in-convolutional-neural-network-4dfa96d7b37e
489+ - https://becominghuman.ai/back-propagation-in-convolutional-neural-networks-intuition-and-code-714ef1c38199
486490
487491 Returns a tuple of:
488492 - dx: Gradient with respect to x
@@ -551,7 +555,20 @@ def max_pool_forward_naive(x, pool_param):
551555 ###########################################################################
552556 # TODO: Implement the max pooling forward pass #
553557 ###########################################################################
554- pass
558+ (N , C , H , W ) = x .shape
559+ pool_height = pool_param ['pool_height' ]
560+ pool_width = pool_param ['pool_width' ]
561+ stride = pool_param ['stride' ]
562+ out_H = H // stride
563+ out_W = W // stride
564+ out = np .zeros ((N , C , out_H , out_W ))
565+
566+ for h in range (out_H ):
567+ for w in range (out_W ):
568+ xx = h * stride
569+ yy = w * stride
570+ out [:,:,h ,w ] = np .max (x [:,:,xx :xx + pool_height ,yy :yy + pool_width ], axis = (2 ,3 ))
571+
555572 ###########################################################################
556573 # END OF YOUR CODE #
557574 ###########################################################################
@@ -574,7 +591,28 @@ def max_pool_backward_naive(dout, cache):
574591 ###########################################################################
575592 # TODO: Implement the max pooling backward pass #
576593 ###########################################################################
577- pass
594+ (x , pool_param ) = cache
595+
596+ pool_height = pool_param ['pool_height' ]
597+ pool_width = pool_param ['pool_width' ]
598+ stride = pool_param ['stride' ]
599+
600+ dx = np .zeros_like (x )
601+
602+ (N , C , H , W ) = dout .shape
603+ for h in range (H ):
604+ for w in range (W ):
605+ xx = h * stride
606+ yy = w * stride
607+ # find which x were contribute to the out
608+ x_frame = x [:,:,xx :xx + pool_height ,yy :yy + pool_width ]
609+ # x_frame has shape = [number_of_samples, features] but should be [number_of_samples, features, h, w]
610+ # or at least [number_of_samples, features, 1, 1]
611+ # in other words operation "*[:,:,None,None]" changes dimesion
612+ # from [number_of_samples, features] to [number_of_samples, features, 1, 1]
613+ x_mask = x_frame == x_frame .max (axis = (2 ,3 ))[:,:,None ,None ]
614+ dx [:,:,xx :xx + pool_height ,yy :yy + pool_width ] += dout [:,:,h ,w ][:,:,None ,None ] * x_mask
615+
578616 ###########################################################################
579617 # END OF YOUR CODE #
580618 ###########################################################################
@@ -612,7 +650,11 @@ def spatial_batchnorm_forward(x, gamma, beta, bn_param):
612650 # version of batch normalization defined above. Your implementation should#
613651 # be very short; ours is less than five lines. #
614652 ###########################################################################
615- pass
653+ N , C , H , W = x .shape
654+ # put channel at the last dimention and stretch all dimensions except the last one
655+ flat_output , cache = batchnorm_forward (x .transpose (0 ,2 ,3 ,1 ).reshape ((N * H * W ,C )), gamma , beta , bn_param )
656+ # revert dimensions
657+ out = flat_output .reshape (N ,H ,W ,C ).transpose (0 ,3 ,1 ,2 )
616658 ###########################################################################
617659 # END OF YOUR CODE #
618660 ###########################################################################
@@ -642,7 +684,9 @@ def spatial_batchnorm_backward(dout, cache):
642684 # version of batch normalization defined above. Your implementation should#
643685 # be very short; ours is less than five lines. #
644686 ###########################################################################
645- pass
687+ N , C , H , W = dout .shape
688+ flat_dx , dgamma , dbeta = batchnorm_backward (dout .transpose (0 ,2 ,3 ,1 ).reshape ((N * H * W ,C )), cache )
689+ dx = flat_dx .reshape (N ,H ,W ,C ).transpose (0 ,3 ,1 ,2 )
646690 ###########################################################################
647691 # END OF YOUR CODE #
648692 ###########################################################################
0 commit comments