{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### <p style=\"text-align: right;\"> &#9989; Put your name here.</p>\n",
    "\n",
    "#### <p style=\"text-align: right;\"> &#9989; Put your group member names here.</p>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Day 22 In-Class Assignment: Artificial Neural Network\n",
    "\n",
    "</p>\n",
    "\n",
    "<img src= \"https://ml4a.github.io/images/temp_fig_mnist.png\" width=500px>\n",
    "<p style=\"text-align: right;\">From: Machine Learning for Artists - https://ml4a.github.io/</p>\n",
    "\n",
    "\n",
    "\n",
    "1. **Scientific motivation** \n",
    "    - Data Analysis / Pattern Recognition\n",
    "2. **Modeling tools** \n",
    "    - Artificial Neural networks\n",
    "    - Error Calculations\n",
    "3. **Programming concepts** \n",
    "    - More Debugging\n",
    "    - Selecting and using libraries\n",
    "4. **Python Programming Concepts** \n",
    "    - More Understanding classes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Agenda for today's class \n",
    "\n",
    "1. Review pre-class assignment\n",
    "1. Modify code to be more flexible\n",
    "1. Use our ANN on the \"Digits\" dataset\n",
    "1. Finding/Using Neural Networks Libraries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "# 1. Review pre-class assignment\n",
    "\n",
    "Below we summarize the steps involved in designing and training a feed-forward artificial neural network. We will use the [partSix.py](./partSix.py) file provided in the \"Neural Networks Demystified\" module which can be downloaded from github:\n",
    "\n",
    "    git clone https://github.com/stephencwelch/Neural-Networks-Demystified\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %load partSix.py\n",
    "# Neural Networks Demystified\n",
    "# Part 6: Training\n",
    "#\n",
    "# Supporting code for short YouTube series on artificial neural networks.\n",
    "#\n",
    "# Stephen Welch\n",
    "# @stephencwelch\n",
    "\n",
    "\n",
    "## ----------------------- Part 1 ---------------------------- ##\n",
    "import numpy as np\n",
    "\n",
    "# X = (hours sleeping, hours studying), y = Score on test\n",
    "X = np.array(([3,5], [5,1], [10,2]), dtype=float)\n",
    "y = np.array(([75], [82], [93]), dtype=float)\n",
    "\n",
    "# Normalize\n",
    "X = X/np.amax(X, axis=0)\n",
    "y = y/100 #Max test score is 100\n",
    "\n",
    "## ----------------------- Part 5 ---------------------------- ##\n",
    "\n",
    "class Neural_Network(object):\n",
    "    def __init__(self):        \n",
    "        #Define Hyperparameters\n",
    "        self.inputLayerSize = 2\n",
    "        self.outputLayerSize = 1\n",
    "        self.hiddenLayerSize = 3\n",
    "        \n",
    "        #Weights (parameters)\n",
    "        self.W1 = np.random.randn(self.inputLayerSize,self.hiddenLayerSize)\n",
    "        self.W2 = np.random.randn(self.hiddenLayerSize,self.outputLayerSize)\n",
    "        \n",
    "    def forward(self, X):\n",
    "        #Propogate inputs though network\n",
    "        self.z2 = np.dot(X, self.W1)\n",
    "        self.a2 = self.sigmoid(self.z2)\n",
    "        self.z3 = np.dot(self.a2, self.W2)\n",
    "        yHat = self.sigmoid(self.z3) \n",
    "        return yHat\n",
    "        \n",
    "    def sigmoid(self, z):\n",
    "        #Apply sigmoid activation function to scalar, vector, or matrix\n",
    "        return 1/(1+np.exp(-z))\n",
    "    \n",
    "    def sigmoidPrime(self,z):\n",
    "        #Gradient of sigmoid\n",
    "        return np.exp(-z)/((1+np.exp(-z))**2)\n",
    "    \n",
    "    def costFunction(self, X, y):\n",
    "        #Compute cost for given X,y, use weights already stored in class.\n",
    "        self.yHat = self.forward(X)\n",
    "        J = 0.5*sum((y-self.yHat)**2)\n",
    "        return J\n",
    "        \n",
    "    def costFunctionPrime(self, X, y):\n",
    "        #Compute derivative with respect to W and W2 for a given X and y:\n",
    "        self.yHat = self.forward(X)\n",
    "        \n",
    "        delta3 = np.multiply(-(y-self.yHat), self.sigmoidPrime(self.z3))\n",
    "        dJdW2 = np.dot(self.a2.T, delta3)\n",
    "        \n",
    "        delta2 = np.dot(delta3, self.W2.T)*self.sigmoidPrime(self.z2)\n",
    "        dJdW1 = np.dot(X.T, delta2)  \n",
    "        \n",
    "        return dJdW1, dJdW2\n",
    "    \n",
    "    #Helper Functions for interacting with other classes:\n",
    "    def getParams(self):\n",
    "        #Get W1 and W2 unrolled into vector:\n",
    "        params = np.concatenate((self.W1.ravel(), self.W2.ravel()))\n",
    "        return params\n",
    "    \n",
    "    def setParams(self, params):\n",
    "        #Set W1 and W2 using single paramater vector.\n",
    "        W1_start = 0\n",
    "        W1_end = self.hiddenLayerSize * self.inputLayerSize\n",
    "        self.W1 = np.reshape(params[W1_start:W1_end], (self.inputLayerSize , self.hiddenLayerSize))\n",
    "        W2_end = W1_end + self.hiddenLayerSize*self.outputLayerSize\n",
    "        self.W2 = np.reshape(params[W1_end:W2_end], (self.hiddenLayerSize, self.outputLayerSize))\n",
    "        \n",
    "    def computeGradients(self, X, y):\n",
    "        dJdW1, dJdW2 = self.costFunctionPrime(X, y)\n",
    "        return np.concatenate((dJdW1.ravel(), dJdW2.ravel()))\n",
    "\n",
    "def computeNumericalGradient(N, X, y):\n",
    "        paramsInitial = N.getParams()\n",
    "        numgrad = np.zeros(paramsInitial.shape)\n",
    "        perturb = np.zeros(paramsInitial.shape)\n",
    "        e = 1e-4\n",
    "\n",
    "        for p in range(len(paramsInitial)):\n",
    "            #Set perturbation vector\n",
    "            perturb[p] = e\n",
    "            N.setParams(paramsInitial + perturb)\n",
    "            loss2 = N.costFunction(X, y)\n",
    "            \n",
    "            N.setParams(paramsInitial - perturb)\n",
    "            loss1 = N.costFunction(X, y)\n",
    "\n",
    "            #Compute Numerical Gradient\n",
    "            numgrad[p] = (loss2 - loss1) / (2*e)\n",
    "\n",
    "            #Return the value we changed to zero:\n",
    "            perturb[p] = 0\n",
    "            \n",
    "        #Return Params to original value:\n",
    "        N.setParams(paramsInitial)\n",
    "\n",
    "        return numgrad \n",
    "        \n",
    "## ----------------------- Part 6 ---------------------------- ##\n",
    "from scipy import optimize\n",
    "\n",
    "\n",
    "class trainer(object):\n",
    "    def __init__(self, N):\n",
    "        #Make Local reference to network:\n",
    "        self.N = N\n",
    "        \n",
    "    def callbackF(self, params):\n",
    "        self.N.setParams(params)\n",
    "        self.J.append(self.N.costFunction(self.X, self.y))   \n",
    "        \n",
    "    def costFunctionWrapper(self, params, X, y):\n",
    "        self.N.setParams(params)\n",
    "        cost = self.N.costFunction(X, y)\n",
    "        grad = self.N.computeGradients(X,y)\n",
    "        return cost, grad\n",
    "        \n",
    "    def train(self, X, y):\n",
    "        #Make an internal variable for the callback function:\n",
    "        self.X = X\n",
    "        self.y = y\n",
    "\n",
    "        #Make empty list to store costs:\n",
    "        self.J = []\n",
    "        \n",
    "        params0 = self.N.getParams()\n",
    "\n",
    "        options = {'maxiter': 200, 'disp' : True}\n",
    "        _res = optimize.minimize(self.costFunctionWrapper, params0, jac=True, method='BFGS', \\\n",
    "                                 args=(X, y), options=options, callback=self.callbackF)\n",
    "\n",
    "        self.N.setParams(_res.x)\n",
    "        self.optimizationResults = _res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Input Data\", X)\n",
    "print(\"Output Data\", y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Untrained Random Network\n",
    "NN = Neural_Network()\n",
    "y1 = NN.forward(X)\n",
    "print(\"Untrained Output\", y1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Training step\n",
    "T = trainer(NN)\n",
    "T.train(X,y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Trained Network\n",
    "y2 = NN.forward(X)\n",
    "print(\"Trained Output\",y2)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "&#9989; **DO THIS:** Calculate and compare the [mean squared error](https://en.wikipedia.org/wiki/Mean_squared_error) for untrained network (```y1```) and the trained network (```y2```). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Put your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----\n",
    "\n",
    "# 2. Modify code to be more flexible\n",
    "\n",
    "The code for our Neural Network example above assumes an input layer size of 2, hidden layer size of 3 and an output layer size of 1.  \n",
    "\n",
    "\n",
    "&#9989; **DO THIS:** Modify the code in Section 1 above so that the user can specify these as inputs when creating the Neural_Network object.  The default values should stay the same. Rerun the above example to make sure it still works. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "# 3. Use our ANN on the \"Digits\" dataset.\n",
    "\n",
    "Here is the code copied from our previous Machine Learning module which downloads the \"digits\" dataset and separates it into training and testing sets. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9f01025ef4ef4cff96fcdee80f354ea5",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "interactive(children=(IntSlider(value=898, description='i', max=1796), Output()), _dom_classes=('widget-intera…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pylab as plt\n",
    "import numpy as np\n",
    "from sklearn.datasets import fetch_lfw_people, load_digits\n",
    "from sklearn.model_selection import train_test_split\n",
    "# ATTENTION: you might need to change the above line to \"from sklearn.cross_validation import train_test_split\" if you're using an older version of sklearn\n",
    "\n",
    "sk_data = load_digits();\n",
    "\n",
    "#Cool slider to browse all of the images.\n",
    "from ipywidgets import interact\n",
    "def browse_images(images, labels, categories):\n",
    "    n = len(images)\n",
    "    def view_image(i):\n",
    "        plt.imshow(images[i], cmap=plt.cm.gray_r, interpolation='nearest')\n",
    "        plt.title('%s' % categories[labels[i]])\n",
    "        plt.axis('off')\n",
    "        plt.show()\n",
    "    interact(view_image, i=(0,n-1))\n",
    "browse_images(sk_data.images, sk_data.target, sk_data.target_names)\n",
    "\n",
    "\n",
    "feature_vectors = sk_data.data\n",
    "class_labels = sk_data.target\n",
    "categories = sk_data.target_names\n",
    "\n",
    "N, h, w = sk_data.images.shape\n",
    "train_vectors, test_vectors, train_labels, test_labels = train_test_split(feature_vectors, class_labels, test_size=0.25, random_state=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.2 0.6 0.6 ... 0.9 0.1 0.5]\n"
     ]
    }
   ],
   "source": [
    "print(train_labels/10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "&#9989; **DO THIS:** Make changes to and finish the following code to work with the \"digits\" data.  Some of the work has already been done for you.  Please consider the following when making changes:\n",
    "\n",
    "* For this new input to work, you need to transform the training and testing data into a format that can work with the class that was developed.  Use the example from above and the functions such as ```type``` and ```shape``` to figure out how to transform the data into inputs suitable for training the Neural Network. This will be the first step before you can run the example code below.\n",
    "* Modify the number of Input, Output and Hidden layers to match the new problem. (I've supplied \"?\" for now, you should think about what these could/should be.)\n",
    "* Make sure your inputs and outputs are normalized between zero (0) and one (1).  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-15-4a5ffda47e4b>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-15-4a5ffda47e4b>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    NN = Neural_Network(ILS=?,OLS=?,HLS=?)\u001b[0m\n\u001b[1;37m                            ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "#Run the training. \n",
    "NN = Neural_Network(ILS=?,OLS=?,HLS=?)\n",
    "T = trainer(NN)\n",
    "T.train(train_vectors, train_labels,maxiter=500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.19802374]\n",
      " [0.60041839]\n",
      " [0.60011129]\n",
      " ...\n",
      " [0.8903276 ]\n",
      " [0.10924318]\n",
      " [0.51757989]]\n",
      "Training Data error 0.0002386631276722677\n"
     ]
    }
   ],
   "source": [
    "pred_labels = NN.forward(train_vectors)\n",
    "print(pred_labels)\n",
    "print(\"Training Data error\", np.sum((train_labels - pred_labels)*(train_labels-pred_labels))/len(train_vectors))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Testing Data error 0.02303573906406873\n"
     ]
    }
   ],
   "source": [
    "pred_labels = NN.forward(test_vectors)\n",
    "\n",
    "print(\"Testing Data error\", np.sum((test_labels - pred_labels)*(test_labels-pred_labels))/len(test_vectors))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 648x864 with 25 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Pay attention to how the plotting code rescales the data labels,\n",
    "# if you scaled them differently, you may need to change this code.\n",
    "def plot_gallery(images, true_titles, pred_titles, h, w, n_row=5, n_col=5):\n",
    "    \"\"\"Helper function to plot a gallery of portraits\"\"\"\n",
    "    plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))\n",
    "    plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)\n",
    "    for i in range(n_row * n_col):\n",
    "        plt.subplot(n_row, n_col, i + 1)\n",
    "        plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray_r)\n",
    "        plt.title('Pred='+str(pred_titles[i]*16), size=9)\n",
    "        plt.xlabel('Actual='+str(true_titles[i]*16), size=9)\n",
    "        plt.xticks(())\n",
    "        plt.yticks(())\n",
    "\n",
    "plot_gallery(test_vectors, test_labels, pred_labels, h,w)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "&#9989; **DO THIS:** Modify the parameters of the neural network to get the best fit of the data. Consider also changing the training data you're providing to see how this changes your fit. Is it possible to change the number of input layers or output layers? If so, how you might you do it?\n",
    "\n",
    "Record your thoughts below along with your final best fit parameters/data. **Once you've come up with your best training data and neural network parameters, post your data/parameters the Slack channel for your section.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*Put your thoughts/data/parameters here!*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "# 4. Finding/Using Neural Networks Libraries\n",
    "In this section we will repeat both examples from above (Grades and Digits) using a python neural network library.  \n",
    "\n",
    "&#9989; Do This - As a group, find examples of neural network packages in python.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=8 color=\"#009600\">&#9998;</font> Do This - Erase the contents of this cell and replace it with your answer to the above question!  (double-click on this text to edit this cell, and hit shift+enter to save the text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**&#9989; DO THIS** - Pick a package (or packages) you find interesting and get them working in this notebook.  I suggest that each group member try to pick a different package and spend about 10 minutes trying to install and get it working. After about 10 minutes compare notes and pick the one the group will think is the easiest. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question :** What package did you pick?  Please include any installation code needed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Put your installation code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "&#9989; **DO THIS** - Create an example to demonstrate that the Neural Network is working.  Preferably using an example that comes with the provided NN Package. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Put your example code here \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "&#9989; **DO THIS** - Reproduce the results from the \"Grade\" example above using ```X``` and ```y```:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Put your Grade example code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "&#9989; **DO THIS** - Reproduce the results from the \"Digits\" example above:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Put your Digits example code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question:** What settings worked the best for the 'Digits' data? How did you find these settings?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=8 color=\"#009600\">&#9998;</font> Do This - Erase the contents of this cell and replace it with your answer to the above question!  (double-click on this text to edit this cell, and hit shift+enter to save the text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question:** What part did you have the most trouble figuring out to get this assignment working?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=8 color=\"#009600\">&#9998;</font> Do This - Erase the contents of this cell and replace it with your answer to the above question!  (double-click on this text to edit this cell, and hit shift+enter to save the text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "-----\n",
    "### Congratulations, we're done!\n",
    "\n",
    "Now, you just need to submit this assignment by uploading it to the course <a href=\"https://d2l.msu.edu/\">Desire2Learn</a> web page for today's submission folder (Don't forget to add your names in the first cell).\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "&#169; Copyright Michigan State University Board of Trustees"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
