{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "accelerator": "GPU", "colab": { "name": "classification_using_NN_MNIST.ipynb", "provenance": [], "collapsed_sections": [] }, "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.5.4" } }, "cells": [ { "cell_type": "markdown", "metadata": { "id": "ahVJXlZUC9xL", "colab_type": "text" }, "source": [ "#
CS568:Deep Learning
Spring 2020
" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "fCuh-o9YS4Bz" }, "source": [ "Mount your Google drive by using this code snippet" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "C5LfwwRbTrq7", "colab": { "base_uri": "https://localhost:8080/", "height": 122 }, "outputId": "1f11e592-48e8-4b73-a329-d6363bb932d1" }, "source": [ "from google.colab import drive\n", "drive.mount('/content/drive')" ], "execution_count": 1, "outputs": [ { "output_type": "stream", "text": [ "Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=947318989803-6bn6qk8qdgf4n4g3pfee6491hc0brc4i.apps.googleusercontent.com&redirect_uri=urn%3aietf%3awg%3aoauth%3a2.0%3aoob&response_type=code&scope=email%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdocs.test%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive%20https%3a%2f%2fwww.googleapis.com%2fauth%2fdrive.photos.readonly%20https%3a%2f%2fwww.googleapis.com%2fauth%2fpeopleapi.readonly\n", "\n", "Enter your authorization code:\n", "··········\n", "Mounted at /content/drive\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "n_EsQs3aThrW" }, "source": [ "check current directory contents" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "lZlK7kFXGqp5", "outputId": "1ec9f87a-1643-4224-fd7f-26950eb9f09a", "colab": { "base_uri": "https://localhost:8080/", "height": 119 } }, "source": [ "!ls '/content/drive/My Drive/CS568-DeepLearning-(Spring2020)/'" ], "execution_count": 3, "outputs": [ { "output_type": "stream", "text": [ "classification_using_NN_cats-vs-dogs.ipynb\n", "classification_using_NN_MNIST.ipynb\n", "dataset\n", "keras_basics_notebook.ipynb\n", "regression_using_NN_boston-housing.ipynb\n", "working_with_google_colab.ipynb\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "HwrnPVMOWQ1z" }, "source": [ "**Neural Network in Keras**\n", "In this excercise, we will learn to: \n", "1. import MNIST dataset and visualize some example images\n", "2. define the neural network model with a single hidden layer\n", "3. train the model and plot the accuracy and loss at each epoch\n", "4. test the model\n", "6. save the model after every 10 epochs" ] }, { "cell_type": "markdown", "metadata": { "id": "IM2zY_RVC9zO", "colab_type": "text" }, "source": [ "## 1. Import MNIST dataset" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "V9LLpoTmW3UT", "outputId": "eab3eb64-21b8-4ff1-9d42-a688524a1be1", "colab": { "base_uri": "https://localhost:8080/", "height": 233 } }, "source": [ "from keras.datasets import mnist\n", "import numpy as np\n", "(train_X, train_Y), (test_X, test_Y) = mnist.load_data()\n", "_, img_rows, img_cols = train_X.shape\n", "num_classes = len(np.unique(train_Y))\n", "num_input_nodes = img_rows*img_cols\n", "print(\"Number of training images: %d\"%train_X.shape[0])\n", "print(\"Number of test images: %d\"%train_X.shape[0])\n", "print(\"Image rows: %d\"%train_X.shape[1])\n", "print(\"Image columns: %d\"%train_X.shape[2])\n", "print(\"Number of classes: %d\"%num_classes)\n", "print(\"Training data shape: \", train_X.shape, train_Y.shape)\n", "print(\"Testing data shape: \", test_X.shape, test_Y.shape)" ], "execution_count": 2, "outputs": [ { "output_type": "stream", "text": [ "Using TensorFlow backend.\n" ], "name": "stderr" }, { "output_type": "display_data", "data": { "text/html": [ "

\n", "The default version of TensorFlow in Colab will soon switch to TensorFlow 2.x.
\n", "We recommend you upgrade now \n", "or ensure your notebook will continue to use TensorFlow 1.x via the %tensorflow_version 1.x magic:\n", "more info.

\n" ], "text/plain": [ "" ] }, "metadata": { "tags": [] } }, { "output_type": "stream", "text": [ "Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz\n", "11493376/11490434 [==============================] - 0s 0us/step\n", "Number of training images: 60000\n", "Number of test images: 60000\n", "Image rows: 28\n", "Image columns: 28\n", "Number of classes: 10\n", "Training data shape: (60000, 28, 28) (60000,)\n", "Testing data shape: (10000, 28, 28) (10000,)\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "27BL8GVmXsGF" }, "source": [ "### Visualize some examples from dataset" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "BPIHiZMSXpfi", "outputId": "2e263c3e-e40a-452c-b13a-3b8133b0cdf1", "colab": { "base_uri": "https://localhost:8080/", "height": 213 } }, "source": [ "import matplotlib.pyplot as plt\n", "\n", "fig = plt.figure(figsize=(8,3)) # size of figure in inches (1 inch = 96 pixels)\n", "for i in range(num_classes):\n", " ax = fig.add_subplot(2, 5, 1 + i, xticks=[], yticks=[]) # add_subplot(rows,cols,position,labels on x and y axis)\n", " X_idx = train_X[train_Y[:]==i,:] \n", " ax.set_title(\"Num: \" + str(i)) # plot first image of certain class (label)\n", " plt.imshow(X_idx[1], cmap=\"gray\") #color map gray \n", "plt.show()" ], "execution_count": 4, "outputs": [ { "output_type": "display_data", "data": { "image/png": "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\nuYyd7rAAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "cLk_HsX2X-BM" }, "source": [ "### Pre-processing the dataset" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "sqFxLtL5YEY7", "outputId": "41887a3d-3882-441b-ab18-ea0d48f5ce00", "colab": { "base_uri": "https://localhost:8080/", "height": 85 } }, "source": [ "import keras\n", "# reshape images to column vectors\n", "train_X = train_X.reshape(train_X.shape[0], img_rows*img_cols)\n", "test_X = test_X.reshape(test_X.shape[0], img_rows*img_cols)\n", "# convert class labels to binary class labels\n", "train_Y = keras.utils.np_utils.to_categorical(train_Y, num_classes)\n", "test_Y = keras.utils.np_utils.to_categorical(test_Y, num_classes)\n", "print(\"train_X:\",train_X.shape)\n", "print(\"test_X:\",test_X.shape)\n", "print(\"train_Y:\",train_Y.shape)\n", "print(\"test_Y:\",test_Y.shape)" ], "execution_count": 5, "outputs": [ { "output_type": "stream", "text": [ "train_X: (60000, 784)\n", "test_X: (10000, 784)\n", "train_Y: (60000, 10)\n", "test_Y: (10000, 10)\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "id": "IPHnDNuMC90a", "colab_type": "text" }, "source": [ "# 2. Define model" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "WgWpdiyWYhKg", "outputId": "ab5e7b84-1fb4-4651-bf1c-cbc05c65d982", "colab": { "base_uri": "https://localhost:8080/", "height": 357 } }, "source": [ "from keras.models import Sequential\n", "from keras.layers.core import Dense\n", "from keras.optimizers import SGD\n", "\n", "def nn():\n", " # initialize model\n", " model = Sequential()\n", " # add an input layer and a hidden layer with sigmoid activation \n", " model.add(Dense(100, input_dim = num_input_nodes, activation='sigmoid'))\n", " # add output layer with activation\n", " model.add(Dense(num_classes, activation='softmax'))\n", " return model\n", "\n", "# define model\n", "model = nn()\n", "# define optimizer\n", "sgd = SGD(lr=0.01) # check with different lr values\n", "model.compile(optimizer=sgd, loss='mse', metrics=['accuracy'])\n", "# print model information\n", "model.summary()" ], "execution_count": 6, "outputs": [ { "output_type": "stream", "text": [ "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:66: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:541: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:4432: The name tf.random_uniform is deprecated. Please use tf.random.uniform instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/optimizers.py:793: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.\n", "\n", "Model: \"sequential_1\"\n", "_________________________________________________________________\n", "Layer (type) Output Shape Param # \n", "=================================================================\n", "dense_1 (Dense) (None, 100) 78500 \n", "_________________________________________________________________\n", "dense_2 (Dense) (None, 10) 1010 \n", "=================================================================\n", "Total params: 79,510\n", "Trainable params: 79,510\n", "Non-trainable params: 0\n", "_________________________________________________________________\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "Fijtj_ElY3Wu" }, "source": [ "## 3. Train the model" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "9IxjWs1RY5vG", "outputId": "61044f6d-9109-486c-bfd2-ed50c24ecd9a", "colab": { "base_uri": "https://localhost:8080/", "height": 663 } }, "source": [ "import time\n", "start = time.time()\n", "model_info = model.fit(train_X, train_Y, batch_size=16, epochs=10, verbose=2, validation_split=0.2)\n", "end = time.time()\n", "print(\"Model took %0.2f seconds to train\"%(end - start))" ], "execution_count": 7, "outputs": [ { "output_type": "stream", "text": [ "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:1033: The name tf.assign_add is deprecated. Please use tf.compat.v1.assign_add instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:1020: The name tf.assign is deprecated. Please use tf.compat.v1.assign instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:3005: The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.\n", "\n", "Train on 48000 samples, validate on 12000 samples\n", "Epoch 1/10\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:190: The name tf.get_default_session is deprecated. Please use tf.compat.v1.get_default_session instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:197: The name tf.ConfigProto is deprecated. Please use tf.compat.v1.ConfigProto instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:207: The name tf.global_variables is deprecated. Please use tf.compat.v1.global_variables instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:216: The name tf.is_variable_initialized is deprecated. Please use tf.compat.v1.is_variable_initialized instead.\n", "\n", "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/keras/backend/tensorflow_backend.py:223: The name tf.variables_initializer is deprecated. Please use tf.compat.v1.variables_initializer instead.\n", "\n", " - 16s - loss: 0.0697 - acc: 0.4713 - val_loss: 0.0513 - val_acc: 0.7047\n", "Epoch 2/10\n", " - 7s - loss: 0.0431 - acc: 0.7570 - val_loss: 0.0344 - val_acc: 0.8215\n", "Epoch 3/10\n", " - 7s - loss: 0.0322 - acc: 0.8222 - val_loss: 0.0272 - val_acc: 0.8542\n", "Epoch 4/10\n", " - 7s - loss: 0.0267 - acc: 0.8518 - val_loss: 0.0233 - val_acc: 0.8722\n", "Epoch 5/10\n", " - 7s - loss: 0.0235 - acc: 0.8694 - val_loss: 0.0209 - val_acc: 0.8825\n", "Epoch 6/10\n", " - 7s - loss: 0.0214 - acc: 0.8789 - val_loss: 0.0194 - val_acc: 0.8898\n", "Epoch 7/10\n", " - 7s - loss: 0.0197 - acc: 0.8880 - val_loss: 0.0181 - val_acc: 0.8938\n", "Epoch 8/10\n", " - 7s - loss: 0.0184 - acc: 0.8936 - val_loss: 0.0171 - val_acc: 0.8997\n", "Epoch 9/10\n", " - 7s - loss: 0.0173 - acc: 0.9000 - val_loss: 0.0165 - val_acc: 0.9022\n", "Epoch 10/10\n", " - 7s - loss: 0.0166 - acc: 0.9036 - val_loss: 0.0158 - val_acc: 0.9064\n", "Model took 76.11 seconds to train\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "rZBraDW4ZB1e" }, "source": [ "**Visualize accuracy and loss plots over training epochs**" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "hgut7YBAbr3O", "outputId": "6d824777-4de2-4ff2-ff5b-dc1e4c0ab268", "colab": { "base_uri": "https://localhost:8080/", "height": 350 } }, "source": [ "def plot_model_history(model_history):\n", " fig, axs = plt.subplots(1,2,figsize=(15,5))\n", " # model history for accuracy\n", " axs[0].plot(range(1,len(model_history.history['acc'])+1),model_history.history['acc'])\n", " axs[0].plot(range(1,len(model_history.history['val_acc'])+1),model_history.history['val_acc'])\n", " axs[0].set_title('Model Accuracy')\n", " axs[0].set_ylabel('Accuracy')\n", " axs[0].set_xlabel('Epoch')\n", " axs[0].set_xticks(np.arange(1,len(model_history.history['acc'])+1),len(model_history.history['acc'])/10)\n", " axs[0].legend(['training acc', 'val acc'], loc='best')\n", " axs[0].grid(True)\n", " # model history for loss\n", " axs[1].plot(range(1,len(model_history.history['loss'])+1),model_history.history['loss'])\n", " axs[1].plot(range(1,len(model_history.history['val_loss'])+1),model_history.history['val_loss'])\n", " axs[1].set_title('Model Loss')\n", " axs[1].set_ylabel('Loss')\n", " axs[1].set_xlabel('Epoch')\n", " axs[1].set_xticks(np.arange(1,len(model_history.history['loss'])+1),len(model_history.history['loss'])/10)\n", " axs[1].legend(['training loss', 'val loss'], loc='best')\n", " axs[1].grid(True)\n", "plot_model_history(model_info)" ], "execution_count": 9, "outputs": [ { "output_type": "display_data", "data": { "image/png": "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\n3nsvH3zwAX5+fsyfP5877rijxc+viLRS1kJVKVQUOq/KoiPLXQ9sACb7OsI2zxgzGiiz1m46yT63\nArcCJCQkkJaWdlp1WWvZkF1LkJ8hNd7/tMrwppKSktM+to5K56z5dM6OFx0dTXFx8Qm319bWnnT7\nmbr77rvZuXMnZ599Nueffz7Tp0/nkUceoVOnTnzzzTd8+eWXzJkzh/3791NRUcEPfvADbrrpJgCG\nDBnCsmXLKCkpYdasWYwdO5YvvviCrl278tprrxEaGsptt93GjBkzuOKKKxgyZAhz5szhgw8+oLq6\nmkWLFjFgwABycnK45ZZbOHjwIKNGjeLTTz9l+fLlxMUd+32ctZaSkhKCg4N54oknWLx4MQA33ngj\nP/zhDyktLWXu3Lns378fl8vFPffcw6xZs3jooYd47733CAgI4IILLuDXv/71MeVWVFQ06+/Sqwme\nMWYG8GfAH1horX20wfZewAtAZyAPuMFau8+bMXnDo48+yqZNm9iwwRkekZaWxvr169m0adORGW9e\neOEFYmNjKS8vZ+TIkcyaNeu4P4rt27ezcOFCXnzxRa699lreeustbrjhhuPqi4+PZ/369Tz11FM8\n/vjjLFy4kIcffpgLLriA+++/nw8++IDnn3++0Vh//etfExsbS21tLVOmTOGrr75i0KBBzJ49m3/8\n4x+MHDmSoqIiQkNDWbBgAZmZmWzYsIGAgADy8vI8fOZExKdcLicpq5eYOa+G7wuhsvD4dRVFYGsb\nLXoABlyPgF+H7iiyH+hR732Se11j++wzxgQA0UBuve3XcYrWO2vtAmABwIgRI+zkyZNPO+Df/HEZ\nceHB/PDqMaddhrekpaVxJsfWEemcNZ/O2fG2bNly0hkfvT2L5u9//3u2bdvGV199BTi/o40bNx5z\nn71o0aJj7rOvv/76IxPDREREALBz507+8Y9/MHToUK699lqWLl3KDTfcQGBgIKGhoURGRmKMoXv3\n7mzYsIGnnnqKp59+moULF3L//fczderUI/fZixYtIiIi4rjjrqvvm2++4dVXXyU9PR1rLaNHj2b6\n9Ons2rWLnj178uabbxIZGUlhYSFVVVX897//ZevWrRhjKCgoOK7ckJAQhg0b1uRz5rUEr97g8qk4\n3VLSjTHvWms319vtcWCRtfYlY8wFwG9wBpOftof/ncHmA0VnUsRxUrpF8dClqc36zKhRo46ZzvQv\n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\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] } } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "4ymLrIHOcDMY" }, "source": [ "## 5. Test the model" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "KeHHiF20cFtR", "outputId": "69278545-1ad5-4aca-f3f2-74d6edb9a436", "colab": { "base_uri": "https://localhost:8080/", "height": 34 } }, "source": [ "def accuracy(test_X, test_Y, model):\n", " result = model.predict(test_X) # will give you (N,10) matrix, in each row we have probabilities of a neuron\n", " predicted_class = np.argmax(result, axis=1) # returns the indices of the maximum index along 1 axis\n", " true_class = np.argmax(test_Y, axis=1) # returns the indices of the maximum index along 1 axis\n", " num_correct = np.sum(predicted_class == true_class) \n", " accuracy = float(num_correct)/result.shape[0]\n", " return (accuracy * 100)\n", "\n", "print(\"Accuracy on test data is: %0.2f\"%accuracy(test_X, test_Y, model))" ], "execution_count": 10, "outputs": [ { "output_type": "stream", "text": [ "Accuracy on test data is: 90.41\n" ], "name": "stdout" } ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "qXaUxYufAXM_" }, "source": [ "## 5. Save the model after every 10 epochs" ] }, { "cell_type": "code", "metadata": { "colab_type": "code", "id": "MPyCVwJrAyCQ", "colab": {} }, "source": [ "from keras.callbacks import ModelCheckpoint\n", "import os\n", "\n", "# define a deep neural network\n", "model = nn()\n", "# define optimizer\n", "sgd = SGD(lr=0.1)\n", "model.compile(optimizer=sgd, loss='mse', metrics=['accuracy'])\n", "# checkpoint\n", "outputFolder = 'weights/'\n", "if not os.path.exists(outputFolder):\n", " os.makedirs(outputFolder)\n", "\n", "filepath=outputFolder+\"/weights-{epoch:02d}-{val_acc:.2f}.hdf5\"\n", "checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, \\\n", " save_best_only=False, save_weights_only=True, \\\n", " mode='auto', period=10)\n", "callbacks_list = [checkpoint]\n", "\n", "# train the model\n", "model_info = model.fit(train_X, train_Y, batch_size=128, \\\n", " epochs=80, callbacks=callbacks_list, verbose=0, \\\n", " validation_split=0.2)\n", "# compute test accuracy\n", "print(\"Accuracy on test data is: %0.2f\"%accuracy(test_X, test_Y, model))" ], "execution_count": 0, "outputs": [] } ] }