[SOLVED] Deep Learning Visual Computing Assignment 2-Multi-layer neural networks

35.00 $

Category: Tags: , , , , , , ,
Click Category Button to View Your Next Assignment | Homework

You will receive the following solution file(s) instantly after successful payment:

zip file icon 2.-Multi-layer-neural-networks-vdx5p7.zip (534.2 KB)
Assignment Instructions Updated Recently? Submit Below and we will provide new Solution!
Submit New Instructions
🔒 Securely Powered by:
Secure Checkout
5/5 - (2 votes)

Assignment 2

In this assignment we will be build a multi layer neural network and train it to classify hand-written digits into 10 classes (digits 0-9). We will use the MNIST dataset of handwritten digits for training the classifier. The dataset is a good example of real-world data and is popular in the Machine Learning community.

In [186]:

Load and Visualize Data

MNIST dataset contains grayscale samples of handwritten digits of size 28 examples.

trX.shape:  (60000, 1, 28, 28)
trY.shape:  (60000,)
tsX.shape:  (10000, 1, 28, 28)
tsY.shape:  (10000,)
trX.shape:  (784, 2000)
trY.shape:  (1, 2000)
tsX.shape:  (784, 2000)
tsY.shape:  (1, 2000)
Train max: value = 1.0, Train min: value = -1.0
Test max: value = 1.0, Test min: value = -1.0
Unique labels in train:  [0 1 2 3 4 5 6 7 8 9]
Unique labels in test:  [0 1 2 3 4 5 6 7 8 9]
Displaying a few samples
labels
[[0 9 0 5 0 7 0 0 5 6]
 [0 5 4 4 6 7 3 0 9 7]
 [8 8 8 7 6 2 2 1 9 6]
 [8 1 7 2 0 3 5 2 7 6]
 [1 0 6 3 8 0 4 1 5 5]
 [9 1 3 1 8 2 7 5 1 6]
 [1 1 7 8 7 4 4 1 3 4]
 [7 7 8 1 8 6 4 4 2 8]
 [5 8 9 6 7 4 1 7 5 1]
 [0 6 5 8 6 9 8 4 1 5]]

We split the assignment into 2 sections.

Section 1

28. It is split into training set of 60,000 examples, and a test set of 10,000

In [189]:

In [190]:

In [192]:

In [193]:

In [195]:

In [196]:

In [197]:

In [198]:

In [200]:

In [114]:

In [202]:

In [203]:

In [117]:

In [205]:

In [207]:

In [208]:

In [209]:

In [210]:

In [212]:

In [213]:

In [214]:

In [215]:

In [218]:

In [219]:

In [220]:

We will define the activation functions and their derivatives which will be used later during forward and backward propagation. We will define the softmax cross entropy loss for calculating the prediction loss.

Section 2

We will initialize the network and define forward and backward propagation through a single layer. We will extend this to multiple layers of a network. We will initialize and train the multi-layer neural network

Section 1 Activation Functions

An Activation function usually adds nonlinearity to the output of a network layer using a mathematical operation. We will use two types of activation function in this assignment,

Rectified Linear Unit or ReLU Linear activation (This is a dummy activation function without any nonlinearity implemented for convenience)

ReLU (Rectified Linear Unit) (10 points)

ReLU (Rectified Linear Unit) is a piecewise linear function defined as Hint: use numpy.maximum

ReLU – Gradient (15 points)

The gradient of ReLu( ) is 1 if else it is 0.

Linear Activation

There is no activation involved here. It is an identity function.

Softmax Activation and Cross-entropy Loss Function (15 Points)

The softmax activation is computed on the outputs from the last layer and the output label with the maximum probablity is predicted as class label. The

In [ ]:

# Contains hidden tests testing for test data accuracy > 85%
#import libraries and functions to load the data

from digits import get_mnist
from matplotlib import pyplot as plt import numpy as np
import ast
import sys
import numpy.testing as npt
import pytest
import random

random.seed(1)
np.random.seed(1)
trX, trY, tsX, tsY = get_mnist()
print('trX.shape: ', trX.shape)
print('trY.shape: ', trY.shape)
print('tsX.shape: ', tsX.shape)
print('tsY.shape: ', tsY.shape)
# The data is of the format (no_samples, channels, img_height, img_width)
# In the training data trX, there are 60000 images. Each image has one channel (gray scale).
# Each image is of height=28 and width=28 pixels
# Lets sample a smaller subest to work with.
# We will use 2000 training examples and 1000 test samples.
# We define a function which we can use later as well

def sample_mnist(n_train=2000, n_test=1000): trX, trY, tsX, tsY = get_mnist() random.seed(1)
np.random.seed(1)

    tr_idx = np.random.choice(trX.shape[0], n_train)
    trX = trX[tr_idx]
    trY = trY[tr_idx]
    ts_idx = np.random.choice(tsX.shape[0], n_train)
    tsX = tsX[ts_idx]

tsY = tsY[ts_idx]
trX = trX.reshape(-1, 28*28).T trY = trY.reshape(1, -1)
tsX = tsX.reshape(-1, 28*28).T tsY = tsY.reshape(1, -1) return trX, trY, tsX, tsY

# Lets verify the function

trX, trY, tsX, tsY = sample_mnist(n_train=2000, n_test=1000) # Lets examine the data and see if it is normalized print(‘trX.shape: ‘, trX.shape)
print(‘trY.shape: ‘, trY.shape)

print(‘tsX.shape: ‘, tsX.shape)
print(‘tsY.shape: ‘, tsY.shape)
print(‘Train max: value = {}, Train min: value = {}’.format(np.max(trX), np.min(trX))) print(‘Test max: value = {}, Test min: value = {}’.format(np.max(tsX), np.min(tsX))) print(‘Unique labels in train: ‘, np.unique(trY))
print(‘Unique labels in test: ‘, np.unique(tsY))

# Let's visualize a few samples and their labels from the train and test datasets.

print(‘\nDisplaying a few samples’)
visx = np.concatenate((trX[:,:50],tsX[:,:50]), axis=1).reshape(28,28,10,10).transpose(2,0,3,1).reshape(28*10,-1) visy = np.concatenate((trY[:,:50],tsY[:,:50]), axis=1).reshape(10,-1)
print(‘labels’)
print(visy)
plt.figure(figsize = (8,8))
plt.axis(‘off’)
plt.imshow(visx, cmap=’gray’);

def relu(Z): ”’

    Computes relu activation of input Z
    Inputs:
        Z: numpy.ndarray (n, m) which represent 'm' samples each of 'n' dimension
    Outputs:
        A: where A = ReLU(Z) is a numpy.ndarray (n, m) representing 'm' samples each of 'n' dimension
        cache: a dictionary with {"Z", Z}

”’

cache = {}
# your code here

    A = np.maximum(0,Z)
    cache["Z"]=Z

return A, cache

#Test

z_tst = [-2,-1,0,1,2]
a_tst, c_tst = relu(z_tst)
npt.assert_array_equal(a_tst,[0,0,0,1,2])
npt.assert_array_equal(c_tst["Z"], [-2,-1,0,1,2])

def relu_der(dA, cache): ”’

    Computes derivative of relu activation
    Inputs:
        dA: derivative from the subsequent layer of dimension (n, m).
            dA is multiplied elementwise with the gradient of ReLU
        cache: dictionary with {"Z", Z}, where Z was the input
            to the activation layer during forward propagation
    Outputs:
        dZ: the derivative of dimension (n,m). It is the elementwise
            product of the derivative of ReLU and dA

”’

dZ = np.array(dA, copy=True) Z = cache[“Z”]
# your code here
for i in range(Z.shape[0]):

for j in range(Z.shape[1]): if Z[i][j] > 0:

dZ[i][j]=dA[i][j] else:

return dZ

dZ[i][j]=0

#Test

dA_tst = np.array([[0,2],[1,1]])
cache_tst = {}
cache_tst['Z'] = np.array([[-1,2],[1,-2]])
npt.assert_array_equal(relu_der(dA_tst,cache_tst),np.array([[0,2],[1,0]]))

def linear(Z): ”’

    Computes linear activation of Z
    This function is implemented for completeness
    Inputs:
        Z: numpy.ndarray (n, m) which represent 'm' samples each of 'n' dimension
    Outputs:
        A: where A = Linear(Z) is a numpy.ndarray (n, m) representing 'm' samples each of 'n' dimension
        cache: a dictionary with {"Z", Z}

”’

A=Z
cache = {} cache[“Z”] = Z return A, cache

def linear_der(dA, cache): ”’

    Computes derivative of linear activation
    This function is implemented for completeness
    Inputs:
        dA: derivative from the subsequent layer of dimension (n, m).
            dA is multiplied elementwise with the gradient of Linear(.)
        cache: dictionary with {"Z", Z}, where Z was the input
            to the activation layer during forward propagation
    Outputs:
        dZ: the derivative of dimension (n,m). It is the elementwise
            product of the derivative of Linear(.) and dA

”’

dZ = np.array(dA, copy=True) return dZ

softmax function can also be refered as normalized exponential function which takes a vector of distribution consisting of probabilities proportional to the exponentials of the input numbers.

real numbers as input, and normalizes it into a probability

is the sample of dimensions. We estimate the softmax , where the components of are,

The input to the softmax function is the matrix,
for each of the samples to . The softmax activation for sample

, where

The output of the softmax is from all the input components of

If the output of softmax is given by groundtruth labels is given by,

, where
before calculating the softmax. This constant is

and the ground truth is given by

. In order to avoid floating point overflow, we subtract a constant , where, . The activation is given by,

, the cross entropy loss between the predictions and

is

where is the identity function given by

Hint: use numpy.exp numpy.max, numpy.sum numpy.log Also refer to use of ‘keepdims’ and ‘axis’ parameter.

def softmax_cross_entropy_loss(Z, Y=np.array([])): ”’

    Computes the softmax activation of the inputs Z
    Estimates the cross entropy loss
    Inputs:
        Z: numpy.ndarray (n, m)
        Y: numpy.ndarray (1, m) of labels
            when y=[] loss is set to []
    Outputs:
        A: numpy.ndarray (n, m) of softmax activations
        cache: a dictionary to store the activations which will be used later to estimate derivatives
        loss: cost of prediction

”’

    # your code here

A=np.copy(Z)
if (Y.size == 0):

loss = [] else:

        loss = 0
    m = Z.shape[1]

for col in range(Z.shape[1]):

sum_exp = np.sum(np.exp(Z[:,col])) for row in range(Z.shape[0]):

A[row][col]=np.exp(Z[row][col])/sum_exp if (Y.size!=0 and Y[0][col]==row):

loss = loss + np.log(A[row][col]) if (Y.size != 0):

        loss = -1/m * loss

cache = {} cache[“A”] = A return A, cache, loss

#test cases for softmax_cross_entropy_loss
np.random.seed(1)
Z_t = np.random.randn(3,4)
Y_t = np.array([[1,0,1,2]])
A_t = np.array([[0.57495949, 0.38148818, 0.05547572, 0.36516899],
       [0.26917503, 0.07040735, 0.53857622, 0.49875847],
       [0.15586548, 0.54810447, 0.40594805, 0.13607254]])
A_est, cache_est, loss_est = softmax_cross_entropy_loss(Z_t, Y_t)
npt.assert_almost_equal(loss_est,1.2223655548779273,decimal=5)
npt.assert_array_almost_equal(A_est,A_t,decimal=5)
npt.assert_array_almost_equal(cache_est['A'],A_t,decimal=5)
# hidden test cases follow

Derivative of the softmax_cross_entropy_loss(.) (15 points)

We discused in the lecture that it is easier to directly estimate which is , where

Let be the dimension input and be the groundtruth labels. If given by,

where, is the one-hot representation of .

is the input to the softmax_cross_entropy_loss(

One-hot encoding is a binary representation of the discrete class labels. For example, let data points. In this case will be a matrix. Let the categories of the 4 data points be

for a 3-category problem. Assume there are . The one hot representation is given by,

is

where, the one-hot encoding for label

Section 2
Parameter Initialization (10 points)

is . Similarly, the one-hot encoding for

def softmax_cross_entropy_loss_der(Y, cache): ”’

    Computes the derivative of the softmax activation and cross entropy loss
    Inputs:
        Y: numpy.ndarray (1, m) of labels
        cache: a dictionary with cached activations A of size (n,m)
    Outputs:
        dZ: derivative dL/dZ - a numpy.ndarray of dimensions (n, m)

”’

    Y_hot=np. array([])
    A = cache["A"]
    dZ = np.copy(A)
    m = Y.shape[1]

for col in range(A.shape[1]):
for row in range(A.shape[0]):

if (Y[0][col]==row):
dZ[row][col]= 1/m * (A[row][col] – 1)

else:
dZ[row][col]= 1/m * A[row][col]

    # your code here

return dZ

#test cases for softmax_cross_entropy_loss_der
np.random.seed(1)
Z_t = np.random.randn(3,4)
Y_t = np.array([[1,0,1,2]])
A_t = np.array([[0.57495949, 0.38148818, 0.05547572, 0.36516899],
       [0.26917503, 0.07040735, 0.53857622, 0.49875847],
       [0.15586548, 0.54810447, 0.40594805, 0.13607254]])
cache_t={}
cache_t['A'] = A_t
dZ_t = np.array([[ 0.14373987, -0.15462795,  0.01386893,  0.09129225],
       [-0.18270624,  0.01760184, -0.11535594,  0.12468962],
       [ 0.03896637,  0.13702612,  0.10148701, -0.21598186]])
dZ_est = softmax_cross_entropy_loss_der(Y_t, cache_t)
npt.assert_almost_equal(dZ_est,dZ_t,decimal=5)
# hidden test cases follow

Let us now define a function that can initialize the parameters of the multi-layer neural network. The network parameters will be stored as dictionary elements that can easily be passed as function parameters while calculating gradients during back propogation.

1. The weight matrix is initialized with random values from a normal distribution with variance . For example, to create a matrix of dimension , with

values from a normal distribution with variance , we write

zero for faster training.
2. Bias values are initialized with 0. For example a bias vector of dimensions is initialized as

The dimension for weight matrix for layer is given by ( Number-of-neurons-in-layer- bias for for layer is (Number-of-neurons-in-layer- 1)

def initialize_network(net_dims): ”’

    Initializes the parameters of a multi-layer neural network

. The is to ensure very small values close to

    Inputs:
        net_dims: List containing the dimensions of the network. The values of the array represent the number of nod
es in
        each layer. For Example, if a Neural network contains 784 nodes in the input layer, 800 in the first hidden
 layer,
        500 in the secound hidden layer and 10 in the output layer, then net_dims = [784,800,500,10].
    Outputs:
        parameters: Python Dictionary for storing the Weights and bias of each layer of the network

”’

numLayers = len(net_dims) parameters = {}
for l in range(numLayers-1):

# Hint:
# parameters[“W”+str(l+1)] =
# parameters[“b”+str(l+1)] =
# your code here
dim_current_layer = net_dims[l+1]
dim_previous_layer = net_dims[l]
parameters[“W”+str(l+1)] = 0.01 * np.random.randn(dim_current_layer, dim_previous_layer) parameters[“b”+str(l+1)] = np.zeros((dim_current_layer,1))

return parameters

#Test

net_dims_tst = [5,4,1]
parameters_tst = initialize_network(net_dims_tst) assert parameters_tst[‘W1’].shape == (4,5)
assert parameters_tst[‘W2’].shape == (1,4)
assert parameters_tst[‘b1’].shape == (4,1)
assert parameters_tst[‘b2’].shape == (1,1)
assert parameters_tst[‘b1’].all() == 0
assert parameters_tst[‘b2’].all() == 0
# There are hidden tests

Forward Propagation Through a Single Layer (5 points)

If the vectorized input to any layer of neural network is activation is):

def linear_forward(A_prev, W, b): ”’

    Input A_prev propagates through the layer
    Z = WA + b is the output of this layer.

and the parameters of the layer is given by

, the output of the layer (before the

    Inputs:
        A_prev: numpy.ndarray (n,m) the input to the layer
        W: numpy.ndarray (n_out, n) the weights of the layer
        b: numpy.ndarray (n_out, 1) the bias of the layer
    Outputs:
        Z: where Z = W.A_prev + b, where Z is the numpy.ndarray (n_out, m) dimensions
        cache: a dictionary containing the inputs A

”’

    # your code here
    Z = np.dot(W, A_prev) + b

cache = {} cache[“A”] = A_prev return Z, cache

#Hidden test cases follow
np.random.seed(1)
n1 = 3
m1 = 4
A_prev_t = np.random.randn(n1,m1)
W_t = np.random.randn(n1, n1)
b_t = np.random.randn(n1, 1)
Z_est, cache_est = linear_forward(A_prev_t, W_t, b_t)

Activation After Forward Propagation

The linear transformation in a layer is usually followed by a nonlinear activation function given by,

Depending on the activation choosen for the given layer, the can represent different operations.

def layer_forward(A_prev, W, b, activation): ”’

    Input A_prev propagates through the layer and the activation
    Inputs:
        A_prev: numpy.ndarray (n,m) the input to the layer
        W: numpy.ndarray (n_out, n) the weights of the layer
        b: numpy.ndarray (n_out, 1) the bias of the layer
        activation: is the string that specifies the activation function
    Outputs:
        A: = g(Z), where Z = WA + b, where Z is the numpy.ndarray (n_out, m) dimensions
        g is the activation function
        cache: a dictionary containing the cache from the linear and the nonlinear propagation
        to be used for derivative

”’

Z, lin_cache = linear_forward(A_prev, W, b) if activation == “relu”:

A, act_cache = relu(Z) elif activation == “linear”: A, act_cache = linear(Z)

cache = {}
cache[“lin_cache”] = lin_cache cache[“act_cache”] = act_cache return A, cache

Multi-Layers Forward Propagation

Multiple layers are stacked to form a multi layer network. The number of layers in the network can be inferred from the size of the initialize_network() function. If the number of items in the dictionary element is , then the number of layers will be

variable from

During forward propagation, the input which is a matrix of samples where each sample is dimensions, is input into the first layer. The subsequent layers use the activation output from the previous layer as inputs.

Note all the hidden layers in our network use ReLU activation except the last layer which uses Linear activation. Forward Propagation

def multi_layer_forward(A0, parameters): ”’

    Forward propgation through the layers of the network
    Inputs:
        A0: numpy.ndarray (n,m) with n features and m samples
        parameters: dictionary of network parameters {"W1":[..],"b1":[..],"W2":[..],"b2":[..]...}
    Outputs:
        AL: numpy.ndarray (c,m)  - outputs of the last fully connected layer before softmax
            where c is number of categories and m is number of samples
        caches: a dictionary of associated caches of parameters and network inputs

”’

    L = len(parameters)//2
    A = A0
    caches = []

for l in range(1,L):
A, cache = layer_forward(A, parameters[“W”+str(l)], parameters[“b”+str(l)], “relu”) caches.append(cache)

AL, cache = layer_forward(A, parameters[“W”+str(L)], parameters[“b”+str(L)], “linear”) caches.append(cache)
return AL, caches

Backward Propagagtion Through a Single Layer (10 points)

Consider the linear layer represented as

. We would like to estimate the gradients – represented as , – represented as . The input to estimate these derivatives is – represented as . The derivatives are given by,

and –

is of

where dimensions

is matrix of derivatives. The figure below represents a case fo binary cassification where . The example can be extended to .

Backward Propagation

def linear_backward(dZ, cache, W, b): ”’

    Backward prpagation through the linear layer
    Inputs:
        dZ: numpy.ndarray (n,m) derivative dL/dz
        cache: a dictionary containing the inputs A, for the linear layer
            where Z = WA + b,
            Z is (n,m); W is (n,p); A is (p,m); b is (n,1)
        W: numpy.ndarray (n,p)
        b: numpy.ndarray (n, 1)
    Outputs:
        dA_prev: numpy.ndarray (p,m) the derivative to the previous layer
        dW: numpy.ndarray (n,p) the gradient of W
        db: numpy.ndarray (n, 1) the gradient of b

”’

A = cache[“A”]
# your code here
dA_prev = np.dot(np.transpose(W), dZ) dW = np.dot(dZ, np.transpose(A))
db = np.sum(dZ, axis=1, keepdims=True) return dA_prev, dW, db

#Hidden test cases follow
np.random.seed(1)
n1 = 3
m1 = 4
p1 = 5
dZ_t = np.random.randn(n1,m1)
A_t = np.random.randn(p1,m1)
cache_t = {}
cache_t['A'] = A_t
W_t = np.random.randn(n1,p1)
b_t = np.random.randn(n1,1)

dA_prev_est, dW_est, db_est = linear_backward(dZ_t, cache_t, W_t, b_t) Back Propagation With Activation

We will define the backpropagation for a layer. We will use the backpropagation for a linear layer along with the derivative for the activation.

def layer_backward(dA, cache, W, b, activation): ”’

    Backward propagation through the activation and linear layer
    Inputs:
        dA: numpy.ndarray (n,m) the derivative to the previous layer
        cache: dictionary containing the linear_cache and the activation_cache
        activation - activation of the layer
        W: numpy.ndarray (n,p)
        b: numpy.ndarray (n, 1)
    Outputs:
        dA_prev: numpy.ndarray (p,m) the derivative to the previous layer
        dW: numpy.ndarray (n,p) the gradient of W
        db: numpy.ndarray (n, 1) the gradient of b

”’

    lin_cache = cache["lin_cache"]
    act_cache = cache["act_cache"]

if activation == “relu”:
dZ = relu_der(dA, act_cache)

elif activation == “linear”:
dZ = linear_der(dA, act_cache)

dA_prev, dW, db = linear_backward(dZ, lin_cache, W, b) return dA_prev, dW, db

Multi-layers Back Propagation

We have defined the required functions to handle back propagation for single layer. Now we will stack the layers together and perform back propagation on the entire network.

def multi_layer_backward(dAL, caches, parameters): ”’

    Back propgation through the layers of the network (except softmax cross entropy)
    softmax_cross_entropy can be handled separately
    Inputs:
        dAL: numpy.ndarray (n,m) derivatives from the softmax_cross_entropy layer
        caches: a dictionary of associated caches of parameters and network inputs
        parameters - dictionary of network parameters {"W1":[..],"b1":[..],"W2":[..],"b2":[..]...}
    Outputs:
        gradients: dictionary of gradient of network parameters
            {"dW1":[..],"db1":[..],"dW2":[..],"db2":[..],...}

”’

L = len(caches)
gradients = {}
dA = dAL
activation = “linear”
for l in reversed(range(1,L+1)):

        dA, gradients["dW"+str(l)], gradients["db"+str(l)] = \
                    layer_backward(dA, caches[l-1], \
                    parameters["W"+str(l)],parameters["b"+str(l)],\
                    activation)
        activation = "relu"

return gradients

Prediction (10 points)

We will perform forward propagation through the entire network and determine the class predictions for the input data

def

#

classify(X, parameters):
”’
Network prediction for inputs X

Inputs:
    X: numpy.ndarray (n,m) with n features and m samples
    parameters: dictionary of network parameters
        {"W1":[..],"b1":[..],"W2":[..],"b2":[..],...}
Outputs:
    YPred: numpy.ndarray (1,m) of predictions
'''
# Forward propagate input 'X' using multi_layer_forward(.) and obtain the final activation 'A'
# Using 'softmax_cross_entropy loss(.)', obtain softmax activation 'AL' with input 'A' from step 1
# Predict class label 'YPred' as the 'argmax' of softmax activation from step-2.
# Note: the shape of 'YPred' is (1,m), where m is the number of samples
# your code here
A, caches = multi_layer_forward(X, parameters)
AL,cache,loss = softmax_cross_entropy_loss(A)
YPred = np.array([])
  YPred = np.reshape(YPred, (-1,1))

YPred = np.argmax(AL, axis=0)
YPred = YPred.reshape(-1, YPred.size) return YPred

#Hidden test cases follow
np.random.seed(1)
n1 = 3
m1 = 4
p1 = 2
X_t = np.random.randn(n1,m1)
W1_t = np.random.randn(p1,n1)
b1_t = np.random.randn(p1,1)
W2_t = np.random.randn(p1,p1)
b2_t = np.random.randn(p1,1)
parameters_t = {'W1':W1_t, 'b1':b1_t, 'W2':W2_t, 'b2':b2_t}
YPred_est = classify(X_t, parameters_t)

Parameter Update Using Batch-Gradient

The parameter gradients calculated during back propagation are used to update the values of the network parameters.

where is the learning rate of the network.

def update_parameters(parameters, gradients, epoch, alpha): ”’

    Updates the network parameters with gradient descent
    Inputs:
        parameters: dictionary of network parameters
            {"W1":[..],"b1":[..],"W2":[..],"b2":[..],...}
        gradients: dictionary of gradient of network parameters
            {"dW1":[..],"db1":[..],"dW2":[..],"db2":[..],...}
        epoch: epoch number
        alpha: step size or learning rate
    Outputs:
        parameters: updated dictionary of network parameters
            {"W1":[..],"b1":[..],"W2":[..],"b2":[..],...}

”’

L = len(parameters)//2 for i in range(L):

#parameters[“W”+str(i+1)] =
#parameters[“b”+str(i+1)] =
# your code here
parameters[“W”+str(i+1)] = parameters[“W”+str(i+1)] – alpha * gradients[“dW”+str(i+1)] parameters[“b”+str(i+1)] = parameters[“b”+str(i+1)] – alpha * gradients[“db”+str(i+1)]

return parameters Neural Network

Let us now assemble all the components of the neural network together and define a complete training loop for a Multi-layer Neural Network.

def multi_layer_network(X, Y, net_dims, num_iterations=500, learning_rate=0.1, log=True): ”’

    Creates the multilayer network and trains the network
    Inputs:
        X: numpy.ndarray (n,m) of training data
        Y: numpy.ndarray (1,m) of training data labels
        net_dims: tuple of layer dimensions
        num_iterations: num of epochs to train
        learning_rate: step size for gradient descent
        log: boolean to print training progression
    Outputs:
        costs: list of costs (or loss) over training
        parameters: dictionary of trained network parameters

”’

    parameters = initialize_network(net_dims)
    A0 = X
    costs = []
    num_classes = 10

alpha = learning_rate
for ii in range(num_iterations):

        ## Forward Propagation
        # Step 1: Input 'A0' and 'parameters' into the network using multi_layer_forward()
        #         and calculate output of last layer 'A' (before softmax) and obtain cached activations as 'caches'
        # Step 2: Input 'A' and groundtruth labels 'Y' to softmax_cros_entropy_loss(.) and estimate
        #         activations 'AL', 'softmax_cache' and 'loss'
        ## Back Propagation
        # Step 3: Estimate gradient 'dAL' with softmax_cros_entropy_loss_der(.) using groundtruth
        #         labels 'Y' and 'softmax_cache'
        # Step 4: Estimate 'gradients' with multi_layer_backward(.) using 'dAL' and 'parameters'
        # Step 5: Estimate updated 'parameters' and updated learning rate 'alpha' with update_parameters(.)
  •         #          using 'parameters', 'gradients', loop variable 'ii' (epoch number) and 'learning_rate'
    
  •         #          Note: Use the same variable 'parameters' as input and output to the update_parameters(.) function
    
            # your code here
    
            A, caches = multi_layer_forward(A0, parameters)
            AL, softmax_cache, cost = softmax_cross_entropy_loss(A, Y)
            dAL = softmax_cross_entropy_loss_der(Y, softmax_cache)
            gradients = multi_layer_backward(dAL, caches, parameters)
            parameters = update_parameters(parameters, gradients, ii, learning_rate)
    

    if ii % 20 == 0: costs.append(cost) if log:

    print(“Cost at iteration %i is: %.05f, learning rate: %.05f” %(ii+1, cost, learning_rate)) return costs, parameters

    Training – 10 points

    We will now intialize a neural network with 1 hidden layer whose dimensions is 200. Since the input samples are of dimension 28 28, the input layer will be of dimension 784. The output dimension is 10 since we have a 10 category classification. We will train the model and compute its accuracy on both training and test sets and plot the training cost (or loss) against the number of iterations.

    # You should be able to get a train accuracy of >90% and a test accuracy >85%
    # The settings below gave >95% train accuracy and >90% test accuracy
    # Feel free to adjust the values and explore how the network behaves
    

    net_dims = [784,200,10]
    #784 is for image dimensions #10 is for number of categories #200 is arbitrary

    # initialize learning rate and num_iterations
    
    learning_rate = 0.1
    num_iterations = 500
    
    np.random.seed(1)
    print("Network dimensions are:" + str(net_dims))
    
    # getting the subset dataset from MNIST
    
    trX, trY, tsX, tsY = sample_mnist(n_train=2000, n_test=1000)
    costs, parameters = multi_layer_network(trX, trY, net_dims, \
    

    num_iterations=num_iterations, learning_rate=learning_rate) # compute the accuracy for training set and testing set

    train_Pred = classify(trX, parameters)
    test_Pred = classify(tsX, parameters)
    

    #Estimate the training accuracy ‘trAcc’ and the testing accuracy ‘teAcc’ # your code here
    if trY.size!=0:

    trAcc = np.mean(train_Pred==trY) if tsY.size!=0:

    teAcc = np.mean(test_Pred==tsY)
    print(“Accuracy for training set is {0:0.3f} %”.format(trAcc))

    print(“Accuracy for testing set is {0:0.3f} %”.format(teAcc))

    plt.plot(costs)
    plt.xlabel("Iterations")
    plt.ylabel("Loss")
    plt.show()
    
    Network dimensions are:[784, 200, 10]
    Cost at iteration 1 is: 2.30262, learning rate: 0.10000
    Cost at iteration 21 is: 1.80242, learning rate: 0.10000
    Cost at iteration 41 is: 0.92838, learning rate: 0.10000
    Cost at iteration 61 is: 0.71804, learning rate: 0.10000
    Cost at iteration 81 is: 0.58955, learning rate: 0.10000
    Cost at iteration 101 is: 0.53325, learning rate: 0.10000
    Cost at iteration 121 is: 0.43405, learning rate: 0.10000
    Cost at iteration 141 is: 0.42289, learning rate: 0.10000
    Cost at iteration 161 is: 0.34212, learning rate: 0.10000
    Cost at iteration 181 is: 0.33355, learning rate: 0.10000
    Cost at iteration 201 is: 0.31770, learning rate: 0.10000
    Cost at iteration 221 is: 0.28235, learning rate: 0.10000
    Cost at iteration 241 is: 0.27505, learning rate: 0.10000
    Cost at iteration 261 is: 0.24805, learning rate: 0.10000
    Cost at iteration 281 is: 0.23275, learning rate: 0.10000
    Cost at iteration 301 is: 0.22678, learning rate: 0.10000
    Cost at iteration 321 is: 0.20941, learning rate: 0.10000
    Cost at iteration 341 is: 0.20796, learning rate: 0.10000
    Cost at iteration 361 is: 0.18465, learning rate: 0.10000
    Cost at iteration 381 is: 0.17449, learning rate: 0.10000
    Cost at iteration 401 is: 0.17399, learning rate: 0.10000
    Cost at iteration 421 is: 0.15403, learning rate: 0.10000
    Cost at iteration 441 is: 0.14431, learning rate: 0.10000
    Cost at iteration 461 is: 0.14161, learning rate: 0.10000
    Cost at iteration 481 is: 0.13169, learning rate: 0.10000
    Accuracy for training set is 0.976 %
    Accuracy for testing set is 0.902 %
    

is the

) function.
matrix of softmax activations of , the derivative is

Number-of-neurons-in-layer-

). The dimension of the

4 = m

}2,1,0{ ∈ )i(y

A

Zd

)m × n(

])m(zd,…,)2(zd,)1(zd[ = Zd

L sretemarap

L2 sretemarap

×

verp_Ad bd
Ld Ld Ld

l

× )1+l( ))4 ,3((sorez .pn = b

)1+l(

4×3w1

⊤]1,0,0[ = )4( ̄y

2 = )4(y ]2,1,0,1[= Y

⎦1000⎣
⎥ 0 1 0 1 ⎢ = ̄Y ⎤0010⎡

⊤]0,1,0[ = )1( ̄y

1 = )1(y
4×3 Z

bd Wd

Wd

)b , W(

verp_A

n≤k≤1 rof )nz…,2z,1z(xam = xamz

)i( )xamz −

n =)i(ka kz(pxe

)i(a
n

))i(z(xamtfos = )i(a )i(z

m 1 )m × n(

n

m m×n 0A

hti )i(z n

])m(z,…,)2(z,)1(z[ = Z

Zd

Zd Ld

verp_Ad b+verp_A.W=Z

1 × 3
10.0 )4 ,3(ndnar .modnar .pn ∗ 10.0 = w

1

,bd.α−b=:b Wd .α − W =: W

1=i )i(Zd∑ = bd

m TAZd = Wd

Zd T W = verp_Ad

) .(σ .)Z(σ = A

b + verp_A . W = Z

b + verp_A . W = Z

) ̄Y − A ( m = Z d 1

ZdZ )m×n(A)m,1(Y)m×n(Z Z ZZdZd

eslaF = noitidnoc fi ,0 = }noitidnoc{I eurT = noitidnoc fi ,1 = }noitidnoc{I

1=k 1=i m
ki a g o l } k = i y { I ∑ ∑ 1 − = ) Y , A ( s s o L

)i(
⊤] na,…, 2a, 1a[ = )i(a

)i(z ])m(a….)2(a,)1(a[ = A

xamz
)i( )i( )i(

) kz(pxe1=k∑ n≤k≤1 rof )i( n =)i(ka

Z = )Z(raeniL

)x,0(xam = )x(ULeR

Ld

nm
])m(y,…,)2(y,)1(y[ = Y A

Y

)xamz − kz(pxe 1=k∑

) kz(pxe )i(

×

)m×n( )m×1(

× )1+l(

)1+l(

)bd , Wd(

Y ̄Y

0>Z Z

n

α

I

  • 2.-Multi-layer-neural-networks-vdx5p7.zip