human
I am working on the file ".ipynb_checkpoints/Lxmls_Day5-checkpoint.ipynb".
The first task is:
Go to lxmls/deep learning/mlp.py:class NumpyMLP:def grads() and complete the code of the NumpyMLP class with
the Backpropagation recursion that we just saw.
Can you write Python program for it?
assistant
#Here is the Python program you requested.

    def grads(self, x, y):
        """
       Computes the gradients of the network with respect to cross entropy
       error cost
       """

        # Run forward and store activations for each layer
        activations = self.forward(x, all_outputs=True)

        # For each layer in reverse store the gradients for each parameter
        nabla_params = [None] * (2*self.n_layers)

        for n in np.arange(self.n_layers-1, -1, -1):

            # Get weigths and bias (always in even and odd positions)
            # Note that sometimes we need the weight from the next layer
            W = self.params[2*n]
            b = self.params[2*n+1]
            if n != self.n_layers-1:
                W_next = self.params[2*(n+1)]

            # Solving Exercise 5.1
            if n < self.n_layers - 1 :
                ent = np.dot(W_next.T, ent )
                ent *= activations[ n ] * (1 - activations[ n ] ) # This is correct but confusing n+1 is n in the guide
            else:  # NOTE: This assumes cross entropy cost
                if self.actvfunc[ n ] == 'sigmoid':
                    ent = ( activations[ n ] - y ) / y.shape[ 0 ]
                elif self.actvfunc[ n ] == 'softmax':
                    I = index2onehot( y , W.shape[ 0 ] )
                    ent = (activations[ n ] - I ) / y.shape[ 0 ]

            nabla_W = np.zeros( W.shape )
            for l in np.arange( ent.shape[ 1 ] ):
                if n == 0:
                    nabla_W += np.outer( ent[ :, l ], x[ :, l] )
                else:
                    nabla_W += np.outer( ent[ :, l ], activations[ n - 1] [ :, l ] )
            nabla_b = np.sum( ent , 1, keepdims=True )

            #End of the solution 5.1

            # Store the gradients
            nabla_params[2*n] = nabla_W
            nabla_params[2*n+1] = nabla_b

        return nabla_params