{"cells":[{"metadata":{"_uuid":"b264e4ac46fcec68eddface58c8343f440734148"},"cell_type":"markdown","source":"# Aim of the Project\n\nIn this project, we  experiment with two models to classify MNIST data. First, we train a logistic regression model which shows classification accuracy of around $90\\%$ in the test dataset and $85\\%$ in the submission dataset. Second, we train a four layer neural network model on MNIST training dataset. As of now, the classification accuracy on the training dataset is around $98\\%$ and on the test dataset is around $95\\%$.\n\nThis main purpose of the project is to understand the backpropagation algorithm. The neural network model has been coded from scratch and may be extremely inefficient in practice. I plan to do further experiments on hyperparameter tuning, regularization, effect of other activitation functions, cost functions and performance evaluation on other network architectures.\n\n\n"},{"metadata":{"trusted":true,"_uuid":"de8bcb89f66015f1206a8afb086edb58ee471db5"},"cell_type":"code","source":"#!conda env list","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c8cbb055667483812b69486161116a7077f2e49d"},"cell_type":"code","source":"#import sys\n#!conda install --yes --prefix {sys.prefix} scikit-learn","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ccdf7c1aa8ef9ccc7488fd9664a1f043a0ae2d42"},"cell_type":"markdown","source":"# Packages needed"},{"metadata":{"trusted":true,"_uuid":"68ac9fd05de647d4dd9f3e142f2fcf68ab71d955"},"cell_type":"code","source":"# PACKAGE\nimport numpy as np","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cc6d8861bb2fe8e1708c0f2b1cd651789ee269d9"},"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom matplotlib import cbook\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.linear_model import LogisticRegression\n#import seaborn as sns","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6b76ad9691ee114e5d749b9e90ae4164b7ff3e8a"},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nfrom sklearn.preprocessing import MinMaxScaler\nfrom sklearn.preprocessing import StandardScaler","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c2aca5532f7538c63f51a4b9fe403a76efde1c8f"},"cell_type":"markdown","source":"# Kaggle dataset"},{"metadata":{"trusted":true,"_uuid":"39bc2af573f338217ee88a2929a2758e54af98c1"},"cell_type":"code","source":"# input methods\nimport os\nprint(os.listdir(\"../input\"))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c6d5f636b1c2f47b8968f621e084043844a1b1f9"},"cell_type":"code","source":"training_data = pd.read_csv(\"../input/train.csv\")\ntraining_data = training_data.values","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0344308044364bc123c54ed7482e85227fccae9b"},"cell_type":"markdown","source":"# Explanation of the dataset dimensions\n\n<code>training_data</code> is a numpy array with columns representing features and rows as the instances of the training dataset. The first column of the <code>training_data</code> is the label column."},{"metadata":{"_uuid":"c2aa18cbcfff49549876b659e7a038eef4c685f0"},"cell_type":"markdown","source":"# Dividing dataset into training, dev and test dataset."},{"metadata":{"trusted":true,"_uuid":"c1cb70af7e2a31aec5daa62a3fb2cf40072f2a4a"},"cell_type":"code","source":"length = training_data.shape[0]\nlength\ntraining_length = round(0.7*(length))\n#dev_length = round(0.8*(length))\nx_train = training_data[:training_length,1:].T\ny_train = training_data[:training_length,0]\n\n#x_dev = training_data[training_length+1:dev_length,1:].T\n#y_dev = training_data[training_length+1:dev_length,0]\n\nx_test = training_data[training_length+1:,1:].T\ny_test = training_data[training_length+1:,0]\n\n\n\ny_train = y_train.reshape(1,len(y_train))\n#y_dev = y_dev.reshape(1,len(y_dev))\ny_test = y_test.reshape(1,len(y_test))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f94e0ee4045799f7b1eee5a26a57d7591705426e"},"cell_type":"markdown","source":"# Data Rescaling and Standardization\n## Rescaling"},{"metadata":{"trusted":true,"_uuid":"c2ebada05dd736a076506a425a5ccd5eeeabcc07"},"cell_type":"code","source":"scaler = MinMaxScaler(feature_range=(0, 1))\nx_train = scaler.fit_transform(x_train)\nx_test = scaler.fit_transform(x_test) ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"55fdf45b796a3a19cacfe909f42694d6ace8fdf8"},"cell_type":"markdown","source":"## Standardization\n\nData preprocessing such that the mean of the data is $0$ and standard deviation is $1$."},{"metadata":{"trusted":true,"_uuid":"27c27f77bc0e643beac487be5af3c31d244b6b1d"},"cell_type":"code","source":"#scaler_train = StandardScaler().fit(x_train)\n#scaler_test = StandardScaler().fit(x_test)\n#x_train = scaler_train.transform(x_train)\n#x_test = scaler_test.transform(x_test)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"26f568568be8e337683735d7b90bd3cad55fc720"},"cell_type":"markdown","source":"The standardization has been commented out since this resulted in deterioration of the performance of the logistic regression."},{"metadata":{"_uuid":"80f8cd58336b91af8fc8097a54a0ea79dd74965c"},"cell_type":"markdown","source":"Here is an example of a training set image."},{"metadata":{"trusted":true,"_uuid":"cade1cabcbdfe078a647d896268a1cfc562b3e49"},"cell_type":"code","source":"\nimg = x_train[:,3]\nimg = img.reshape(28,28)\nplt.imshow(img,cmap = 'gray')\nplt.show()\n#y_train[:,3]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"407056167842c4ab8d60601a0ff7f9d6a65431f8"},"cell_type":"markdown","source":"# Exploratory Data Analysis"},{"metadata":{"trusted":true,"_uuid":"33a4c736c067e7a1dcb7fc7bb1af5d5df1a135d1"},"cell_type":"code","source":"count_in_labels = []\nfor i in range(10):\n    idx = y_train == i\n    count_in_labels.append(len(y_train[idx]))\n    print(\"Count in label %d is %d\"%(i,count_in_labels[i]))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f775c3de5b542f51493f385713bfe2395af5b10c"},"cell_type":"markdown","source":"All the labels have approximately same amount of instances."},{"metadata":{"_uuid":"a971b2932e788166d1b61b1a47c493708b500600"},"cell_type":"markdown","source":"# Experimenting with Logostic Regression"},{"metadata":{"_uuid":"8a10b82a21e7170dc0933fb9dddd50db325a68b0"},"cell_type":"markdown","source":"## Training the dataset"},{"metadata":{"trusted":true,"_uuid":"1659ec63d9c36448a13a2da222a4bf4186c621c2"},"cell_type":"code","source":"logisticregsr = LogisticRegression(multi_class='multinomial', solver = 'lbfgs')\ny_train_l = y_train.ravel()\nlogisticregsr.fit(x_train.T,y_train_l)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"22992c8d52c5a1dce38b0d1512870e36f51b3120"},"cell_type":"code","source":"pred = logisticregsr.predict(x_test.T)\ny_test_check = y_test.ravel()\ny_train_check = y_train.ravel()\n#y_test_check.shape\nscore_train = logisticregsr.score(x_train.T,y_train_check)*100\nprint(\"The accuracy on train data is\",score_train,\"%\")\nscore_test = logisticregsr.score(x_test.T,y_test_check)*100\nprint(\"The accuracy on test data is\",score_test,\"%\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"88a1671a6a31d8ddafd88ae0611faef3f0de48c1"},"cell_type":"markdown","source":"# Accuracy\n\nThe accuracy on the train data is around $94\\%$ and on the test data is about $92\\%$.\n\n# Confusion Matrix\n"},{"metadata":{"scrolled":true,"trusted":true,"_uuid":"827d22450bb6040ee19c0092cc87f456e9a81097"},"cell_type":"code","source":"c_matrix = confusion_matrix(y_test_check,pred)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2c6855248a4df18009a28483bcd402ff561aff42"},"cell_type":"code","source":"print(c_matrix)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5e501f8008f9b8b4cb462db8fcc5debfd7f386ce"},"cell_type":"markdown","source":"The submission set resulted in an accuracy of around 85.2%"},{"metadata":{"_uuid":"a56bd6919131baf1724806f396a45fba979523e9"},"cell_type":"markdown","source":"# Experimenting with Neural Network\n\n## Transforming the output in the dataset\n\nEach entry in <code>y_train</code> (or <code>y_test</code>) is a number in the range of 0 to 9 which is the label of the corresponding instance in x_train. The function <code>transform_output</code> takes such a label $y$ as input and outputs a binary column vector with $1$ in the $y^{th}$ position and $0$ in rest of the entries. \nFor example, if an instance has label $5$, then the corresponding transformed label vector is ${(0,0,0,0,0,1,0,0,0,0)}^T$.\n\n## Building the neural network\n\nWe define a network class which has the information of size of the layers and corresponding initializing weights and biases.\n\nTake a proper look at the indices. It can get confusing. if there are three layers, then there will be two weight matrices and biases.\n\n### Cost function\n\nLet $y$ be the transformed label vector of an arbitrary instance and $a$ be the output of the model. Then the cost function $C$ is defined as : \n\n$$ C(y,a) =  \\frac{{||y-a||}^{2}}{2} $$\n\nOver the whole training set, the (vectorized) cost function is an average of cost functions of all the instances,\n\n$$ C(Y,A) = \\frac{1}{2m}\\sum\\limits_{i=1}^{m}C(y^{(i)},a^{(i)})$$\n\nwhere $Y =[y^{(1)}\\ ...\\ y^{(m)}]$, $A = [a^{(1)}\\ ...\\ a^{(m)}]$ and $y^{(i)}$ and $a^{(i)}$ are the transformed label vector and output of the model respectively. Observe that both $y^{(i)}$ and $a^{(i)}$ are column vectors.\n\nOne important thing to note that $Y$ is given and $A$ is computed by the model. Therefore, the actual variables in the cost function are actually the weights and biases of the neural networks. \n\n### He Initialization\n\n### Activation function\n\nWe use RELU as the activation function for hidden layers and sigmoid for probability estimation for output layer.\n\n### Feedforward \n\nGiven a neural network with its set of weights, biases and input vector $x$, feedforward computes the prediction vector $a$ (where value at each entry i is the probability that x belongs to the class i). The computation at layer $l$ is \n$$ z^{[l]} = w^{[l]}.a^{[l-1]} +b^{[l]} $$\n$$ a^{[l]} = \\sigma(z^{[l]})$$\n\nI have defined two functions <code>feedforward</code> and <code>feedforward_output</code>. <code>feedforward</code>, along with computing $a$, also caches $z$ and $a$ so that they can be used in backpropagation. The other function just computes $a$.\n\n### Backpropagation\n\nBackpropagation is used to compute $\\frac{\\partial C}{\\partial w^{[l]}}$ and $\\frac{\\partial C}{\\partial b^{[l]}}$ for all layers $l$ in the neural network. <code>backpropagation</code> returns two lists of the partial derivatives of all the weights and biases($dw$ and $db$).\n\nComputation of the partial derivatives make use of the following formulae:\n\n$$ \\frac{\\partial C}{\\partial w^{[l]}} =  \\frac{\\partial C}{\\partial z^{[l]}}. \\frac{\\partial z^{[l]}}{\\partial w^{[l]}} $$\n\n$$  \\frac{\\partial C}{\\partial b^{[l]}} =  \\frac{\\partial C}{\\partial z^{[l]}}$$\n\nIn the code, we represent $\\frac{\\partial C}{\\partial w^{[l]}}$ as $dw$, $\\frac{\\partial C}{\\partial b^{[l]}}$\nas db and  $\\frac{\\partial C}{\\partial z^{[l]}}$ as $dz$.\n\nIn the vectorized form (i.e over all inputs of the batch), dw and db are computed as:\n\n$$ dw^{[l]} =  \\frac{1}{m}dz.{A^{[t]}}^T$$\n$$ db^{[l]} = \\frac{1}{m}.\\sum\\limits_{i=1}^{m} dz^{[l]}[:,i]$$\n\n### compute_dZ function\n\n$dz^{[l]}$ is computed using the compute_dZ function. \nIn the vectorized form, it is computed using the following equation: \n\n$$dz^{[L]} = \\nabla_a C*\\sigma'(z^{[L]}) $$\n$$dz^{[l]} = {w^{[l+1]}}^T.dz^{[l+1]}*\\sigma'(z^{[l]})$$\n\nHere $*$ is a broadcast operation.\n\nTherefore, <code>compute_dZ</code> takes as arguments, training data (<code>batch_x,batch_y</code>), $l$ (current layer), $z$ values (stored in <code>Z_cache</code>), and $dz^{l+1}$ (as <code>dZ</code>).\n\n### Exponentially Weighted average\n\nGiven a set of points $\\lbrace a_1,...,a_n\\rbrace$, moving average $\\lbrace v_1,...,v_n\\rbrace$ is computed as follows:\n\n<ul>\n<li> Initialize $v_1 = 0$.</li>\n<li> \nFor $i = 2$ to $n$:\n<ul>\n   <li>$ v_i = \\beta v_{i-1} + (1 - \\beta)a_i $</li>\n</ul>        \n</li>\n</ul> \n\nwhere $\\beta\\in (0,1)$.\n\nThe set $\\lbrace v_1,v_2,...,v_n\\rbrace$ is tolerant to noise in the original dataset.\n\n### Gradient Descent with Moment\n\nWe use the idea of exponentially weighted average to gradient descent. For every iteration, we use backpropagation to compute <code>dw</code> and <code>db</code> and then compute the exponentially weighted average using the computed gradients.\n<ul>\n<li> Compute <code>dw</code> and <code>db</code> using <code>backpropagation</code>.</li>\n<li> <code>vdw</code> $=\\beta$<code>vdw</code> $+(1-\\beta)$<code>dw</code></li>\n<li> <code>vdb</code> $=\\beta$<code>vdb</code> $+(1-\\beta)$<code>db</code></li>\n</ul>\n\nSetting $\\beta = 0.9$ works as a pretty robust value. Using Gradient Descent with moment leads to faster convergence.\n\n### Update function\n\n\n<code>update</code> function calls the backpropagation function to compute the gradients $dw$ and $db$, and updates the weights and biases of the neural network by taking exponentially weighted average.\n\n\n### Minibatch Gradient Descent \n\nMinibatch Gradient Descent function is implemented as SGD in the code which takes in as arguments training data, batch_size, no_of_epoch and eta as parameters and perform the procedure outlined in the process outline. \n\nProcess outline:\n\nFor no_of_epoch times, do the following :  \n<ul>\n<li>Randomly shuffle the training data. </li>\n<li> Seperate the training_data into <code>x_train_shuffled</code> and <code>y_train_shuffled</code>.</li>\n<li>Divide the shuffled training data (<code>x_train_shuffled</code> and <code>y_train_shuffled</code>) into batches of specified <code>batch_size</code> and store the batches in the lists <code>batches_x</code> and <code>batches_y</code>.</li>\n\n<li>For each (<code>batch_x</code>,<code>batch_y</code>) in <code>zip(batches_x,batches_y)</code>, use the tuple to update the parameters (i.e call the update function which in turn performs the backpropagation and computes gradient descent with moment).</li>\n\n<li>Completion of the whole dataset marks the end of one epoch.</li>\n</ul>\n\n<code>batch_size, no_of_epoch</code> and <code>eta</code> are the hyperparameters of the algorithm."},{"metadata":{"trusted":true,"_uuid":"2a29782224cad6bb8f2a545ceab0367a67f6383c"},"cell_type":"code","source":"def transform_output(y):\n    l = y.shape[1]\n    ty = np.zeros((10,l))\n    for i in range(l):\n        s = y[0,i].astype(int)\n        # print(type(s))\n        ty[s,i] = 1\n    return ty","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4d77a547d9462195a8400a74010ddd60c165aa79"},"cell_type":"code","source":"def function(z):\n    return np.maximum(0.01*z,z)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"653ecf20e2fb76bac319ec12422c9943e3a0076b"},"cell_type":"code","source":"def function_prime(z):\n    a = np.greater(z,0.01*z)\n    a = a.astype(int)\n    a[a==0] = 0.01\n    return a","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"836bad8b052b3c25edfc3880954ee050edc14dfe"},"cell_type":"code","source":"def cost_function(y,a,m):\n    b = y-a\n    s = (1/(2*m))*(np.dot(b.T,b))\n    l = s.shape[1]\n    dsum = 0\n    for i in range(l):\n        dsum = dsum + s[i,i]\n    return dsum","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cf31634d55af5eb9c9d7c6284764177fc4820945"},"cell_type":"code","source":"def sigmoid(z):\n    return 1/(1 + np.exp(-z))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e837966893695fdbc71d01a4015037df0fb4cea9"},"cell_type":"code","source":"def sigmoid_prime(z):\n    return sigmoid(z)*(1-sigmoid(z))","execution_count":null,"outputs":[]},{"metadata":{"scrolled":true,"trusted":true,"_uuid":"402a09f755b832140e133964bf310eac138638cc"},"cell_type":"code","source":"def grad_a_cost_function(y,a,m):\n    return -(1/m)*(y-a)\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"921ac5aed9ba4fb14085a18efc513497b91f80fe"},"cell_type":"markdown","source":"# Defining the Neural Network"},{"metadata":{"trusted":true,"_uuid":"4fc819733891054f26a97aa864ae1e9a96765e2e"},"cell_type":"code","source":"class Network:\n    # atype is the activation type; whether it is a RELU or sigmoid\n    def __init__(self,sizes,atype):\n        self.num_layers = len(sizes)\n        self.weights = []\n        if atype==\"sigmoid\":\n            self.biases = [np.random.randn(y,1) for y in sizes[1:]]\n            #self.biases = [np.zeros((y,1)) for y in sizes[1:]]\n            #self.weights = [np.zeros((sizes[1],sizes[0]))]\n            #self.weights = [np.zeros((sizes[1],sizes[0]))\n            for x in range(1,len(sizes)):\n                (self.weights).append(np.random.randn(sizes[x],sizes[x-1]))\n        else:\n            self.biases = [np.zeros((y,1)) for y in sizes[1:]]\n            #self.weights = [np.zeros((sizes[1],sizes[0]))]\n            for x in range(1,len(sizes)):\n                (self.weights).append(np.random.randn(sizes[x],sizes[x-1])*np.sqrt(2/sizes[x-1]))\n                \n            \n    def feedforward(self, batch_x):\n        length = len(self.weights)\n        a_cache=[]\n        a = batch_x\n        a_cache.append(a)\n        z_cache=[] \n        for i in range(length-1):\n            z = np.dot(self.weights[i],a) + self.biases[i]\n            z_cache.append(z)\n            a = function(z)\n            a_cache.append(a)\n        i=i+1\n        z = np.dot(self.weights[i],a) + self.biases[i]\n        z_cache.append(z)\n        a = sigmoid(z)\n        a_cache.append(a)\n        return a_cache,z_cache\n    \n    def feedforward_output(self, x_test):\n        length = len(self.weights)\n        a = x_test\n        for i in range(length-1):\n            z = np.dot(self.weights[i],a) + self.biases[i]\n            a = function(z)\n            #print(\"z[\",i,\"] = \",z)\n        i = i + 1\n        z = np.dot(self.weights[i],a) + self.biases[i]\n        #print(\"z[\",i,\"] = \",z)\n        a = sigmoid(z)\n        return a\n    \n    def compute_dZ(self,batch_x,batch_y,l,Z_cache,dZ):\n        m = batch_x.shape[1]\n        n = batch_x.shape[0]\n        #y = batch[n-1,:]\n        #y = y.reshape(1,len(y))\n        # print(type(y))\n        #print(y.shape)\n        #y = transform_output(y)\n        if l== self.num_layers - 2:\n            #a = function(Z_cache[l])\n            a = sigmoid(Z_cache[l])\n            #return grad_a_cost_function(batch_y,a,m)*function_prime(Z_cache[l]) \n            return grad_a_cost_function(batch_y,a,m)*sigmoid_prime(Z_cache[l])\n        else:\n            return np.dot(self.weights[l+1].T,dZ)*function_prime(Z_cache[l])\n    \n    def backpropagation(self,batch_x,batch_y):\n        dw = []\n        db = []\n        m = batch_x.shape[1]\n        A_cache,Z_cache = self.feedforward(batch_x)\n        L = self.num_layers\n        dZ = []\n        for l in range(L-2,-1,-1):\n            dZ = self.compute_dZ(batch_x,batch_y,l,Z_cache,dZ)\n            db.append((1/m)*np.sum(dZ,axis = 1,keepdims = True))\n            dw.append((1/m)*np.dot(dZ,A_cache[l].T))\n        db.reverse()\n        dw.reverse()\n        return dw,db \n        \n    def update(self,batch_x,batch_y,eta,vdw,vdb):\n        beta = 0.9\n        dw,db = self.backpropagation(batch_x,batch_y)\n        \n        vdw = [beta*x +(1-beta)*y for (x,y) in zip(vdw,dw)]\n        vdb = [beta*x +(1-beta)*y for (x,y) in zip(vdb,db)]\n        for i in range(self.num_layers-1):\n            #check(dw[i])\n            self.weights[i] = self.weights[i] - eta*vdw[i]\n            self.biases[i] = self.biases[i] - eta*vdb[i]\n        \n        return vdw,vdb\n\n            \n    # we assume that in the training data, rows represent the features of the training set and columns denote the \n    # instances of the training set.\n    \n    def SGD(self,x_train,y_train,batch_size,no_of_epoch,eta,x_test=None,y_test=None):\n        training_data = x_train\n        print(training_data.shape)\n        print(y_train.shape)\n        training_data = np.append(training_data,y_train,axis = 0)\n        print(training_data.shape)\n        # In the previous two lines, we have put x_train and y_train into one matrix: training data;\n        #training_data = [[x_train],\n        #                 [ytrain]]\n        n = training_data.shape[0]\n        training_size = training_data.shape[1]\n        vdw = [np.zeros(y.shape) for y in self.weights]\n        vdb = [np.zeros(y.shape) for y in self.biases]\n        for i in range(no_of_epoch):\n            np.random.shuffle(training_data.T)\n            x_train_shuffled = training_data[:-1,:]\n            y_train_shuffled = training_data[n-1,:]\n            y_train_shuffled = y_train_shuffled.reshape(1,len(y_train_shuffled ))\n            # print(type(y_train_shuffled))\n            y_train_shuffled_transformed = transform_output(y_train_shuffled)\n            batches_x = [x_train_shuffled[:,k:k + batch_size] for k in range(0,training_size,batch_size)]\n            batches_y = [y_train_shuffled_transformed[:,k:k + batch_size] for k in range(0,training_size,batch_size)]\n            for (batch_x,batch_y) in zip(batches_x,batches_y):\n                vdw,vdb = self.update(batch_x,batch_y,eta,vdw,vdb)\n            a = self.feedforward_output(x_train[:,1:10])\n            m = a.shape[1]\n            y = transform_output(y_train[:,1:10])\n            cost = cost_function(y,a,m)\n            print(\"The cost after epoch no.\",i,\" is \",cost)\n            #a = np.argmax(a,axis = 0)\n            #s = score(y_train,a)\n            #print(s)\n        \n        ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a5a9d8bf7f9640fd1591186fb004eb0075f46427"},"cell_type":"markdown","source":"# Initialization of hyperparameters"},{"metadata":{"trusted":true,"_uuid":"67287e7f052e3c28c840237eeec0ce401b17458d"},"cell_type":"code","source":"n = Network([784,30,30,10],\"RELU\")\nn.SGD(x_train,y_train,10,50,0.5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7e5b7631339863586d24d356372ee80ed450181f"},"cell_type":"code","source":"img = x_test[:,7]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"da9d8d6383c76158f17a76c376dea51fee82ef62"},"cell_type":"code","source":"img = img.reshape(len(img),1)\nA_test= n.feedforward_output(img)\nA_test = np.argmax(A_test,axis=0)\nprint(img.shape)\nimg = img.reshape(28,28)\nplt.imshow(img,cmap = 'gray')\nplt.show()\nprint(\"The predicted output is\", A_test)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"01a8d815206145e4c120b70a47063bc8080bd20f"},"cell_type":"markdown","source":"# Score"},{"metadata":{"trusted":true,"_uuid":"0aabb3c9993e6a38de90a47ac2b76e9ed33c7ba9"},"cell_type":"code","source":"A_train = n.feedforward_output(x_train)\nA_train = np.argmax(A_train,axis = 0)\n#A.shape\nA_train = A_train.reshape(1,len(A_train))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"75f89f47ff3c733db5a910ffb57902a91cb0288f"},"cell_type":"code","source":"A_test = n.feedforward_output(x_test)\nA_test = np.argmax(A_test,axis = 0)\nA_test.shape\nA_test = A_test.reshape(1,len(A_test))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d016ebd9a52c7efb01bc5662d4968bcef98ce40d"},"cell_type":"code","source":"def score(y,a):\n    l = y.shape[1]\n    return (1 - (np.count_nonzero(y-a)/l))*100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4d514f192efd40178050ae74e1ec912b1bff0d26"},"cell_type":"code","source":"score_train = score(y_train,A_train)\nscore_test = score(y_test,A_test)\nprint(\"Accuracy on train data is \",score_train, \"% and on test data is\",score_test,\"%\")","execution_count":null,"outputs":[]},{"metadata":{"collapsed":true,"_uuid":"5413cd82e5eb05bd68b26b237e87917eae14682f"},"cell_type":"markdown","source":"# References\n<ul>\n <li>neuralnetworksanddeeplearning.com </li>\n  <li>deeplearning.ai Coursera Specialization</li>  \n</ul>"},{"metadata":{"trusted":true,"_uuid":"91f514b1f8efbd675055bca10c3753a019a462ce"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"anaconda-cloud":{},"coursera":{"course_slug":"maths4ml-calculus","graded_item_id":"oBlKd","launcher_item_id":"37rcX"},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}