├── Convolutional Neural Networks in TensorFlow ├── README.md ├── 'Exercise_2_Cats_vs_Dogs_using_augmentation_Question-FINAL.ipynb ├── Exercise_1_Cats_vs_Dogs_Question-FINAL.ipynb └── utf-8''Exercise_4_Multi_class_classifier_Question-FINAL.ipynb └── Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning ├── README.md ├── 'Exercise2-Question_mnist_without_conv.ipynb ├── Excercise-3-Question_mnist_with Convnet.ipynb └── Exercise4-Question_complex_images_convnet_imagedatagenerator.ipynb /Convolutional Neural Networks in TensorFlow/README.md: -------------------------------------------------------------------------------- 1 | # Assignment and weekly excersises of Convolutional Neural Networks in TensorFlow 2 | 3 | This course is a part of Tensorflow in practice specialisation.Link to the course is [here](https://www.coursera.org/specializations/tensorflow-in-practice) 4 | Here is my completed course certificate.[check here](https://www.coursera.org/account/accomplishments/records/4U9UTSGGE2AF) 5 | -------------------------------------------------------------------------------- /Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/README.md: -------------------------------------------------------------------------------- 1 | # Assignment and weekly excersises of Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning 2 | This course is a part of Tensorflow in practice specialisation.Link to the course is [here](https://www.coursera.org/specializations/tensorflow-in-practice) 3 | Here is my completed course certificate.[check here](https://www.coursera.org/account/accomplishments/records/7RSNJUWK9WQP) 4 | -------------------------------------------------------------------------------- /Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/'Exercise2-Question_mnist_without_conv.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "tOoyQ70H00_s" 8 | }, 9 | "source": [ 10 | "## Exercise 2\n", 11 | "In the course you learned how to do classificaiton using Fashion MNIST, a data set containing items of clothing. There's another, similar dataset called MNIST which has items of handwriting -- the digits 0 through 9.\n", 12 | "\n", 13 | "Write an MNIST classifier that trains to 99% accuracy or above, and does it without a fixed number of epochs -- i.e. you should stop training once you reach that level of accuracy.\n", 14 | "\n", 15 | "Some notes:\n", 16 | "1. It should succeed in less than 10 epochs, so it is okay to change epochs= to 10, but nothing larger\n", 17 | "2. When it reaches 99% or greater it should print out the string \"Reached 99% accuracy so cancelling training!\"\n", 18 | "3. If you add any additional variables, make sure you use the same names as the ones used in the class\n", 19 | "\n", 20 | "I've started the code for you below -- how would you finish it? " 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 1, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "import tensorflow as tf\n", 30 | "from os import path, getcwd, chdir\n", 31 | "\n", 32 | "# DO NOT CHANGE THE LINE BELOW. If you are developing in a local\n", 33 | "# environment, then grab mnist.npz from the Coursera Jupyter Notebook\n", 34 | "# and place it inside a local folder and edit the path to that location\n", 35 | "path = f\"{getcwd()}/../tmp2/mnist.npz\"" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 7, 41 | "metadata": { 42 | "colab": {}, 43 | "colab_type": "code", 44 | "id": "9rvXQGAA0ssC" 45 | }, 46 | "outputs": [], 47 | "source": [ 48 | "# GRADED FUNCTION: train_mnist\n", 49 | "def train_mnist():\n", 50 | " # Please write your code only where you are indicated.\n", 51 | " # please do not remove # model fitting inline comments.\n", 52 | "\n", 53 | " # YOUR CODE SHOULD START HERE\n", 54 | "\n", 55 | " # YOUR CODE SHOULD END HERE\n", 56 | "\n", 57 | " mnist = tf.keras.datasets.mnist\n", 58 | "\n", 59 | " (x_train, y_train),(x_test, y_test) = mnist.load_data(path=path)\n", 60 | " x_train=x_train/255\n", 61 | " x_test=x_test/255\n", 62 | " model = tf.keras.models.Sequential([\n", 63 | " # YOUR CODE SHOULD START HERE\n", 64 | " tf.keras.layers.Flatten(input_shape=(28,28)),\n", 65 | " tf.keras.layers.Dense(4096,activation='relu'),\n", 66 | " tf.keras.layers.Dense(1024,activation='relu'),\n", 67 | "\n", 68 | " tf.keras.layers.Dense(10,activation='softmax')\n", 69 | " # YOUR CODE SHOULD END HERE\n", 70 | " ])\n", 71 | "\n", 72 | " model.compile(optimizer='adam',\n", 73 | " loss='sparse_categorical_crossentropy',\n", 74 | " metrics=['accuracy'])\n", 75 | " \n", 76 | " # model fitting\n", 77 | " history = model.fit(x_train,y_train,epochs=9,validation_data=(x_test,y_test))\n", 78 | " \n", 79 | " # model fitting\n", 80 | " return history.epoch, history.history['acc'][-1]" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 8, 86 | "metadata": { 87 | "colab": {}, 88 | "colab_type": "code", 89 | "id": "9rvXQGAA0ssC" 90 | }, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [ 96 | "Train on 60000 samples, validate on 10000 samples\n", 97 | "Epoch 1/9\n", 98 | "60000/60000 [==============================] - 18s 301us/sample - loss: 0.1820 - acc: 0.9445 - val_loss: 0.1006 - val_acc: 0.9711\n", 99 | "Epoch 2/9\n", 100 | "60000/60000 [==============================] - 18s 293us/sample - loss: 0.0864 - acc: 0.9737 - val_loss: 0.0976 - val_acc: 0.9720\n", 101 | "Epoch 3/9\n", 102 | "60000/60000 [==============================] - 17s 277us/sample - loss: 0.0586 - acc: 0.9814 - val_loss: 0.0860 - val_acc: 0.9755\n", 103 | "Epoch 4/9\n", 104 | "60000/60000 [==============================] - 17s 277us/sample - loss: 0.0487 - acc: 0.9852 - val_loss: 0.0711 - val_acc: 0.9797\n", 105 | "Epoch 5/9\n", 106 | "60000/60000 [==============================] - 16s 275us/sample - loss: 0.0415 - acc: 0.9876 - val_loss: 0.0952 - val_acc: 0.9793\n", 107 | "Epoch 6/9\n", 108 | "60000/60000 [==============================] - 17s 282us/sample - loss: 0.0333 - acc: 0.9901 - val_loss: 0.1083 - val_acc: 0.9751\n", 109 | "Epoch 7/9\n", 110 | "60000/60000 [==============================] - 17s 287us/sample - loss: 0.0296 - acc: 0.9915 - val_loss: 0.1070 - val_acc: 0.9774\n", 111 | "Epoch 8/9\n", 112 | "60000/60000 [==============================] - 16s 270us/sample - loss: 0.0284 - acc: 0.9918 - val_loss: 0.0948 - val_acc: 0.9818\n", 113 | "Epoch 9/9\n", 114 | "60000/60000 [==============================] - 18s 295us/sample - loss: 0.0273 - acc: 0.9932 - val_loss: 0.1130 - val_acc: 0.9768\n" 115 | ] 116 | }, 117 | { 118 | "data": { 119 | "text/plain": [ 120 | "([0, 1, 2, 3, 4, 5, 6, 7, 8], 0.9932333)" 121 | ] 122 | }, 123 | "execution_count": 8, 124 | "metadata": {}, 125 | "output_type": "execute_result" 126 | } 127 | ], 128 | "source": [ 129 | "train_mnist()" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 4, 135 | "metadata": {}, 136 | "outputs": [], 137 | "source": [ 138 | "# Now click the 'Submit Assignment' button above.\n", 139 | "# Once that is complete, please run the following two cells to save your work and close the notebook" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 6, 145 | "metadata": {}, 146 | "outputs": [ 147 | { 148 | "data": { 149 | "application/javascript": [ 150 | "\n", 151 | "IPython.notebook.save_checkpoint();\n" 152 | ], 153 | "text/plain": [ 154 | "" 155 | ] 156 | }, 157 | "metadata": {}, 158 | "output_type": "display_data" 159 | } 160 | ], 161 | "source": [ 162 | "%%javascript\n", 163 | "\n", 164 | "IPython.notebook.save_checkpoint();" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": null, 170 | "metadata": {}, 171 | "outputs": [], 172 | "source": [ 173 | "%%javascript\n", 174 | "IPython.notebook.session.delete();\n", 175 | "window.onbeforeunload = null\n", 176 | "setTimeout(function() { window.close(); }, 1000);" 177 | ] 178 | } 179 | ], 180 | "metadata": { 181 | "coursera": { 182 | "course_slug": "introduction-tensorflow", 183 | "graded_item_id": "d6dew", 184 | "launcher_item_id": "FExZ4" 185 | }, 186 | "kernelspec": { 187 | "display_name": "Python 3", 188 | "language": "python", 189 | "name": "python3" 190 | }, 191 | "language_info": { 192 | "codemirror_mode": { 193 | "name": "ipython", 194 | "version": 3 195 | }, 196 | "file_extension": ".py", 197 | "mimetype": "text/x-python", 198 | "name": "python", 199 | "nbconvert_exporter": "python", 200 | "pygments_lexer": "ipython3", 201 | "version": "3.6.8" 202 | } 203 | }, 204 | "nbformat": 4, 205 | "nbformat_minor": 1 206 | } 207 | -------------------------------------------------------------------------------- /Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Excercise-3-Question_mnist_with Convnet.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "iQjHqsmTAVLU" 8 | }, 9 | "source": [ 10 | "## Exercise 3\n", 11 | "In the videos you looked at how you would improve Fashion MNIST using Convolutions. For your exercise see if you can improve MNIST to 99.8% accuracy or more using only a single convolutional layer and a single MaxPooling 2D. You should stop training once the accuracy goes above this amount. It should happen in less than 20 epochs, so it's ok to hard code the number of epochs for training, but your training must end once it hits the above metric. If it doesn't, then you'll need to redesign your layers.\n", 12 | "\n", 13 | "I've started the code for you -- you need to finish it!\n", 14 | "\n", 15 | "When 99.8% accuracy has been hit, you should print out the string \"Reached 99.8% accuracy so cancelling training!\"\n" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 1, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "import tensorflow as tf\n", 25 | "from os import path, getcwd, chdir\n", 26 | "\n", 27 | "# DO NOT CHANGE THE LINE BELOW. If you are developing in a local\n", 28 | "# environment, then grab mnist.npz from the Coursera Jupyter Notebook\n", 29 | "# and place it inside a local folder and edit the path to that location\n", 30 | "path = f\"{getcwd()}/../tmp2/mnist.npz\"" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "config = tf.ConfigProto()\n", 40 | "config.gpu_options.allow_growth = True\n", 41 | "sess = tf.Session(config=config)" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 8, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "import numpy as np" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 11, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "# GRADED FUNCTION: train_mnist_conv\n", 60 | "def train_mnist_conv():\n", 61 | " # Please write your code only where you are indicated.\n", 62 | " # please do not remove model fitting inline comments.\n", 63 | "\n", 64 | " # YOUR CODE STARTS HERE\n", 65 | " \n", 66 | " # YOUR CODE ENDS HERE\n", 67 | "\n", 68 | " mnist = tf.keras.datasets.mnist\n", 69 | " (training_images, training_labels), (test_images, test_labels) = mnist.load_data(path=path)\n", 70 | " # YOUR CODE STARTS HERE\n", 71 | " training_images=training_images/255\n", 72 | " test_images=test_images/255\n", 73 | " training_images=np.expand_dims(training_images,axis=3)\n", 74 | " test_images=np.expand_dims(test_images,axis=3)\n", 75 | " # YOUR CODE ENDS HERE\n", 76 | "\n", 77 | " model = tf.keras.models.Sequential([\n", 78 | " # YOUR CODE STARTS HERE\n", 79 | " tf.keras.layers.Conv2D(64,kernel_size=(5,5),activation='relu',input_shape=(28,28,1)),\n", 80 | " tf.keras.layers.MaxPooling2D(pool_size=(3,3)),\n", 81 | " tf.keras.layers.Flatten(),\n", 82 | " tf.keras.layers.Dense(512,activation='relu'),\n", 83 | " tf.keras.layers.Dense(10,activation='softmax')\n", 84 | "\n", 85 | " # YOUR CODE ENDS HERE\n", 86 | " ])\n", 87 | "\n", 88 | " model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n", 89 | " # model fitting\n", 90 | " history = model.fit(training_images,training_labels,epochs=19,validation_data=(test_images,test_labels))\n", 91 | " # model fitting\n", 92 | " return history.epoch, history.history['acc'][-1]\n", 93 | "\n" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 12, 99 | "metadata": {}, 100 | "outputs": [ 101 | { 102 | "name": "stdout", 103 | "output_type": "stream", 104 | "text": [ 105 | "Train on 60000 samples, validate on 10000 samples\n", 106 | "Epoch 1/19\n", 107 | "60000/60000 [==============================] - 22s 374us/sample - loss: 0.1086 - acc: 0.9665 - val_loss: 0.0406 - val_acc: 0.9856\n", 108 | "Epoch 2/19\n", 109 | "60000/60000 [==============================] - 16s 262us/sample - loss: 0.0375 - acc: 0.9878 - val_loss: 0.0370 - val_acc: 0.9888\n", 110 | "Epoch 3/19\n", 111 | "60000/60000 [==============================] - 16s 262us/sample - loss: 0.0243 - acc: 0.9921 - val_loss: 0.0391 - val_acc: 0.9889\n", 112 | "Epoch 4/19\n", 113 | "60000/60000 [==============================] - 17s 280us/sample - loss: 0.0182 - acc: 0.9940 - val_loss: 0.0298 - val_acc: 0.9912\n", 114 | "Epoch 5/19\n", 115 | "60000/60000 [==============================] - 17s 285us/sample - loss: 0.0125 - acc: 0.9961 - val_loss: 0.0315 - val_acc: 0.9908\n", 116 | "Epoch 6/19\n", 117 | "60000/60000 [==============================] - 17s 287us/sample - loss: 0.0097 - acc: 0.9966 - val_loss: 0.0456 - val_acc: 0.9883\n", 118 | "Epoch 7/19\n", 119 | "60000/60000 [==============================] - 17s 288us/sample - loss: 0.0090 - acc: 0.9968 - val_loss: 0.0580 - val_acc: 0.9869\n", 120 | "Epoch 8/19\n", 121 | "60000/60000 [==============================] - 17s 285us/sample - loss: 0.0068 - acc: 0.9980 - val_loss: 0.0380 - val_acc: 0.9906\n", 122 | "Epoch 9/19\n", 123 | "60000/60000 [==============================] - 18s 293us/sample - loss: 0.0061 - acc: 0.9980 - val_loss: 0.0360 - val_acc: 0.9910\n", 124 | "Epoch 10/19\n", 125 | "60000/60000 [==============================] - 17s 289us/sample - loss: 0.0048 - acc: 0.9984 - val_loss: 0.0524 - val_acc: 0.9885\n", 126 | "Epoch 11/19\n", 127 | "60000/60000 [==============================] - 17s 280us/sample - loss: 0.0054 - acc: 0.9982 - val_loss: 0.0534 - val_acc: 0.9909\n", 128 | "Epoch 12/19\n", 129 | "60000/60000 [==============================] - 17s 276us/sample - loss: 0.0058 - acc: 0.9983 - val_loss: 0.0512 - val_acc: 0.9893\n", 130 | "Epoch 13/19\n", 131 | "60000/60000 [==============================] - 17s 278us/sample - loss: 0.0036 - acc: 0.9990 - val_loss: 0.0542 - val_acc: 0.9892\n", 132 | "Epoch 14/19\n", 133 | "60000/60000 [==============================] - 17s 280us/sample - loss: 0.0040 - acc: 0.9989 - val_loss: 0.0570 - val_acc: 0.9905\n", 134 | "Epoch 15/19\n", 135 | "60000/60000 [==============================] - 17s 285us/sample - loss: 0.0045 - acc: 0.9987 - val_loss: 0.0593 - val_acc: 0.9909\n", 136 | "Epoch 16/19\n", 137 | "60000/60000 [==============================] - 17s 285us/sample - loss: 0.0027 - acc: 0.9991 - val_loss: 0.0692 - val_acc: 0.9893\n", 138 | "Epoch 17/19\n", 139 | "60000/60000 [==============================] - 17s 290us/sample - loss: 0.0049 - acc: 0.9987 - val_loss: 0.0614 - val_acc: 0.9899\n", 140 | "Epoch 18/19\n", 141 | "60000/60000 [==============================] - 17s 284us/sample - loss: 0.0038 - acc: 0.9990 - val_loss: 0.0734 - val_acc: 0.9888\n", 142 | "Epoch 19/19\n", 143 | "60000/60000 [==============================] - 18s 303us/sample - loss: 0.0024 - acc: 0.9994 - val_loss: 0.0699 - val_acc: 0.9897\n" 144 | ] 145 | } 146 | ], 147 | "source": [ 148 | "_, _ = train_mnist_conv()" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": null, 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "# Now click the 'Submit Assignment' button above.\n", 158 | "# Once that is complete, please run the following two cells to save your work and close the notebook" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": null, 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "%%javascript\n", 168 | "\n", 169 | "IPython.notebook.save_checkpoint();" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "metadata": {}, 176 | "outputs": [], 177 | "source": [ 178 | "%%javascript\n", 179 | "IPython.notebook.session.delete();\n", 180 | "window.onbeforeunload = null\n", 181 | "setTimeout(function() { window.close(); }, 1000);" 182 | ] 183 | } 184 | ], 185 | "metadata": { 186 | "coursera": { 187 | "course_slug": "introduction-tensorflow", 188 | "graded_item_id": "ml06H", 189 | "launcher_item_id": "hQF8A" 190 | }, 191 | "kernelspec": { 192 | "display_name": "Python 3", 193 | "language": "python", 194 | "name": "python3" 195 | }, 196 | "language_info": { 197 | "codemirror_mode": { 198 | "name": "ipython", 199 | "version": 3 200 | }, 201 | "file_extension": ".py", 202 | "mimetype": "text/x-python", 203 | "name": "python", 204 | "nbconvert_exporter": "python", 205 | "pygments_lexer": "ipython3", 206 | "version": "3.6.8" 207 | } 208 | }, 209 | "nbformat": 4, 210 | "nbformat_minor": 1 211 | } 212 | -------------------------------------------------------------------------------- /Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Exercise4-Question_complex_images_convnet_imagedatagenerator.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "UncprnB0ymAE" 8 | }, 9 | "source": [ 10 | "Below is code with a link to a happy or sad dataset which contains 80 images, 40 happy and 40 sad. \n", 11 | "Create a convolutional neural network that trains to 100% accuracy on these images, which cancels training upon hitting training accuracy of >.999\n", 12 | "\n", 13 | "Hint -- it will work best with 3 convolutional layers." 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "import tensorflow as tf\n", 23 | "import os\n", 24 | "import zipfile\n", 25 | "from os import path, getcwd, chdir\n", 26 | "\n", 27 | "# DO NOT CHANGE THE LINE BELOW. If you are developing in a local\n", 28 | "# environment, then grab happy-or-sad.zip from the Coursera Jupyter Notebook\n", 29 | "# and place it inside a local folder and edit the path to that location\n", 30 | "path = f\"{getcwd()}/../tmp2/happy-or-sad.zip\"\n", 31 | "\n", 32 | "zip_ref = zipfile.ZipFile(path, 'r')\n", 33 | "zip_ref.extractall(\"/tmp/h-or-s\")\n", 34 | "zip_ref.close()" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 10, 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "# GRADED FUNCTION: train_happy_sad_model\n", 44 | "def train_happy_sad_model():\n", 45 | " # Please write your code only where you are indicated.\n", 46 | " # please do not remove # model fitting inline comments.\n", 47 | "\n", 48 | " DESIRED_ACCURACY = 0.999\n", 49 | "\n", 50 | " \n", 51 | " # This Code Block should Define and Compile the Model. Please assume the images are 150 X 150 in your implementation.\n", 52 | " model = tf.keras.models.Sequential([\n", 53 | " # Your Code Here\n", 54 | " tf.keras.layers.Conv2D(16,kernel_size=(5,5),activation='relu',input_shape=(150,150,3)),\n", 55 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 56 | " tf.keras.layers.Conv2D(32,kernel_size=(5,5),activation='relu'),\n", 57 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 58 | " tf.keras.layers.Conv2D(64,kernel_size=(5,5),activation='relu'),\n", 59 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 60 | " tf.keras.layers.Flatten(),\n", 61 | " tf.keras.layers.Dense(512,activation='relu'),\n", 62 | " tf.keras.layers.Dense(1,activation='sigmoid')\n", 63 | " \n", 64 | " ])\n", 65 | "\n", 66 | " from tensorflow.keras.optimizers import RMSprop\n", 67 | "\n", 68 | " model.compile(loss='binary_crossentropy',metrics=['accuracy'],optimizer=RMSprop(lr=0.001))\n", 69 | " \n", 70 | "\n", 71 | " # This code block should create an instance of an ImageDataGenerator called train_datagen \n", 72 | " # And a train_generator by calling train_datagen.flow_from_directory\n", 73 | "\n", 74 | " from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 75 | "\n", 76 | " train_datagen = ImageDataGenerator(rescale=1./255)\n", 77 | "\n", 78 | " # Please use a target_size of 150 X 150.\n", 79 | " train_generator = train_datagen.flow_from_directory(\n", 80 | " \"/tmp/h-or-s\",batch_size=4,target_size=(150,150),class_mode='binary')\n", 81 | " # Your Code Here)\n", 82 | " # Expected output: 'Found 80 images belonging to 2 classes'\n", 83 | "\n", 84 | " # This code block should call model.fit_generator and train for\n", 85 | " # a number of epochs.\n", 86 | " # model fitting\n", 87 | " history = model.fit_generator(train_generator,epochs=20)\n", 88 | " # Your Code Here)\n", 89 | " # model fitting\n", 90 | " return history.history['acc'][-1]" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 11, 96 | "metadata": {}, 97 | "outputs": [ 98 | { 99 | "name": "stderr", 100 | "output_type": "stream", 101 | "text": [ 102 | "W0602 16:31:39.310365 140644650891072 deprecation.py:323] From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/nn_impl.py:180: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n", 103 | "Instructions for updating:\n", 104 | "Use tf.where in 2.0, which has the same broadcast rule as np.where\n" 105 | ] 106 | }, 107 | { 108 | "name": "stdout", 109 | "output_type": "stream", 110 | "text": [ 111 | "Found 80 images belonging to 2 classes.\n", 112 | "Epoch 1/20\n", 113 | "20/20 [==============================] - 6s 279ms/step - loss: 3.8764 - acc: 0.5625\n", 114 | "Epoch 2/20\n", 115 | "20/20 [==============================] - 1s 35ms/step - loss: 0.6581 - acc: 0.7750\n", 116 | "Epoch 3/20\n", 117 | "20/20 [==============================] - 1s 35ms/step - loss: 0.4889 - acc: 0.7625\n", 118 | "Epoch 4/20\n", 119 | "20/20 [==============================] - 1s 40ms/step - loss: 0.2436 - acc: 0.8875\n", 120 | "Epoch 5/20\n", 121 | "20/20 [==============================] - 1s 40ms/step - loss: 0.1632 - acc: 0.9625\n", 122 | "Epoch 6/20\n", 123 | "20/20 [==============================] - 1s 45ms/step - loss: 0.1494 - acc: 0.9500\n", 124 | "Epoch 7/20\n", 125 | "20/20 [==============================] - 1s 40ms/step - loss: 0.1391 - acc: 0.9375\n", 126 | "Epoch 8/20\n", 127 | "20/20 [==============================] - 1s 40ms/step - loss: 0.0323 - acc: 1.0000\n", 128 | "Epoch 9/20\n", 129 | "20/20 [==============================] - 1s 40ms/step - loss: 0.0090 - acc: 1.0000\n", 130 | "Epoch 10/20\n", 131 | "20/20 [==============================] - 1s 40ms/step - loss: 6.9138e-04 - acc: 1.0000\n", 132 | "Epoch 11/20\n", 133 | "20/20 [==============================] - 1s 40ms/step - loss: 8.2460e-05 - acc: 1.0000\n", 134 | "Epoch 12/20\n", 135 | "20/20 [==============================] - 1s 35ms/step - loss: 3.7469e-05 - acc: 1.0000\n", 136 | "Epoch 13/20\n", 137 | "20/20 [==============================] - 1s 40ms/step - loss: 5.2296e-05 - acc: 1.0000\n", 138 | "Epoch 14/20\n", 139 | "20/20 [==============================] - 1s 36ms/step - loss: 0.0585 - acc: 0.9875\n", 140 | "Epoch 15/20\n", 141 | "20/20 [==============================] - 1s 40ms/step - loss: 2.8687e-06 - acc: 1.0000: 1s - loss: 2.7878e-09 - acc:\n", 142 | "Epoch 16/20\n", 143 | "20/20 [==============================] - 1s 39ms/step - loss: 2.7452e-06 - acc: 1.0000\n", 144 | "Epoch 17/20\n", 145 | "20/20 [==============================] - 1s 40ms/step - loss: 2.4763e-06 - acc: 1.0000: 0s - loss: 3.1582e-06 - acc: 1\n", 146 | "Epoch 18/20\n", 147 | "20/20 [==============================] - 1s 35ms/step - loss: 1.9686e-06 - acc: 1.0000\n", 148 | "Epoch 19/20\n", 149 | "20/20 [==============================] - 1s 40ms/step - loss: 8.5964e-07 - acc: 1.0000\n", 150 | "Epoch 20/20\n", 151 | "20/20 [==============================] - 1s 40ms/step - loss: 3.6271e-07 - acc: 1.0000\n" 152 | ] 153 | }, 154 | { 155 | "data": { 156 | "text/plain": [ 157 | "1.0" 158 | ] 159 | }, 160 | "execution_count": 11, 161 | "metadata": {}, 162 | "output_type": "execute_result" 163 | } 164 | ], 165 | "source": [ 166 | "# The Expected output: \"Reached 99.9% accuracy so cancelling training!\"\"\n", 167 | "train_happy_sad_model()" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 4, 173 | "metadata": {}, 174 | "outputs": [], 175 | "source": [ 176 | "# Now click the 'Submit Assignment' button above.\n", 177 | "# Once that is complete, please run the following two cells to save your work and close the notebook" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": null, 183 | "metadata": {}, 184 | "outputs": [], 185 | "source": [ 186 | "%%javascript\n", 187 | "\n", 188 | "IPython.notebook.save_checkpoint();" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": {}, 195 | "outputs": [], 196 | "source": [ 197 | "%%javascript\n", 198 | "IPython.notebook.session.delete();\n", 199 | "window.onbeforeunload = null\n", 200 | "setTimeout(function() { window.close(); }, 1000);" 201 | ] 202 | } 203 | ], 204 | "metadata": { 205 | "coursera": { 206 | "course_slug": "introduction-tensorflow", 207 | "graded_item_id": "1kAlw", 208 | "launcher_item_id": "PNLYD" 209 | }, 210 | "kernelspec": { 211 | "display_name": "Python 3", 212 | "language": "python", 213 | "name": "python3" 214 | }, 215 | "language_info": { 216 | "codemirror_mode": { 217 | "name": "ipython", 218 | "version": 3 219 | }, 220 | "file_extension": ".py", 221 | "mimetype": "text/x-python", 222 | "name": "python", 223 | "nbconvert_exporter": "python", 224 | "pygments_lexer": "ipython3", 225 | "version": "3.6.8" 226 | } 227 | }, 228 | "nbformat": 4, 229 | "nbformat_minor": 1 230 | } 231 | -------------------------------------------------------------------------------- /Convolutional Neural Networks in TensorFlow/'Exercise_2_Cats_vs_Dogs_using_augmentation_Question-FINAL.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 10, 6 | "metadata": { 7 | "colab": {}, 8 | "colab_type": "code", 9 | "id": "dn-6c02VmqiN" 10 | }, 11 | "outputs": [], 12 | "source": [ 13 | "# ATTENTION: Please do not alter any of the provided code in the exercise. Only add your own code where indicated\n", 14 | "# ATTENTION: Please do not add or remove any cells in the exercise. The grader will check specific cells based on the cell position.\n", 15 | "# ATTENTION: Please use the provided epoch values when training.\n", 16 | "\n", 17 | "# In this exercise you will train a CNN on the FULL Cats-v-dogs dataset\n", 18 | "# This will require you doing a lot of data preprocessing because\n", 19 | "# the dataset isn't split into training and validation for you\n", 20 | "# This code block has all the required inputs\n", 21 | "import os\n", 22 | "import zipfile\n", 23 | "import random\n", 24 | "import shutil\n", 25 | "import tensorflow as tf\n", 26 | "from tensorflow.keras.optimizers import RMSprop\n", 27 | "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 28 | "from shutil import copyfile\n", 29 | "from os import getcwd" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 11, 35 | "metadata": { 36 | "colab": {}, 37 | "colab_type": "code", 38 | "id": "3sd9dQWa23aj" 39 | }, 40 | "outputs": [], 41 | "source": [ 42 | "# This code block unzips the full Cats-v-Dogs dataset to /tmp\n", 43 | "# which will create a tmp/PetImages directory containing subdirectories\n", 44 | "# called 'Cat' and 'Dog' (that's how the original researchers structured it)\n", 45 | "path_cats_and_dogs = f\"{getcwd()}/../tmp2/cats-and-dogs.zip\"\n", 46 | "shutil.rmtree('/tmp')\n", 47 | "\n", 48 | "local_zip = path_cats_and_dogs\n", 49 | "zip_ref = zipfile.ZipFile(local_zip, 'r')\n", 50 | "zip_ref.extractall('/tmp')\n", 51 | "zip_ref.close()" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 12, 57 | "metadata": { 58 | "colab": {}, 59 | "colab_type": "code", 60 | "id": "gi3yD62a6X3S" 61 | }, 62 | "outputs": [ 63 | { 64 | "name": "stdout", 65 | "output_type": "stream", 66 | "text": [ 67 | "1500\n", 68 | "1500\n" 69 | ] 70 | } 71 | ], 72 | "source": [ 73 | "print(len(os.listdir('/tmp/PetImages/Cat/')))\n", 74 | "print(len(os.listdir('/tmp/PetImages/Dog/')))\n", 75 | "\n", 76 | "# Expected Output:\n", 77 | "# 1500\n", 78 | "# 1500" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 13, 84 | "metadata": { 85 | "colab": {}, 86 | "colab_type": "code", 87 | "id": "F-QkLjxpmyK2" 88 | }, 89 | "outputs": [], 90 | "source": [ 91 | "# Use os.mkdir to create your directories\n", 92 | "# You will need a directory for cats-v-dogs, and subdirectories for training\n", 93 | "# and testing. These in turn will need subdirectories for 'cats' and 'dogs'\n", 94 | "try:\n", 95 | " os.mkdir('/tmp/cats-v-dogs')\n", 96 | " os.mkdir('/tmp/cats-v-dogs/training')\n", 97 | " os.mkdir('/tmp/cats-v-dogs/training/cats')\n", 98 | " os.mkdir('/tmp/cats-v-dogs/training/dogs')\n", 99 | "\n", 100 | " os.mkdir('/tmp/cats-v-dogs/testing')\n", 101 | " os.mkdir('/tmp/cats-v-dogs/testing/cats')\n", 102 | " os.mkdir('/tmp/cats-v-dogs/testing/dogs')\n", 103 | "\n", 104 | " #YOUR CODE GOES HERE\n", 105 | "except OSError:\n", 106 | " pass" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 14, 112 | "metadata": { 113 | "colab": {}, 114 | "colab_type": "code", 115 | "id": "zvSODo0f9LaU" 116 | }, 117 | "outputs": [], 118 | "source": [ 119 | "# Write a python function called split_data which takes\n", 120 | "# a SOURCE directory containing the files\n", 121 | "# a TRAINING directory that a portion of the files will be copied to\n", 122 | "# a TESTING directory that a portion of the files will be copie to\n", 123 | "# a SPLIT SIZE to determine the portion\n", 124 | "# The files should also be randomized, so that the training set is a random\n", 125 | "# X% of the files, and the test set is the remaining files\n", 126 | "# SO, for example, if SOURCE is PetImages/Cat, and SPLIT SIZE is .9\n", 127 | "# Then 90% of the images in PetImages/Cat will be copied to the TRAINING dir\n", 128 | "# and 10% of the images will be copied to the TESTING dir\n", 129 | "# Also -- All images should be checked, and if they have a zero file length,\n", 130 | "# they will not be copied over\n", 131 | "#\n", 132 | "# os.listdir(DIRECTORY) gives you a listing of the contents of that directory\n", 133 | "# os.path.getsize(PATH) gives you the size of the file\n", 134 | "# copyfile(source, destination) copies a file from source to destination\n", 135 | "# random.sample(list, len(list)) shuffles a list\n", 136 | "def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):\n", 137 | " total=len(os.listdir(SOURCE))\n", 138 | " train=int(total*SPLIT_SIZE)\n", 139 | " test=total-train\n", 140 | " SET=random.sample(os.listdir(SOURCE),len(os.listdir(SOURCE)))\n", 141 | " for i in range(train):\n", 142 | " copyfile(SOURCE+SET[i],TRAINING+SET[i])\n", 143 | " for i in range(train,train+test):\n", 144 | " copyfile(SOURCE+SET[i],TESTING+SET[i])\n", 145 | "\n", 146 | "# YOUR CODE STARTS HERE\n", 147 | "# YOUR CODE ENDS HERE\n", 148 | "\n", 149 | "\n", 150 | "CAT_SOURCE_DIR = \"/tmp/PetImages/Cat/\"\n", 151 | "TRAINING_CATS_DIR = \"/tmp/cats-v-dogs/training/cats/\"\n", 152 | "TESTING_CATS_DIR = \"/tmp/cats-v-dogs/testing/cats/\"\n", 153 | "DOG_SOURCE_DIR = \"/tmp/PetImages/Dog/\"\n", 154 | "TRAINING_DOGS_DIR = \"/tmp/cats-v-dogs/training/dogs/\"\n", 155 | "TESTING_DOGS_DIR = \"/tmp/cats-v-dogs/testing/dogs/\"\n", 156 | "\n", 157 | "split_size = .9\n", 158 | "split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)\n", 159 | "split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 15, 165 | "metadata": { 166 | "colab": {}, 167 | "colab_type": "code", 168 | "id": "luthalB76ufC" 169 | }, 170 | "outputs": [ 171 | { 172 | "name": "stdout", 173 | "output_type": "stream", 174 | "text": [ 175 | "1350\n", 176 | "1350\n", 177 | "150\n", 178 | "150\n" 179 | ] 180 | } 181 | ], 182 | "source": [ 183 | "print(len(os.listdir('/tmp/cats-v-dogs/training/cats/')))\n", 184 | "print(len(os.listdir('/tmp/cats-v-dogs/training/dogs/')))\n", 185 | "print(len(os.listdir('/tmp/cats-v-dogs/testing/cats/')))\n", 186 | "print(len(os.listdir('/tmp/cats-v-dogs/testing/dogs/')))\n", 187 | "\n", 188 | "# Expected output:\n", 189 | "# 1350\n", 190 | "# 1350\n", 191 | "# 150\n", 192 | "# 150" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 16, 198 | "metadata": { 199 | "colab": {}, 200 | "colab_type": "code", 201 | "id": "-BQrav4anTmj" 202 | }, 203 | "outputs": [], 204 | "source": [ 205 | "# DEFINE A KERAS MODEL TO CLASSIFY CATS V DOGS\n", 206 | "# USE AT LEAST 3 CONVOLUTION LAYERS\n", 207 | "model = tf.keras.models.Sequential([\n", 208 | " tf.keras.layers.Conv2D(64,input_shape=(150,150,3),kernel_size=(3,3),activation='relu'),\n", 209 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 210 | " tf.keras.layers.Conv2D(64,kernel_size=(3,3),activation='relu'),\n", 211 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 212 | " tf.keras.layers.Conv2D(64,kernel_size=(3,3),activation='relu'),\n", 213 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 214 | " tf.keras.layers.Flatten(),\n", 215 | " tf.keras.layers.Dense(1024,activation='relu'),\n", 216 | " tf.keras.layers.Dense(2,activation='sigmoid')\n", 217 | "# YOUR CODE HERE\n", 218 | "])\n", 219 | "\n", 220 | "model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['acc'])\n" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "# NOTE:\n", 228 | "\n", 229 | "In the cell below you **MUST** use a batch size of 10 (`batch_size=10`) for the `train_generator` and the `validation_generator`. Using a batch size greater than 10 will exceed memory limits on the Coursera platform." 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 17, 235 | "metadata": { 236 | "colab": {}, 237 | "colab_type": "code", 238 | "id": "mlNjoJ5D61N6" 239 | }, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "Found 2700 images belonging to 2 classes.\n", 246 | "Found 300 images belonging to 2 classes.\n" 247 | ] 248 | } 249 | ], 250 | "source": [ 251 | "TRAINING_DIR = '/tmp/cats-v-dogs/training'\n", 252 | "train_datagen = ImageDataGenerator(rescale=1./255,\n", 253 | " rotation_range=60,\n", 254 | " width_shift_range=0.2,\n", 255 | " height_shift_range=0.2,\n", 256 | " shear_range=0.2,\n", 257 | " zoom_range=0.2,\n", 258 | " fill_mode=\"nearest\",\n", 259 | " horizontal_flip=True,\n", 260 | ")\n", 261 | "\n", 262 | "# NOTE: YOU MUST USE A BATCH SIZE OF 10 (batch_size=10) FOR THE \n", 263 | "# TRAIN GENERATOR.\n", 264 | "train_generator = train_datagen.flow_from_directory(TRAINING_DIR,batch_size=10,target_size=(150,150))\n", 265 | "\n", 266 | "VALIDATION_DIR = '/tmp/cats-v-dogs/testing'\n", 267 | "validation_datagen = ImageDataGenerator(rescale=1./255)\n", 268 | "\n", 269 | "# NOTE: YOU MUST USE A BACTH SIZE OF 10 (batch_size=10) FOR THE \n", 270 | "# VALIDATION GENERATOR.\n", 271 | "validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,batch_size=10,target_size=(150,150))\n", 272 | "\n", 273 | "\n", 274 | "\n", 275 | "# Expected Output:\n", 276 | "# Found 2700 images belonging to 2 classes.\n", 277 | "# Found 300 images belonging to 2 classes.\n" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 20, 283 | "metadata": {}, 284 | "outputs": [ 285 | { 286 | "name": "stdout", 287 | "output_type": "stream", 288 | "text": [ 289 | "Epoch 1/2\n", 290 | "270/270 [==============================] - 68s 251ms/step - loss: 0.6155 - acc: 0.6783 - val_loss: 0.5777 - val_acc: 0.6883\n", 291 | "Epoch 2/2\n", 292 | "270/270 [==============================] - 67s 247ms/step - loss: 0.6424 - acc: 0.6733 - val_loss: 0.5501 - val_acc: 0.7033\n" 293 | ] 294 | } 295 | ], 296 | "source": [ 297 | "history = model.fit_generator(train_generator,\n", 298 | " epochs=2,\n", 299 | " verbose=1,\n", 300 | " validation_data=validation_generator)\n" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 21, 306 | "metadata": { 307 | "colab": {}, 308 | "colab_type": "code", 309 | "id": "MWZrJN4-65RC" 310 | }, 311 | "outputs": [ 312 | { 313 | "data": { 314 | "text/plain": [ 315 | "Text(0.5, 1.0, 'Training and validation loss')" 316 | ] 317 | }, 318 | "execution_count": 21, 319 | "metadata": {}, 320 | "output_type": "execute_result" 321 | }, 322 | { 323 | "data": { 324 | "image/png": "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\n", 325 | "text/plain": [ 326 | "
" 327 | ] 328 | }, 329 | "metadata": { 330 | "needs_background": "light" 331 | }, 332 | "output_type": "display_data" 333 | }, 334 | { 335 | "data": { 336 | "image/png": "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\n", 337 | "text/plain": [ 338 | "
" 339 | ] 340 | }, 341 | "metadata": { 342 | "needs_background": "light" 343 | }, 344 | "output_type": "display_data" 345 | } 346 | ], 347 | "source": [ 348 | "# PLOT LOSS AND ACCURACY\n", 349 | "%matplotlib inline\n", 350 | "\n", 351 | "import matplotlib.image as mpimg\n", 352 | "import matplotlib.pyplot as plt\n", 353 | "\n", 354 | "#-----------------------------------------------------------\n", 355 | "# Retrieve a list of list results on training and test data\n", 356 | "# sets for each training epoch\n", 357 | "#-----------------------------------------------------------\n", 358 | "acc=history.history['acc']\n", 359 | "val_acc=history.history['val_acc']\n", 360 | "loss=history.history['loss']\n", 361 | "val_loss=history.history['val_loss']\n", 362 | "\n", 363 | "epochs=range(len(acc)) # Get number of epochs\n", 364 | "\n", 365 | "#------------------------------------------------\n", 366 | "# Plot training and validation accuracy per epoch\n", 367 | "#------------------------------------------------\n", 368 | "plt.plot(epochs, acc, 'r', \"Training Accuracy\")\n", 369 | "plt.plot(epochs, val_acc, 'b', \"Validation Accuracy\")\n", 370 | "plt.title('Training and validation accuracy')\n", 371 | "plt.figure()\n", 372 | "\n", 373 | "#------------------------------------------------\n", 374 | "# Plot training and validation loss per epoch\n", 375 | "#------------------------------------------------\n", 376 | "plt.plot(epochs, loss, 'r', \"Training Loss\")\n", 377 | "plt.plot(epochs, val_loss, 'b', \"Validation Loss\")\n", 378 | "\n", 379 | "\n", 380 | "plt.title('Training and validation loss')\n", 381 | "\n", 382 | "# Desired output. Charts with training and validation metrics. No crash :)" 383 | ] 384 | }, 385 | { 386 | "cell_type": "markdown", 387 | "metadata": {}, 388 | "source": [ 389 | "# Submission Instructions" 390 | ] 391 | }, 392 | { 393 | "cell_type": "code", 394 | "execution_count": null, 395 | "metadata": {}, 396 | "outputs": [], 397 | "source": [ 398 | "# Now click the 'Submit Assignment' button above." 399 | ] 400 | }, 401 | { 402 | "cell_type": "markdown", 403 | "metadata": {}, 404 | "source": [ 405 | "# When you're done or would like to take a break, please run the two cells below to save your work and close the Notebook. This will free up resources for your fellow learners. " 406 | ] 407 | }, 408 | { 409 | "cell_type": "code", 410 | "execution_count": null, 411 | "metadata": {}, 412 | "outputs": [], 413 | "source": [ 414 | "%%javascript\n", 415 | "\n", 416 | "IPython.notebook.save_checkpoint();" 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": null, 422 | "metadata": {}, 423 | "outputs": [], 424 | "source": [ 425 | "%%javascript\n", 426 | "IPython.notebook.session.delete();\n", 427 | "window.onbeforeunload = null\n", 428 | "setTimeout(function() { window.close(); }, 1000);" 429 | ] 430 | } 431 | ], 432 | "metadata": { 433 | "accelerator": "GPU", 434 | "colab": { 435 | "collapsed_sections": [], 436 | "name": "Exercise 6 - Question.ipynb", 437 | "provenance": [] 438 | }, 439 | "coursera": { 440 | "course_slug": "convolutional-neural-networks-tensorflow", 441 | "graded_item_id": "uAPOR", 442 | "launcher_item_id": "e9lTb" 443 | }, 444 | "kernelspec": { 445 | "display_name": "Python 3", 446 | "language": "python", 447 | "name": "python3" 448 | }, 449 | "language_info": { 450 | "codemirror_mode": { 451 | "name": "ipython", 452 | "version": 3 453 | }, 454 | "file_extension": ".py", 455 | "mimetype": "text/x-python", 456 | "name": "python", 457 | "nbconvert_exporter": "python", 458 | "pygments_lexer": "ipython3", 459 | "version": "3.6.8" 460 | } 461 | }, 462 | "nbformat": 4, 463 | "nbformat_minor": 1 464 | } 465 | -------------------------------------------------------------------------------- /Convolutional Neural Networks in TensorFlow/Exercise_1_Cats_vs_Dogs_Question-FINAL.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 13, 6 | "metadata": { 7 | "colab": {}, 8 | "colab_type": "code", 9 | "id": "dn-6c02VmqiN" 10 | }, 11 | "outputs": [], 12 | "source": [ 13 | "# ATTENTION: Please do not alter any of the provided code in the exercise. Only add your own code where indicated\n", 14 | "# ATTENTION: Please do not add or remove any cells in the exercise. The grader will check specific cells based on the cell position.\n", 15 | "# ATTENTION: Please use the provided epoch values when training.\n", 16 | "\n", 17 | "# In this exercise you will train a CNN on the FULL Cats-v-dogs dataset\n", 18 | "# This will require you doing a lot of data preprocessing because\n", 19 | "# the dataset isn't split into training and validation for you\n", 20 | "# This code block has all the required inputs\n", 21 | "import os\n", 22 | "import zipfile\n", 23 | "import random\n", 24 | "import tensorflow as tf\n", 25 | "import shutil\n", 26 | "from tensorflow.keras.optimizers import RMSprop\n", 27 | "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 28 | "from shutil import copyfile\n", 29 | "from os import getcwd" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 14, 35 | "metadata": { 36 | "colab": {}, 37 | "colab_type": "code", 38 | "id": "3sd9dQWa23aj" 39 | }, 40 | "outputs": [], 41 | "source": [ 42 | "path_cats_and_dogs = f\"{getcwd()}/../tmp2/cats-and-dogs.zip\"\n", 43 | "shutil.rmtree('/tmp')\n", 44 | "\n", 45 | "local_zip = path_cats_and_dogs\n", 46 | "zip_ref = zipfile.ZipFile(local_zip, 'r')\n", 47 | "zip_ref.extractall('/tmp')\n", 48 | "zip_ref.close()\n" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 15, 54 | "metadata": { 55 | "colab": {}, 56 | "colab_type": "code", 57 | "id": "gi3yD62a6X3S" 58 | }, 59 | "outputs": [ 60 | { 61 | "name": "stdout", 62 | "output_type": "stream", 63 | "text": [ 64 | "1500\n", 65 | "1500\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "print(len(os.listdir('/tmp/PetImages/Cat/')))\n", 71 | "print(len(os.listdir('/tmp/PetImages/Dog/')))\n", 72 | "\n", 73 | "# Expected Output:\n", 74 | "# 1500\n", 75 | "# 1500" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 16, 81 | "metadata": { 82 | "colab": {}, 83 | "colab_type": "code", 84 | "id": "F-QkLjxpmyK2" 85 | }, 86 | "outputs": [], 87 | "source": [ 88 | "# Use os.mkdir to create your directories\n", 89 | "# You will need a directory for cats-v-dogs, and subdirectories for training\n", 90 | "# and testing. These in turn will need subdirectories for 'cats' and 'dogs'\n", 91 | "try:\n", 92 | " os.mkdir('/tmp/cats-v-dogs')\n", 93 | " os.mkdir('/tmp/cats-v-dogs/training')\n", 94 | " os.mkdir('/tmp/cats-v-dogs/training/cats')\n", 95 | " os.mkdir('/tmp/cats-v-dogs/training/dogs')\n", 96 | "\n", 97 | " os.mkdir('/tmp/cats-v-dogs/testing')\n", 98 | " os.mkdir('/tmp/cats-v-dogs/testing/cats')\n", 99 | " os.mkdir('/tmp/cats-v-dogs/testing/dogs')\n", 100 | " \n", 101 | "except OSError:\n", 102 | " pass" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 17, 108 | "metadata": { 109 | "colab": {}, 110 | "colab_type": "code", 111 | "id": "zvSODo0f9LaU" 112 | }, 113 | "outputs": [], 114 | "source": [ 115 | "# Write a python function called split_data which takes\n", 116 | "# a SOURCE directory containing the files\n", 117 | "# a TRAINING directory that a portion of the files will be copied to\n", 118 | "# a TESTING directory that a portion of the files will be copie to\n", 119 | "# a SPLIT SIZE to determine the portion\n", 120 | "# The files should also be randomized, so that the training set is a random\n", 121 | "# X% of the files, and the test set is the remaining files\n", 122 | "# SO, for example, if SOURCE is PetImages/Cat, and SPLIT SIZE is .9\n", 123 | "# Then 90% of the images in PetImages/Cat will be copied to the TRAINING dir\n", 124 | "# and 10% of the images will be copied to the TESTING dir\n", 125 | "# Also -- All images should be checked, and if they have a zero file length,\n", 126 | "# they will not be copied over\n", 127 | "#\n", 128 | "# os.listdir(DIRECTORY) gives you a listing of the contents of that directory\n", 129 | "# os.path.getsize(PATH) gives you the size of the file\n", 130 | "# copyfile(source, destination) copies a file from source to destination\n", 131 | "# random.sample(list, len(list)) shuffles a list\n", 132 | "def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):\n", 133 | " total=len(os.listdir(SOURCE))\n", 134 | " train=int(total*SPLIT_SIZE)\n", 135 | " test=total-train\n", 136 | " SET=random.sample(os.listdir(SOURCE),len(os.listdir(SOURCE)))\n", 137 | " for i in range(train):\n", 138 | " copyfile(SOURCE+SET[i],TRAINING+SET[i])\n", 139 | " for i in range(train,train+test):\n", 140 | " copyfile(SOURCE+SET[i],TESTING+SET[i])\n", 141 | " \n", 142 | " \n", 143 | "# YOUR CODE STARTS HERE\n", 144 | "# YOUR CODE ENDS HERE\n", 145 | "\n", 146 | "\n", 147 | "CAT_SOURCE_DIR = \"/tmp/PetImages/Cat/\"\n", 148 | "TRAINING_CATS_DIR = \"/tmp/cats-v-dogs/training/cats/\"\n", 149 | "TESTING_CATS_DIR = \"/tmp/cats-v-dogs/testing/cats/\"\n", 150 | "DOG_SOURCE_DIR = \"/tmp/PetImages/Dog/\"\n", 151 | "TRAINING_DOGS_DIR = \"/tmp/cats-v-dogs/training/dogs/\"\n", 152 | "TESTING_DOGS_DIR = \"/tmp/cats-v-dogs/testing/dogs/\"\n", 153 | "\n", 154 | "split_size = .9\n", 155 | "split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)\n", 156 | "split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 18, 162 | "metadata": { 163 | "colab": {}, 164 | "colab_type": "code", 165 | "id": "luthalB76ufC" 166 | }, 167 | "outputs": [ 168 | { 169 | "name": "stdout", 170 | "output_type": "stream", 171 | "text": [ 172 | "1350\n", 173 | "1350\n", 174 | "150\n", 175 | "150\n" 176 | ] 177 | } 178 | ], 179 | "source": [ 180 | "print(len(os.listdir('/tmp/cats-v-dogs/training/cats/')))\n", 181 | "print(len(os.listdir('/tmp/cats-v-dogs/training/dogs/')))\n", 182 | "print(len(os.listdir('/tmp/cats-v-dogs/testing/cats/')))\n", 183 | "print(len(os.listdir('/tmp/cats-v-dogs/testing/dogs/')))\n", 184 | "\n", 185 | "# Expected output:\n", 186 | "# 1350\n", 187 | "# 1350\n", 188 | "# 150\n", 189 | "# 150" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": 20, 195 | "metadata": { 196 | "colab": {}, 197 | "colab_type": "code", 198 | "id": "-BQrav4anTmj" 199 | }, 200 | "outputs": [], 201 | "source": [ 202 | "# DEFINE A KERAS MODEL TO CLASSIFY CATS V DOGS\n", 203 | "# USE AT LEAST 3 CONVOLUTION LAYERS\n", 204 | "model = tf.keras.models.Sequential([\n", 205 | " tf.keras.layers.Conv2D(64,input_shape=(150,150,3),kernel_size=(3,3),activation='relu'),\n", 206 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 207 | " tf.keras.layers.Conv2D(64,kernel_size=(3,3),activation='relu'),\n", 208 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 209 | " tf.keras.layers.Conv2D(64,kernel_size=(3,3),activation='relu'),\n", 210 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 211 | " tf.keras.layers.Flatten(),\n", 212 | " tf.keras.layers.Dense(1024,activation='relu'),\n", 213 | " tf.keras.layers.Dense(2,activation='sigmoid')\n", 214 | "# YOUR CODE HERE\n", 215 | "])\n", 216 | "\n", 217 | "model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['acc'])" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "# NOTE:\n", 225 | "\n", 226 | "In the cell below you **MUST** use a batch size of 10 (`batch_size=10`) for the `train_generator` and the `validation_generator`. Using a batch size greater than 10 will exceed memory limits on the Coursera platform." 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": 21, 232 | "metadata": { 233 | "colab": {}, 234 | "colab_type": "code", 235 | "id": "mlNjoJ5D61N6" 236 | }, 237 | "outputs": [ 238 | { 239 | "name": "stdout", 240 | "output_type": "stream", 241 | "text": [ 242 | "Found 2700 images belonging to 2 classes.\n", 243 | "Found 300 images belonging to 2 classes.\n" 244 | ] 245 | } 246 | ], 247 | "source": [ 248 | "TRAINING_DIR = '/tmp/cats-v-dogs/training'\n", 249 | "train_datagen = ImageDataGenerator(rescale=1./255)\n", 250 | "\n", 251 | "# NOTE: YOU MUST USE A BATCH SIZE OF 10 (batch_size=10) FOR THE \n", 252 | "# TRAIN GENERATOR.\n", 253 | "train_generator = train_datagen.flow_from_directory(TRAINING_DIR,batch_size=10,target_size=(150,150))\n", 254 | "\n", 255 | "VALIDATION_DIR = '/tmp/cats-v-dogs/testing'\n", 256 | "validation_datagen = ImageDataGenerator(rescale=1./255)\n", 257 | "\n", 258 | "# NOTE: YOU MUST USE A BACTH SIZE OF 10 (batch_size=10) FOR THE \n", 259 | "# VALIDATION GENERATOR.\n", 260 | "validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,batch_size=10,target_size=(150,150))\n", 261 | "\n", 262 | "\n", 263 | "\n", 264 | "# Expected Output:\n", 265 | "# Found 2700 images belonging to 2 classes.\n", 266 | "# Found 300 images belonging to 2 classes." 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 22, 272 | "metadata": { 273 | "colab": {}, 274 | "colab_type": "code", 275 | "id": "KyS4n53w7DxC" 276 | }, 277 | "outputs": [ 278 | { 279 | "name": "stdout", 280 | "output_type": "stream", 281 | "text": [ 282 | "Epoch 1/2\n", 283 | "270/270 [==============================] - 38s 142ms/step - loss: 0.7142 - acc: 0.5707 - val_loss: 0.6748 - val_acc: 0.6217\n", 284 | "Epoch 2/2\n", 285 | "270/270 [==============================] - 38s 142ms/step - loss: 0.6198 - acc: 0.6835 - val_loss: 0.6238 - val_acc: 0.7133\n" 286 | ] 287 | } 288 | ], 289 | "source": [ 290 | "history = model.fit_generator(train_generator,\n", 291 | " epochs=2,\n", 292 | " verbose=1,\n", 293 | " validation_data=validation_generator)\n" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": 23, 299 | "metadata": { 300 | "colab": {}, 301 | "colab_type": "code", 302 | "id": "MWZrJN4-65RC" 303 | }, 304 | "outputs": [ 305 | { 306 | "data": { 307 | "text/plain": [ 308 | "Text(0.5, 1.0, 'Training and validation loss')" 309 | ] 310 | }, 311 | "execution_count": 23, 312 | "metadata": {}, 313 | "output_type": "execute_result" 314 | }, 315 | { 316 | "data": { 317 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAccAAAEICAYAAAAqQj/TAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAcEElEQVR4nO3debxdZX3v8c+XRIaQkIQEGSIhICig4ECqtpVWK9cieqHeWgpULbaotdXWTrfeTtrWtvZlr31V68VSr7XO4kDLrXUWCqWiDaPgVFFUVCwQkjAYhvC7f6y1yc7DGfZJTs7Jyfm8X6/9ytprrf2s51n75HzP86xn75WqQpIkbbXHbFdAkqRdjeEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHaQRJFiS5M8nq6dx3NiU5Msm0f5YryUlJbhx6/pUkJ46y73Yc661Jfnd7Xy+NZ+FsV0DaGZLcOfR0EXAPsKV//tKqevdUyquqLcDi6d53PqiqR09HOUnOAZ5fVU8bKvuc6ShbahmO2i1V1YPh1PdMzqmqT423f5KFVXX/TNRNmow/j7PPYVXNS0lem+T9Sd6b5A7g+Ul+OMnlSTYk+V6SNyZ5WL//wiSVZE3//F399o8muSPJZ5McPtV9++3PSvLVJBuTvCnJZUnOHqfeo9TxpUm+luT2JG8ceu2CJH+V5LYkXwdOnuD8/F6S9zXr3pzkDf3yOUm+1Lfnhr5XN15ZNyV5Wr+8KMk7+7pdD5zQ7Pv7Sb7el3t9klP79ccBfwOc2A9Z3zp0bl8z9Ppf6tt+W5J/THLwKOdmKud5UJ8kn0qyPsnNSf7n0HH+oD8nm5KsS3LIWEPYSf5t8D735/OS/jjrgd9PclSSi/pj3Nqft6VDrz+sb+Mt/fa/TrJ3X+djhvY7OMndSVaM1149lOGo+ey5wHuApcD7gfuBXwNWAj9KFx4vneD1ZwF/AOwPfAv4k6num+ThwPnAb/fH/QbwpAnKGaWOp9CFzhPoQv+kfv3LgGcCjwN+CDh9guO8F3hOkn37ei4EfobufAF8H3g2sB/wYuBNSY6foLyBPwYOBY7o6/nzzfav9u1aCvwp8J4kB1bVF4CXA5dW1eKqWtkWnOSZffnPA1YB3wXa4fPxzk1r3PPcB9SngP8HHAw8Cri4f91v98c/GVgGnANsnuiEDPkR4EvAAcBfAAFeCxwEHEt3zv6gr8NC4CPA14A1dOf0/KraTPfz9Pyhcs8CPl5Vt41YDwFUlQ8fu/UDuBE4qVn3WuAzk7zut4AP9MsLgQLW9M/fBbxlaN9Tgeu2Y99foPuFP9gW4HvA2SO2baw6PmVo+4eB3+qXL6EbXh5sO6X7FTBu2ZcDZ/XLzwK+MsG+/wz8Sr98EnDj0LabgKf1y98afi+AXx7ed4xyrwOe3S+fA1zcbH8X8Jp++R+APxvath/ddeZHTHZupnieXwD8xzj73TCob7P+yPZcA/82eJ/7tn19kjo8b3Bc4ETgZmDBGPv9KN0fWemfXw38j+n+f7W7P+w5aj779vCTJEcn+Ug/TLaJrhfykB7KkJuHlu9m4kk44+17yHA9qvttdtN4hYxYx5GOBXxzgvpC10s8s18+i629RpI8J8nn+iG/DXQ90onO1cDBE9UhydlJrumHBjcAR49YLnTte7C8qtoE3E7XixwY6T2b5DwfSheCY5lo22Tan8eDkpyf5Dt9Hd7e1OHG6iZ/baOqLqPr+T41yWOB1XS9TE2B4aj5rP0Yw9/S9VSOrKr9gD+k68ntTN+j69kAkCRs+8u8tSN1/B7dL9WByT5qcj5wUpJVwGn04ZhkH+CDwJ8DB1bVMuATI9bj5vHqkOQI4Fy64d8VfblfHip3so+dfBc4bKi8JcBy4Dsj1Ks10Xn+NvDIcV433ra7+jotGlp3ULNP276/oJtlfVxfh7ObOhyWZME49XgH3dDqC+iGW+8ZZz+Nw3CUtloCbATu6ic0THS9cbr8M/DEJP+9v470a3TXnHZGHc8HXplkVT8543cm2rmqbqYb+ns73ZDqf/ab9gL2BG4BtiR5DvCMKdThd5MsS/c50JcPbVtMFxC30P2d8GK6nuPA94FHDE+MabwX+MUkxyfZiy68L62qcXviE5joPF8IrE7y8iR7JdkvyeA68VuB1yZ5ZDqPT7I/3R8FN9Nd51yQ5CUMBfkEdbgL2JjkULqh3YHPArcBf5ZuktM+SX50aPs76YZhz6ILSk2R4Sht9Zt0E0TuoOs5vH9nH7Cqvg/8LPAGul92jwSuousxTHcdzwU+DXwB+A+63t9k3kN3DfHBIdWq2gD8OnABsJ7ul/A/j1iHV9P1YG8EPsrQL+6quhZ4E/D5fp9HA58beu0ngf8Evp9keHh08PqP0Q1/XtC/fjXwcyPWqzXuea6qjcB/A36aLrC/Cvx4v/n1wD/SnedNwHnA3v1w+YuB3wVupbsGOdy2sbyabnLWRrpA/tBQHe4HngMcQ9eL/Bbd+zDYfiPd+3xPVf37FNsutl6wlbQL6IfJvgs8r6oune36aO5K8g66ST6vme26zEV+CYA0y5KcTDcz9AfA/wLuo+s9Sdulv357GnDcbNdlrnJYVZp9TwW+Tnet7SeB5zqBQtsryZ8D19B9rOVbs12fucphVUmSGvYcJUlqeM1xN7Fy5cpas2bNbFdDkuaMK6644taqGvOjU4bjbmLNmjWsW7dutqshSXNGknG/JcphVUmSGoajJEkNw1GSpIbhKElSw3CUJKkxYTgmuSjJTzbrXpnk3Eled2f/7yFJxvxy4yQXJ1k7STmvHL7FS5J/SbJsotdMRZKrk7xvusqTJO0eJus5vhc4o1l3Rr9+UlX13ap63uR7juuVwIPhWFWn9HcE2GH9bWgWACcm2Xc6yhznOH5cRpLmmMnC8YPAs5PsCZBkDd3dti9NsjjJp5NcmeQLSU5rX5xkTZLr+uV9krwvyZeSXADsM7TfuUnWJbk+yR/16361P9ZFSS7q192YZGW//BtJrusfrxw63peS/F1f1if6G7OO5Uy6e559gu4Legd1OTLJp/q7kV+Z5JH9+t/p23lNktf16x7s/SZZmeTGfvnsJBcm+Qzw6YnOVZIXJrm2L/edSZYk+cbgnnX9veIefC5J2vkm7NVU1foknweeBfwTXa/x/KqqJJvpviB5Ux9Ylye5sMb/staXAXdX1TFJjgeuHNr2e/2xFtCFyfFV9cYkvwE8vapuHS4oyQnAi4An090Z+3NJ/hW4HTgKOLOqXpzkfLp7rr1rjPr8LN092Y4GXsHW+9W9G3hdVV2QZG9gjyTPogvQJ1fV3f3NSyfzROD4vl0LxzpXwLHA7wM/UlW3Jtm/qu5IcjHwbLr7wp0BfLiq7msP0N8w9SUAq1dPdlN3SdKoRpmQMzy0OjykGrq7UF8LfApYBRw4QTk/Rh9S/U1Nrx3adnqSK+lu8voYutCYyFOBC6rqrqq6E/gwcGK/7RtVdXW/fAWwpn1x39u7tf/G+k8DT0iyf5IlwKqquqCv5+aqupvuZq9/3y9TVesnqR/AJ4f2G+9c/QTwgUH4D+3/Vrrwp//378c6QFWdV1Vrq2rtAQdMdPN4SdJUjBKO/wQ8I8kTgUVVdUW//ueAA4ATqurxdHfE3nuqFUhyOPBbwDOq6njgI9tTzpDhW/1sYeze8ZnA0f0w6A3AfnQ9zKm6n63nsK3zXUPLUzpXVXUZsCbJ04AFVXXddtRNkrSdJg3Hvmd2EfA2tp2IsxT4r6q6L8nTgcMmKeoS4CyAJI8Fju/X70cXJBuTHEg3hDtwB7BkjLIuBX4qyaJ+Ms1z+3WTSrIHcDpwXFWtqao1dEOmZ1bVHcBNSX6q33evfrbsJ4EXDWbODg2r3gic0C9PNPFovHP1GeBnkqxoygV4B91Q75i9RknSzjPq5xzfCzyObcPx3cDaJF8AXgh8eZIyzgUWJ/kS8Md0Q55U1TV0w6lfpguDy4Zecx7wscGEnIGquhJ4O93d0j8HvLWqrhqxLScC36mq7w6tuwQ4NsnBwAuAX+2HQP8dOKiqPgZcCKxLcjVdTxfgL4GXJbkKWDnBMcc8V1V1PfCnwL8muQZ4Q/Oa5Yw4M1iSNH282fEuKsnzgNOq6gWj7L927dryrhySNLokV1TVmJ+39zN4u6Akb6IbXj5ltusiSfOR4bgLqqpXzHYdJGk+87tVJUlqGI6SJDUMR0mSGoajJEkNw1GSpIbhKElSw3CUJKlhOEqS1DAcJUlqGI6SJDUMR0mSGoajJEkNw1GSpIbhKElSw3CUJKlhOEqS1DAcJUlqGI6SJDUMR0mSGoajJEkNw1GSpIbhKElSw3CUJKlhOEqS1DAcJUlqGI6SJDUMR0mSGoajJEkNw1GSpIbhKElSw3CUJKlhOEqS1DAcJUlqGI6SJDUMR0mSGoajJEkNw1GSpIbhKElSw3CUJKlhOEqS1DAcJUlqGI6SJDUMR0mSGoajJEkNw1GSpIbhKElSw3CUJKlhOEqS1Fg42xWQJGnzZti4ETZs6P4dPNrn7bp994VLL53++hiOkqQdct99owXZRM/vvXfiYySw336wdCksW9b9u2oVHHLIzmmT4ShJ89iWLbBp09SCrH3+gx9MfpzFi7tAG4TbAQfAkUduG3bD29vnixfDHjN4IdBwlKQ56oEH4M47ty/YBuvuvHPy4+yzz0ODa/Xq0YJt6dKux7dwjqXNHKuuJO0equDuu7fvOtvg+aZNXTkT2XPPh4bXQQdN3Etrw23PPWfmnOxKDEdJ2g6DCSQ7Mhy5ZcvEx1iw4KHBdfjhUwu2vffurtdpagxHSfPOYALJjgTbVCaQDB6rVsGxx44ebvvuO8+C7Z57YP16uO22rY/Jnu+7L9xww7RXxXCUNKfsyASSwbqpTiBZunTbCSSjBNuSJTM7gWSXsmVLd6JHCbfh53fdNX6Ze+0FK1Z0j/33h6OP7pYPPninNMFwlDRjJppAMmrYTXUCyeAxmEAySrjNxQkkO0VVF1hT6cmtXw+33z7+xdA99oDly7cG3apVcNxxW58Pwq99vmjRjHajffsljWR4Asn2DkeOMoHkYQ97aHANTyAZpdc2HyeQTOree6fek1u/fuLx4yVLtg2yww8fP9wGy0uXzokuteEozRM7OoFk0ya4//6Jj7HHHg8NqjVrRvscmxNIRvTAA1uHLKcSdhN1uffcc9sge9SjJu7FDf7djf8KMRylOWAqE0jG22eUCSRLlmwbVIccsu0EksmCbd5NINkRgyHLqU5AmWjIMtl2yPKQQ+Cxj518yNI37iEMR2knm2gCyai9tlEmkOy777ZBtXIlPPKRo/fa5vUEkh11771bQ2wqYTfRXyyLF28bYIcdNvmQ5bJlvonTxHCUJjA8gWR7hyNHmUCy994PDa5DDx092JxAMk0eeKB746Y6AeWOO8Yv82EP2zbMjjoKnvzkiXtzy5d3szM1a/zvpN3WTE4gaYPrwANHmzgyeL4bX7qZHYM3f6o9udtv7wJyLIMhy0GQHXQQPOYxE/fkVqxwyHKOMhy1y5rKBJLx1o0ygaQNqjVrphZsTiDZye67b/why4nC7p57xi9z3323DbNDD518AsqyZd1X1mheMBy1U0w0gWTUXttkE0hg228gWbasm39wzDGjh5t/1M+gBx7ouuJTHbLctGn8Mhcu3DbIjjxy8p7c/vs7ZKlJGY56iOEJJNs7HDnqBJLhoBpMIBk12JxAMosGQ5ajfE5ueMhyvC8TTbo3dRBeD39491fOZBNQFi/2rxvtFIbjPHfqqd3vreFwm2huwcBgAslwcB166Ogf0l661Akku4T77utCa6q9uc2bxy9z0aJtw+z44yfvyS1f7pCldin+eprnNm3qgm4wgWTUYHNUahdT1f1lM5VrcrfdNtqQ5SDMjjgCfuiHJu7J7b9/9wMlzXGG4zx38cWzXQM9xA9+MPVvP1m/fuL7Hw2GLFes6MavH/3oySegLFnikKXmLcNR2lnuv3/7hiwnumC7aNG2YXbccZNPQFm2zDFsaYr8HyNNpmrrLMupfGZu48bxy1y4cNvvqFyzBk44YfIJKA5ZSjPCcNT8snnz1Hty69dP/IHJpUsf+g0ok01A2W8/hyylXZjhqLlpMGQ51S9tnmjIcp99tg2zwRc2T9STW77cIUtpN+T/as2uqu6zI1OdgLJhw/hlLliwbYCtXg1PeMLkE1D22Wfm2i1pl2Y4avps3jz1ntwoQ5bDYXbUUZNPQHHIUtIOMhz1UFu2bJ1lOZWwu/vu8cvce+9tw+zYYyfvyS1f3n2rtyTNMMNxPquCs8+GW27ZNuw2bBj/VhR77LFtmB16KDzucZNPQFm0aEabJkk7wnCczxK49truGt2KFd0Xm042AWW//fxCU0m7PcNxvrvqqtmugSTtcuwCSJLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIahqMkSQ3DUZKkhuEoSVLDcJQkqWE4SpLUMBwlSWoYjpIkNQxHSZIaOxyOSVYkubp/3JzkO0PP9xyxjL9P8uhJ9vmVJD+3o/UdKu/AJPcnOWe6ypQk7R4W7mgBVXUb8HiAJK8B7qyqvxzeJ0mAVNUD45TxohGO8+YdrWvjdOCzwJnAW6e57AclWVhV9++s8iVJ02+nDasmOTLJF5O8G7geODjJeUnWJbk+yR8O7ftvSR6fZGGSDUlel+SaJJ9N8vB+n9cmeeXQ/q9L8vkkX0nyI/36fZN8qD/uB/tjPX6cKp4JvBI4IsnBQ3V5dpIr++N/ol+3JMk/JLm2f/zUoK5DrzsjyVv75XclOTfJ54E/S/KUvi1XJbksyVH9fguT/FWS6/pyfznJM5N8cKjcZyX5wHS8J5Kk0exwz3ESRwMvrKp1AEleVVXrkywELkrywar6YvOapcC/VtWrkrwB+AXgdWOUnap6UpJTgT8ETgZeAdxcVT+d5HHAlWNVKskaYP+quqIPntOBv05yEHAucGJVfTPJ/v1LXgPcUlXH973gZSO0/WDgKVX1QJKlfZn3JzkZeC3ws8DLgEOAx1XVlv54G4C/SbKi75W/CHjbOO14CfASgNWrV49QJUnSKHb2hJwbBsHYOzPJlXShdQxw7Biv+UFVfbRfvgJYM07ZHx5jn6cC7wOoqmvoeqxjOQN4f7/8PrpeJMAPAxdV1Tf7Mtb3608C3tyvq6q6fZxyh31gaBh5GfChJNcBfwk8Zqjct1TVlsHx+te8GzirD8sTgE+MdYCqOq+q1lbV2gMOOGCEKkmSRrGze453DRb6ocRfA55UVRuSvAvYe4zX3Du0vIXx63jPCPuM50xgZZKf758fkuSIKZbxAJCh521b7hpa/lPg41X1f5IcCXxskrLfBnyoX37/IDwlSTNjJj/KsR9wB7Cpv8b3kzvhGJfRDZGS5DjG6JkmORZYWFWrqmpNVa0BXk/Xm/x34OlJDuv3HQyrfhL4lX5dkizve3i3JzkqyR7Acyeo11LgO/3y2UPrPwn8UpIFw8erqm8DtwKvAt4+lRMgSdpxMxmOVwJfBL4MvIMuyKbbm4BVSb4IvLo/3sZmnzOBC5p1HwLOrKrv010H/Kck19ANbwL8EXBgPyx6NXBiv/53gI/ThepNE9TrL4DX90PKw73NvwVuBq7tj3f60Lb3AN+oqq9O3GRJ0nRLVc12HaZNP9FnYVVt7odxPwEcNRc/SpHkLcBnq+ofRtl/7dq1tW7dusl3lCQBkOSKqlo71radfc1xpi0GPt2HZICXztFgvBq4HfjV2a6LJM1Hu1U4VtUGutmdc1pVjffZTEnSDPC7VSVJahiOkiQ1dqsJOfNZkluAb27ny1fSfXRkPrHNu7/51l6wzVN1WFWN+Q0qhqNIsm68GVu7K9u8+5tv7QXbPJ0cVpUkqWE4SpLUMBwFcN5sV2AW2Obd33xrL9jmaeM1R0mSGvYcJUlqGI6SJDUMx3kkyclJvpLka0leNcb2vZK8v9/+uSRrZr6W02eE9v5Gki8muTbJpwe3KpvLJmvz0H4/naSSzPlp/6O0Ocnp/Xt9fZL3zHQdp9sIP9urk1yU5Kr+5/uU2ajndEnytiT/1d8ZaaztSfLG/nxcm+SJO3zQqvIxDx7AAuAG4AhgT+Aa4Nhmn18G3tIvn0F3o+VZr/tObO/TgUX98svmcntHbXO/3xLgEuByYO1s13sG3uejgKuA5f3zh892vWegzecBL+uXjwVunO1672Cbfwx4InDdONtPAT5Kd8OJpwCf29Fj2nOcP54EfK2qvl5V9wLvA05r9jkNGNwi64PAM5KEuWnS9lbVRVV1d//0cuARM1zH6TbKewzwJ3T3GN08k5XbSUZp84uBN1fV7QBV9V8zXMfpNkqbi+4G89DdbP27M1i/aVdVlwDrJ9jlNOAd1bkcWJbk4B05puE4f6wCvj30/KZ+3Zj7VHerr43Aihmp3fQbpb3DfpHuL8+5bNI298NNh1bVR2ayYjvRKO/zo4BHJbksyeVJTp6x2u0co7T5NcDzk9wE/Avwipmp2qyZ6v/3Se1Wt6yStkeS5wNrgR+f7brsTEn2AN4AnD3LVZlpC+mGVp9GNzpwSZLjqrvF3e7qTODtVfW/k/ww8M4kj62qB2a7YnOFPcf54zvAoUPPH9GvG3Of/obRS4HbZqR202+U9pLkJOD3gFOr6p4ZqtvOMlmblwCPBS5OciPdtZkL5/iknFHe55uAC6vqvqr6BvBVurCcq0Zp8y8C5wNU1WeBvem+oHt3NdL/96kwHOeP/wCOSnJ4kj3pJtxc2OxzIfDz/fLzgM9Uf7V7Dpq0vUmeAPwtXTDO9etQMEmbq2pjVa2sqjVVtYbuOuupVbVudqo7LUb5uf5Hul4jSVbSDbN+fSYrOc1GafO3gGcAJDmGLhxvmdFazqwLgRf2s1afAmysqu/tSIEOq84TVXV/kpcDH6eb7fa2qro+yR8D66rqQuD/0g2/fI3u4vcZs1fjHTNie18PLAY+0M87+lZVnTprld5BI7Z5tzJimz8OPDPJF4EtwG9X1VwdERm1zb8J/F2SX6ebnHP2HP5DlyTvpfsDZ2V/HfXVwMMAquotdNdVTwG+BtwNvGiHjzmHz5ckSTuFw6qSJDUMR0mSGoajJEkNw1GSpIbhKElSw3CUJKlhOEqS1Pj/vUPBEzUbOvYAAAAASUVORK5CYII=\n", 318 | "text/plain": [ 319 | "
" 320 | ] 321 | }, 322 | "metadata": { 323 | "needs_background": "light" 324 | }, 325 | "output_type": "display_data" 326 | }, 327 | { 328 | "data": { 329 | "image/png": "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\n", 330 | "text/plain": [ 331 | "
" 332 | ] 333 | }, 334 | "metadata": { 335 | "needs_background": "light" 336 | }, 337 | "output_type": "display_data" 338 | } 339 | ], 340 | "source": [ 341 | "# PLOT LOSS AND ACCURACY\n", 342 | "%matplotlib inline\n", 343 | "\n", 344 | "import matplotlib.image as mpimg\n", 345 | "import matplotlib.pyplot as plt\n", 346 | "\n", 347 | "#-----------------------------------------------------------\n", 348 | "# Retrieve a list of list results on training and test data\n", 349 | "# sets for each training epoch\n", 350 | "#-----------------------------------------------------------\n", 351 | "acc=history.history['acc']\n", 352 | "val_acc=history.history['val_acc']\n", 353 | "loss=history.history['loss']\n", 354 | "val_loss=history.history['val_loss']\n", 355 | "\n", 356 | "epochs=range(len(acc)) # Get number of epochs\n", 357 | "\n", 358 | "#------------------------------------------------\n", 359 | "# Plot training and validation accuracy per epoch\n", 360 | "#------------------------------------------------\n", 361 | "plt.plot(epochs, acc, 'r', \"Training Accuracy\")\n", 362 | "plt.plot(epochs, val_acc, 'b', \"Validation Accuracy\")\n", 363 | "plt.title('Training and validation accuracy')\n", 364 | "plt.figure()\n", 365 | "\n", 366 | "#------------------------------------------------\n", 367 | "# Plot training and validation loss per epoch\n", 368 | "#------------------------------------------------\n", 369 | "plt.plot(epochs, loss, 'r', \"Training Loss\")\n", 370 | "plt.plot(epochs, val_loss, 'b', \"Validation Loss\")\n", 371 | "\n", 372 | "\n", 373 | "plt.title('Training and validation loss')\n", 374 | "\n", 375 | "# Desired output. Charts with training and validation metrics. No crash :)" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": {}, 381 | "source": [ 382 | "# Submission Instructions" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": null, 388 | "metadata": {}, 389 | "outputs": [], 390 | "source": [ 391 | "# Now click the 'Submit Assignment' button above." 392 | ] 393 | }, 394 | { 395 | "cell_type": "markdown", 396 | "metadata": {}, 397 | "source": [ 398 | "# When you're done or would like to take a break, please run the two cells below to save your work and close the Notebook. This will free up resources for your fellow learners. " 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": null, 404 | "metadata": {}, 405 | "outputs": [], 406 | "source": [ 407 | "%%javascript\n", 408 | "\n", 409 | "IPython.notebook.save_checkpoint();" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": null, 415 | "metadata": {}, 416 | "outputs": [], 417 | "source": [ 418 | "%%javascript\n", 419 | "IPython.notebook.session.delete();\n", 420 | "window.onbeforeunload = null\n", 421 | "setTimeout(function() { window.close(); }, 1000);" 422 | ] 423 | } 424 | ], 425 | "metadata": { 426 | "accelerator": "GPU", 427 | "colab": { 428 | "collapsed_sections": [], 429 | "name": "Exercise 5 - Question.ipynb", 430 | "provenance": [] 431 | }, 432 | "coursera": { 433 | "course_slug": "convolutional-neural-networks-tensorflow", 434 | "graded_item_id": "laIUG", 435 | "launcher_item_id": "jjQWM" 436 | }, 437 | "kernelspec": { 438 | "display_name": "Python 3", 439 | "language": "python", 440 | "name": "python3" 441 | }, 442 | "language_info": { 443 | "codemirror_mode": { 444 | "name": "ipython", 445 | "version": 3 446 | }, 447 | "file_extension": ".py", 448 | "mimetype": "text/x-python", 449 | "name": "python", 450 | "nbconvert_exporter": "python", 451 | "pygments_lexer": "ipython3", 452 | "version": "3.6.8" 453 | } 454 | }, 455 | "nbformat": 4, 456 | "nbformat_minor": 1 457 | } 458 | -------------------------------------------------------------------------------- /Convolutional Neural Networks in TensorFlow/utf-8''Exercise_4_Multi_class_classifier_Question-FINAL.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 91, 6 | "metadata": { 7 | "colab": {}, 8 | "colab_type": "code", 9 | "id": "wYtuKeK0dImp" 10 | }, 11 | "outputs": [], 12 | "source": [ 13 | "# ATTENTION: Please do not alter any of the provided code in the exercise. Only add your own code where indicated\n", 14 | "# ATTENTION: Please do not add or remove any cells in the exercise. The grader will check specific cells based on the cell position.\n", 15 | "# ATTENTION: Please use the provided epoch values when training.\n", 16 | "\n", 17 | "import csv\n", 18 | "import numpy as np\n", 19 | "import tensorflow as tf\n", 20 | "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 21 | "from os import getcwd" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 92, 27 | "metadata": { 28 | "colab": {}, 29 | "colab_type": "code", 30 | "id": "4kxw-_rmcnVu" 31 | }, 32 | "outputs": [ 33 | { 34 | "name": "stdout", 35 | "output_type": "stream", 36 | "text": [ 37 | "(27455, 28, 28)\n", 38 | "(27455,)\n", 39 | "(7172, 28, 28)\n", 40 | "(7172,)\n" 41 | ] 42 | } 43 | ], 44 | "source": [ 45 | "def get_data(filename):\n", 46 | " # You will need to write code that will read the file passed\n", 47 | " # into this function. The first line contains the column headers\n", 48 | " # so you should ignore it\n", 49 | " # Each successive line contians 785 comma separated values between 0 and 255\n", 50 | " # The first value is the label\n", 51 | " # The rest are the pixel values for that picture\n", 52 | " # The function will return 2 np.array types. One with all the labels\n", 53 | " # One with all the images\n", 54 | " #\n", 55 | " # Tips: \n", 56 | " # If you read a full line (as 'row') then row[0] has the label\n", 57 | " # and row[1:785] has the 784 pixel values\n", 58 | " # Take a look at np.array_split to turn the 784 pixels into 28x28\n", 59 | " # You are reading in strings, but need the values to be floats\n", 60 | " # Check out np.array().astype for a conversion\n", 61 | " images=[]\n", 62 | " labels=[]\n", 63 | " \n", 64 | " with open(filename) as training_file:\n", 65 | " rows=training_file.readlines()\n", 66 | " for i in range(1,len(rows)):\n", 67 | " image=rows[i]\n", 68 | " image=image.replace('\\n','')\n", 69 | " image=image.split(',')\n", 70 | " labels.append(int(image[0]))\n", 71 | " image=np.array(image[1:]).astype('float32')\n", 72 | " image=image.reshape((28,28))\n", 73 | " images.append(image)\n", 74 | " \n", 75 | " images=np.array(images)\n", 76 | " labels=np.array(labels)\n", 77 | " # Your code ends here\n", 78 | " return images, labels\n", 79 | "\n", 80 | "path_sign_mnist_train = f\"{getcwd()}/../tmp2/sign_mnist_train.csv\"\n", 81 | "path_sign_mnist_test = f\"{getcwd()}/../tmp2/sign_mnist_test.csv\"\n", 82 | "training_images, training_labels = get_data(path_sign_mnist_train)\n", 83 | "testing_images, testing_labels = get_data(path_sign_mnist_test)\n", 84 | "\n", 85 | "# Keep these\n", 86 | "print(training_images.shape)\n", 87 | "print(training_labels.shape)\n", 88 | "print(testing_images.shape)\n", 89 | "print(testing_labels.shape)\n", 90 | "\n", 91 | "# Their output should be:\n", 92 | "# (27455, 28, 28)\n", 93 | "# (27455,)\n", 94 | "# (7172, 28, 28)\n", 95 | "# (7172,)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 93, 101 | "metadata": { 102 | "colab": {}, 103 | "colab_type": "code", 104 | "id": "awoqRpyZdQkD" 105 | }, 106 | "outputs": [ 107 | { 108 | "name": "stdout", 109 | "output_type": "stream", 110 | "text": [ 111 | "(27455, 28, 28, 1)\n", 112 | "(7172, 28, 28, 1)\n" 113 | ] 114 | } 115 | ], 116 | "source": [ 117 | "# In this section you will have to add another dimension to the data\n", 118 | "# So, for example, if your array is (10000, 28, 28)\n", 119 | "# You will need to make it (10000, 28, 28, 1)\n", 120 | "# Hint: np.expand_dims\n", 121 | "\n", 122 | "training_images = np.expand_dims(training_images,axis=3)\n", 123 | "testing_images = np.expand_dims(testing_images,axis=3)\n", 124 | "\n", 125 | "# Create an ImageDataGenerator and do Image Augmentation\n", 126 | "train_datagen = ImageDataGenerator(\n", 127 | " rescale=1./255,\n", 128 | " width_shift_range=0.1,\n", 129 | " height_shift_range=0.1,\n", 130 | " fill_mode=\"nearest\"\n", 131 | "\n", 132 | " )\n", 133 | "\n", 134 | "validation_datagen = ImageDataGenerator(\n", 135 | " rescale=1./255)\n", 136 | " # Your Code Here)\n", 137 | " \n", 138 | "train_gen=train_datagen.flow(training_images,training_labels,batch_size=64)\n", 139 | "valid_gen=validation_datagen.flow(testing_images,testing_labels,batch_size=64)\n", 140 | "# Keep These\n", 141 | "print(training_images.shape)\n", 142 | "print(testing_images.shape)\n", 143 | " \n", 144 | "# Their output should be:\n", 145 | "# (27455, 28, 28, 1)\n", 146 | "# (7172, 28, 28, 1)" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 94, 152 | "metadata": { 153 | "colab": {}, 154 | "colab_type": "code", 155 | "id": "Rmb7S32cgRqS" 156 | }, 157 | "outputs": [ 158 | { 159 | "name": "stdout", 160 | "output_type": "stream", 161 | "text": [ 162 | "Epoch 1/2\n", 163 | "429/429 [==============================] - 40s 92ms/step - loss: 1.2976 - accuracy: 0.6094 - val_loss: 0.3843 - val_accuracy: 0.8551\n", 164 | "Epoch 2/2\n", 165 | "429/429 [==============================] - 37s 87ms/step - loss: 0.3175 - accuracy: 0.9015 - val_loss: 0.1553 - val_accuracy: 0.9536\n" 166 | ] 167 | }, 168 | { 169 | "data": { 170 | "text/plain": [ 171 | "[26.246650418587656, 0.913971]" 172 | ] 173 | }, 174 | "execution_count": 94, 175 | "metadata": {}, 176 | "output_type": "execute_result" 177 | } 178 | ], 179 | "source": [ 180 | "# Define the model\n", 181 | "# Use no more than 2 Conv2D and 2 MaxPooling2D\n", 182 | "model = tf.keras.models.Sequential([\n", 183 | " tf.keras.layers.Conv2D(32,input_shape=(28,28,1),kernel_size=(3,3),activation='relu'),\n", 184 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 185 | " \n", 186 | " tf.keras.layers.Conv2D(64,kernel_size=(3,3),activation='relu'),\n", 187 | " tf.keras.layers.MaxPooling2D(pool_size=(2,2)),\n", 188 | " tf.keras.layers.Flatten(),\n", 189 | " tf.keras.layers.Dense(1024,activation='relu'),\n", 190 | " tf.keras.layers.Dense(26,activation='softmax')]\n", 191 | " \n", 192 | " )\n", 193 | "\n", 194 | "# Compile Model. \n", 195 | "model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])\n", 196 | "\n", 197 | "# Train the Model\n", 198 | "history = model.fit_generator(train_gen,epochs=2,validation_data=valid_gen)\n", 199 | "\n", 200 | "model.evaluate(testing_images, testing_labels, verbose=0)" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 97, 206 | "metadata": { 207 | "colab": {}, 208 | "colab_type": "code", 209 | "id": "_Q3Zpr46dsij" 210 | }, 211 | "outputs": [ 212 | { 213 | "data": { 214 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEICAYAAABRSj9aAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO3dd3iUVfbA8e8hgKC0UFwpUkSkE0ooilIFgaVIUUAQQQF1BV0bi4KCYAdZZBdZUVGxUBZXBUWs+ENUhIDUIEWMEkB67yHn98d9k0xCQgaYZDKT83mePJmZ931nzjtJTu7ce99zRVUxxhgTvvIEOwBjjDFZyxK9McaEOUv0xhgT5izRG2NMmLNEb4wxYc4SvTHGhDlL9LmQiESIyBERKR/IfYNJRK4WkYDPFRaRG0Ukzuf+BhG5wZ99L+C1XheRxy/0eGMykjfYAZjMicgRn7uXAieBM979u1X1vfN5PlU9AxQK9L65gapWDcTziMhAoK+qtvB57oGBeG5j0rJEHwJUNTnRei3Ggar6VUb7i0heVU3IjtiMyYz9Pgafdd2EARF5WkRmicgMETkM9BWRa0VkiYgcEJEdIjJJRPJ5++cVERWRit79d73tn4nIYRH5UUQqne++3vb2IrJRRA6KyL9E5HsR6Z9B3P7EeLeIbBaR/SIyyefYCBH5p4jsFZEtQLtzvD8jRGRmmscmi8gE7/ZAEVnvnc+vXms7o+eKF5EW3u1LReQdL7Z1QIM0+44UkS3e864Tkc7e47WBfwM3eN1ie3ze29E+x9/jnfteEflIREr7896cz/ucFI+IfCUi+0TkTxEZ5vM6T3jvySERiRGRMul1k4nI4qSfs/d+LvJeZx8wUkSqiMhC7zX2eO9bUZ/jK3jnuNvb/rKIFPBiru6zX2kROSYiJTI6X5MOVbWvEPoC4oAb0zz2NHAK6IT7510QaAg0xn1quwrYCAzx9s8LKFDRu/8usAeIBvIBs4B3L2Dfy4HDQBdv20PAaaB/BufiT4wfA0WBisC+pHMHhgDrgHJACWCR+3VO93WuAo4Al/k89y4g2rvfydtHgFbAcaCOt+1GIM7nueKBFt7t8cC3QCRQAYhNs++tQGnvZ3KbF8NfvG0DgW/TxPkuMNq73daLsS5QAHgF+Maf9+Y83+eiwE7gAeASoAjQyNv2GLAKqOKdQ12gOHB12vcaWJz0c/bOLQG4F4jA/T5eA7QG8nu/J98D433OZ633fl7m7d/U2zYVeMbndR4GPgz232GofQU9APs6zx9Yxon+m0yOewT4r3c7veT9H599OwNrL2DfO4HvfLYJsIMMEr2fMTbx2f4/4BHv9iJcF1bStg5pk0+a514C3Obdbg9sOMe+nwD3ebfPlej/8P1ZAH/z3Ted510L/NW7nVmifxt41mdbEdy4TLnM3pvzfJ9vB5ZlsN+vSfGmedyfRL8lkxh6JL0ucAPwJxCRzn5Ngd8A8e6vBLoF+u8q3L+s6yZ8bPW9IyLVRORT76P4IWAMUPIcx//pc/sY5x6AzWjfMr5xqPvLjM/oSfyM0a/XAn4/R7wA7wO9vdu3efeT4ugoIj953QoHcK3pc71XSUqfKwYR6S8iq7zuhwNANT+fF9z5JT+fqh4C9gNlffbx62eWyft8JS6hp+dc2zKT9vfxChGZLSLbvBjeShNDnLqB/1RU9Xvcp4PrRaQWUB749AJjyrUs0YePtFMLX8W1IK9W1SLAk7gWdlbagWtxAiAiQurElNbFxLgDlyCSZDb9czZwo4iUxXUtve/FWBCYAzyH61YpBnzhZxx/ZhSDiFwFTMF1X5TwnvcXn+fNbCrodlx3UNLzFcZ1EW3zI660zvU+bwUqZ3BcRtuOejFd6vPYFWn2SXt+L+Bmi9X2YuifJoYKIhKRQRzTgb64Tx+zVfVkBvuZDFiiD1+FgYPAUW8w6+5seM1PgPoi0klE8uL6fUtlUYyzgb+LSFlvYO4f59pZVf/EdS+8heu22eRtugTXb7wbOCMiHXF9yf7G8LiIFBN3ncEQn22FcMluN+5/3iBciz7JTqCc76BoGjOAu0SkjohcgvtH9J2qZvgJ6RzO9T7PBcqLyBARuUREiohII2/b68DTIlJZnLoiUhz3D+5P3KB/hIgMxuef0jliOAocFJErcd1HSX4E9gLPihvgLigiTX22v4Pr6rkNl/TNebJEH74eBu7ADY6+ihs0zVKquhPoCUzA/eFWBn7GteQCHeMU4GtgDbAM1yrPzPu4PvfkbhtVPQA8CHyIG9DsgfuH5Y9RuE8WccBn+CQhVV0N/AtY6u1TFfjJ59gvgU3AThHx7YJJOn4BrovlQ+/48kAfP+NKK8P3WVUPAm2A7rh/PhuB5t7mccBHuPf5EG5gtIDXJTcIeBw3MH91mnNLzyigEe4fzlzgA58YEoCOQHVc6/4P3M8haXsc7ud8UlV/OM9zN6QMcBgTcN5H8e1AD1X9LtjxmNAlItNxA7yjgx1LKLILpkxAiUg73AyX47jpeadxrVpjLog33tEFqB3sWEKVdd2YQLse2ILrm74J6GqDZ+ZCichzuLn8z6rqH8GOJ1RZ140xxoQ5a9EbY0yYy3F99CVLltSKFSsGOwxjjAkpy5cv36Oq6U5nznGJvmLFisTExAQ7DGOMCSkikuHV4dZ1Y4wxYc4SvTHGhDlL9MYYE+ZyXB99ek6fPk18fDwnTpwIdigmBylQoADlypUjX76MysUYYyBEEn18fDyFCxemYsWKuIKIJrdTVfbu3Ut8fDyVKlXK/ABjcrGQ6Lo5ceIEJUqUsCRvkokIJUqUsE95xvghJBI9YEnenMV+J4zxj1+JXkTaicgGbyHi4elsryAiX4vIahH5VkR8F584IyIrva+5gQzeGGNC3aFDsHgx/PvfMHVq1rxGpn30XqnZybia1fHAMhGZq6qxPruNB6ar6tsi0gq3SMLt3rbjqlo3wHFnq71799K6tVuL4s8//yQiIoJSpdwFaEuXLiV//vyZPseAAQMYPnw4VatWzXCfyZMnU6xYMfr0udCy48aYnEoV/vgDVq6EVatSvm/ZkrLPtdfC4MGBf21/BmMbAZtVdQuAiMzElQz1TfQ1gIe82wtxixWEjRIlSrBy5UoARo8eTaFChXjkkUdS7ZO8CG+e9D8kvfnmm5m+zn333XfxwWazhIQE8uYNiTF9Y7LNyZMQG3t2Uj9wwG0XgSpVIDoa7roL6tZ1X6VLZ008/nTdlCX1Qr/xnL0O6Cqgm3e7K1DYW94NoICIxIjIEhG5Ob0XEJHB3j4xu3fvPo/wg2vz5s3UqFGDPn36ULNmTXbs2MHgwYOJjo6mZs2ajBkzJnnf66+/npUrV5KQkECxYsUYPnw4UVFRXHvttezatQuAkSNHMnHixOT9hw8fTqNGjahatSo//OAW1jl69Cjdu3enRo0a9OjRg+jo6OR/Qr5GjRpFw4YNqVWrFvfccw9JVUo3btxIq1atiIqKon79+sTFxQHw7LPPUrt2baKiohgxYkSqmMF9krn66qsBeP3117n55ptp2bIlN910E4cOHaJVq1bUr1+fOnXq8MknKQs0vfnmm9SpU4eoqCgGDBjAwYMHueqqq0hISABg//79qe4bE2r27IGvvoKXXoLbb4c6daBQIahfH+68E157zSX+Xr3gP/+BH3+Ew4dhwwaYNQsefxw6dIAyZdw/gKwQqKbYI8C/RaQ/sAi3gHHSiu4VVHWbt3jANyKyRlVTrSyvqlNxy5QRHR197rrJf/+7+/cYSHXrgpdgz9cvv/zC9OnTiY6OBuD555+nePHiJCQk0LJlS3r06EGNGjVSHXPw4EGaN2/O888/z0MPPcS0adMYPvysoQ9UlaVLlzJ37lzGjBnDggUL+Ne//sUVV1zBBx98wKpVq6hfv366cT3wwAM89dRTqCq33XYbCxYsoH379vTu3ZvRo0fTqVMnTpw4QWJiIvPmzeOzzz5j6dKlFCxYkH379mV63j///DMrV64kMjKS06dP89FHH1GkSBF27dpF06ZN6dixI6tWreKFF17ghx9+oHjx4uzbt4+iRYvStGlTFixYQMeOHZkxYwa33HKLfSowOd6ZM/Drr2e30rf5LNdetqxLJ506ue9RUVC5MkRktOx5NvHnr2sbqVe6L0ealehVdTtei15ECgHdvbU4UdVt3vctIvItUA9IlehDWeXKlZOTPMCMGTN44403SEhIYPv27cTGxp6V6AsWLEj79u0BaNCgAd99l/4qe926dUveJ6nlvXjxYv7xD7cOdlRUFDVr1kz32K+//ppx48Zx4sQJ9uzZQ4MGDWjSpAl79uyhU6dOgLvgCOCrr77izjvvpGDBggAUL1480/Nu27YtkZGRgPuHNHz4cBYvXkyePHnYunUre/bs4ZtvvqFnz57Jz5f0feDAgUyaNImOHTvy5ptv8s4772T6esZkp6NHYc0al8yTEvrq1XDsmNueNy9Urw6tWrlknpTUS5YMbtwZ8SfRLwOqiEglXILvhVuNPZmIlAT2qWoibvm4ad7jkcAxVT3p7dMUePGiIr7AlndWueyyy5Jvb9q0iZdffpmlS5dSrFgx+vbtm+48b9/B24iIiAy7LS655JJM90nPsWPHGDJkCCtWrKBs2bKMHDnyguab582bl8TERICzjvc97+nTp3Pw4EFWrFhB3rx5KVeu3Dlfr3nz5gwZMoSFCxeSL18+qlWrdt6xGRMIqrB9+9mt9E2b3DaAYsVcIh80KCWh16gB3p9nSMi0j95boX0I8DmwHpitqutEZIyIdPZ2awFsEJGNwF+AZ7zHqwMxIrIKN0j7fJrZOmHl0KFDFC5cmCJFirBjxw4+//zzgL9G06ZNmT17NgBr1qwhNvbst/P48ePkyZOHkiVLcvjwYT744AMAIiMjKVWqFPPmzQNc8j527Bht2rRh2rRpHD9+HCC566ZixYosX74cgDlz5mQY08GDB7n88svJmzcvX375Jdu8z7KtWrVi1qxZyc/n2yXUt29f+vTpw4ABAy7q/TDGX6dPu1b6O+/Aww/DjTdCqVJQrhx07AgjRsDy5VCrFoweDR9/DHFxsG8fLFzo2pj9+0O9eqGV5MHPPnpVnQ/MT/PYkz635wBnZQJV/YFctKBv/fr1qVGjBtWqVaNChQo0bdo04K8xdOhQ+vXrR40aNZK/ihYtmmqfEiVKcMcdd1CjRg1Kly5N48aNk7e999573H333YwYMYL8+fPzwQcfJPenR0dHky9fPjp16sTYsWN59NFH6dmzJ1OmTEnuakrP7bffTqdOnahduzaNGjWiSpUqgOtaGjZsGM2aNSNv3rw0aNCAN954A4A+ffowZswYevbsGfD3yJj9+13L3LeVvm4dnDrlthcoALVrQ9euKa30OnWgSJHgxp1VctyasdHR0Zp24ZH169dTvXr1IEWUsyQkJJCQkECBAgXYtGkTbdu2ZdOmTSE3mDlz5kw+//xzv6adnov9buRuiYmu1e3b9bJypZuvnuQvf0lJ5knfr7nG9bOHExFZrqrR6W0Ls1MNf0eOHKF169YkJCSgqrz66qshl+TvvfdevvrqKxYsWBDsUEwIOX4c1q5N3UpftcpNVQTIkweqVoWmTeG++1xCj4qCK64Ibtw5QWhlCEOxYsWS+81D1ZQpU4Idgsnhdu5MPeNl5Uo379ybG0Dhwi6J9+uX0kqvVQu8iWMmDUv0xpigSUiAjRtTt9JXrnSJPkn58i6Z9+iRcgVpxYquBW/8Y4neGJMtDh1yc9F9k/qaNZA0EzdfPtcqb98+pZUeFQXe5RrmIliiN8YElCps3Xp214tv8a4SJVwy/9vfUpJ6tWrgR31AcwEs0RtjLlhS8a60XS9pi3c1aOCKdyXNfMnKui7mbNbL5YeWLVuedfHTxIkTuffee895XKFChQDYvn07PXr0SHefFi1akHY6aVoTJ07kWNK110CHDh04kPSXZEw22bMHvv7aFe/q1y918a4BA1zxrhMnoGdPmDIFfvjBddds2ACzZ7viXX/9q6sHY0k+e1mL3g+9e/dm5syZ3HTTTcmPzZw5kxdf9K+aQ5kyZc55ZWlmJk6cSN++fbn00ksBmD9/fiZH5CyZlXA2OUtiImzefHYr3bd4V5kyKcW7klrpOaF4l0mf/eX5oUePHnz66aec8i6ri4uLY/v27dxwww3J89rr169P7dq1+fjjj886Pi4ujlq1agGuPEGvXr2oXr06Xbt2TS47AG5+eVKJ41GjRgEwadIktm/fTsuWLWnZsiXgShPs2bMHgAkTJlCrVi1q1aqVXOI4Li6O6tWrM2jQIGrWrEnbtm1TvU6SefPm0bhxY+rVq8eNN97ITm+qw5EjRxgwYAC1a9emTp06ySUUFixYQP369YmKikpeiGX06NGMHz8++Tlr1apFXFwccXFxVK1alX79+lGrVi22bt2a7vkBLFu2jOuuu46oqCgaNWrE4cOHadasWaryy9dffz2rVq06r5+bydzRo7BkCbz6Ktx7r1v4okgRNx/91lvhhRfcxUctW8L48fDll7Brl0v6n34Kzzzj9rvmGkvyOVnIteiDUaW4ePHiNGrUiM8++4wuXbowc+ZMbr31VkSEAgUK8OGHH1KkSBH27NlDkyZN6Ny5c4brmU6ZMoVLL72U9evXs3r16lRlhp955hmKFy/OmTNnaN26NatXr+b+++9nwoQJLFy4kJJpSuMtX76cN998k59++glVpXHjxjRv3pzIyEg2bdrEjBkzeO2117j11lv54IMP6Nu3b6rjr7/+epYsWYKI8Prrr/Piiy/y0ksvMXbsWIoWLcqaNWsAVzN+9+7dDBo0iEWLFlGpUiW/Shlv2rSJt99+myZNmmR4ftWqVaNnz57MmjWLhg0bcujQIQoWLMhdd93FW2+9xcSJE9m4cSMnTpwgKioq09c06Usq3pW2le5bvKtoUfe3kLQQRlLxLq/IqQlhIZfogyWp+yYp0SfVbFFVHn/8cRYtWkSePHnYtm0bO3fu5IoMLsdbtGgR999/PwB16tShTp06ydtmz57N1KlTSUhIYMeOHcTGxqbantbixYvp2rVrciXJbt268d1339G5c2cqVapE3bpuBUffMse+4uPj6dmzJzt27ODUqVNUqlQJcGWLZ86cmbxfZGQk8+bNo1mzZsn7+FPKuEKFCslJPqPzExFKly5Nw4YNASjiFRu55ZZbGDt2LOPGjWPatGn0798/09czzunT8MsvqUsCrFrl+tiTVKrkknmfPildL+XLW995uAq5RB+sKsVdunThwQcfZMWKFRw7dowGDRoArkjY7t27Wb58Ofny5aNixYoXVBL4t99+Y/z48SxbtozIyEj69+9/Qc+T5BKf8noRERHpdt0MHTqUhx56iM6dO/Ptt98yevTo834d31LGkLqcsW8p4/M9v0svvZQ2bdrw8ccfM3v27JC/GjirHDhwdivdt3jXJZe44l1duqQu3pWmDp4Jc9ZH76dChQrRsmVL7rzzTnr37p38eFKJ3nz58rFw4UJ+//33cz5Ps2bNeP/99wFYu3Ytq1evBlyJ48suu4yiRYuyc+dOPvvss+RjChcuzOGkgh4+brjhBj766COOHTvG0aNH+fDDD7nhhhv8PqeDBw9StqxbFfLtt99OfrxNmzZMnjw5+f7+/ftp0qQJixYt4rfffgNSlzJesWIFACtWrEjenlZG51e1alV27NjBsmXLADh8+HBy7f2BAwdy//3307Bhw+RFTnIrVTcP/cMPYdQouPlmd3VoZCS0aOG6ND/91JXd/fvf4b33XMI/cgSWLYPXX4chQ+CGGyzJ50Yh16IPpt69e9O1a9dU3Rp9+vRJLtEbHR2d6SIa9957LwMGDKB69epUr149+ZNBVFQU9erVo1q1alx55ZWpShwPHjyYdu3aUaZMGRYuXJj8eP369enfvz+NGjUCXGKsV69eut006Rk9ejS33HILkZGRtGrVKjlJjxw5kvvuu49atWoRERHBqFGj6NatG1OnTqVbt24kJiZy+eWX8+WXX9K9e3emT59OzZo1ady4Mddcc026r5XR+eXPn59Zs2YxdOhQjh8/TsGCBfnqq68oVKgQDRo0oEiRIrmuZv3x4y5J+7bSV692UxUhpXjXtde6AdSkrhcr3mUyYmWKTY61fft2WrRowS+//JLh1MxQ/93YufPsrpcNG9z6pODmqSeVAkiq81KzJngzbY1JZmWKTciZPn06I0aMYMKECWEx//7MGVe8K+2SdX/+mbJP+fIuoXfvnpLYK1Wy4l3m4lmiNzlSv3796NevX7DDuCCHD7uuFt+kvnat65IBV7yrZk246abUxbv8mMhkzAUJmUSvqhnOTTe5U7C7HZOKd6Wdxvjrryn7FC/ukrlvX7oV7zLZLSQSfYECBdi7dy8lSpSwZG8Al+T37t1LgWy6mufUKVe8K23Xy/79KftUqeIWjh4wICWpW10XkxP4lehFpB3wMhABvK6qz6fZXgGYBpQC9gF9VTXe23YHMNLb9WlVfZvzVK5cOeLj49m9e/f5HmrCWIECBShXrlzAn3fv3rNb6bGxbpEMcKsY1akDt9ySMkBau7YbODUmJ8o00YtIBDAZaAPEA8tEZK6qxvrsNh6Yrqpvi0gr4DngdhEpDowCogEFlnvH7uc85MuXL/mKTGMCJTHRdbOkbaXHx6fsU6aMa53/9a8prfSrr7a6LibATp92BYeOHIHhwwP+9P606BsBm1V1C4CIzAS6AL6JvgbwkHd7IfCRd/sm4EtV3ecd+yXQDphx8aEb47+jR92AaNq56UePuu0REVC9OjRvntJKj4pyFyAZk2VU3VVww4e7wkMdOsA//hHw/j5/En1ZYKvP/XigcZp9VgHdcN07XYHCIlIig2PLpn0BERkMDAYoX768v7EbcxZV2LHj7Fb6xo2pi3dFRaVeCMOKd5ls9+OP8Oij8P337hfw00/dOopZMKgTqMHYR4B/i0h/YBGwDTjj78GqOhWYCu6CqQDFZMLc6dPu4qK0Sd13KKdSJZfMe/dOSeoVKtgAqQmizZvhscdgzhx3OfPUqW4EP2/WzY3x55m3AVf63C/nPZZMVbfjWvSISCGgu6oeEJFtQIs0x357EfGaXCqpeJdvQl+7NnXxrlq13EIYSV0vVrzL5Ch79sDYsW75rfz5YfRoePjhbBnF9yfRLwOqiEglXILvBdzmu4OIlAT2qWoi8BhuBg7A58CzIpJUkaqtt92YdKlCXNzZrXTf8j2lSrlE/sADKa30qlWztEFkzIU7cQImTYJnn3VX0w0c6JJ86dLZFkKmfxqqmiAiQ3BJOwKYpqrrRGQMEKOqc3Gt9udERHFdN/d5x+4TkbG4fxYAY5IGZo05cSKleFdSQl+1KqV4l4hL4I0bw913py7eZV0vJsdLTIT334cRI9wyXR07wvPPu8uis1lIFDUzoW/XrrNb6b/8krp4V506KbNd6tZ1XTFWvMuEpG++cQOtK1a41dPHj3frMWYhK2pmss2ZM26WmG8rfeXK1MW7rrzSJfOuXVOS+lVXWfEuEwbWrYNhw2D+fFel7t133UyAIP9yW6I3FyypeJdvK33NmtTFu2rUcMW7khJ6nTpQokRw4zYm4HbsgCefhGnToHBhePFFGDo0x8zZtURvMqXqrhb1baGvXHl28a6oKLjnnpSkXr26Fe8yYe7IEdctM26cm+97//0wcmSOa81YojepJBXvSrsYhm/xrquvdom8f/+UPvVy5WyA1OQiCQmu9T5qlOuXvPVWN6umcuVgR5YuS/S5WFLxLt+kHhvrGibginfVru2KdyW10mvXdp9MjcmVVN0VrMOGwfr10LSpK2HQpEmwIzsnS/S5QFLxrrStdN/iXaVLu2Tevn1KUq9SxYp3GZNs+XJ45BH49lv3x/G//7lV2kPgo6wl+jBz7JgbEPVN6qtXu65EcIm7WjVo1ix18a7LLw9u3MbkWHFxrt/9vfegZEn4979h8GA32yBEWKIPUaquazDtNMZNm1wLHqBIEZfEfRfCqFkzx0wEMCZnO3DA9btPmuRa7Y8/7ipLFikS7MjOmyX6EJBUvCtt14tv8a6KFV0i79UrpZVesWJIfKo0Jmc5dQpeecXVpdm/H+64w93OgkVusosl+hzm4MGzE/q6dXDypNueP39K8S7fuenFigU3bmNCnir897+usuSWLdCmjZs2GRUV7MgumiX6IEkq3pU2qfsW7ypZ0iXyoUNTWulVq4ZU16AxoWHxYjfQ+tNPbmrZggXuSr8wYYk+GyQV7/K92Gj1atd6B9e9cs01rnjX4MEpSb10aet6MSZLbdzo+t0/+sitGzltGvTrF3bTzSzRB9iuXWe30n2Ld112metque221MW7LrssuHEbk6vs3g1PPeXWaS1QAJ5+Gh58MGyr6Fmiv0BJxbt8W+mrVrmSF0nKlXPJ/OabU1rplSsHvb6RMbnXsWMwcaIrF3zsmKt/PWpU2M8vtkTvh8OH3dx031a6b/GuvHld8a42bVJa6VFROa7chTG515kz8M47bj78tm3QpYtL9tWqBTuybGGJ3kdS8a60XS+bN6fsExnpkrjvQhjVq7ul7IwxOdAXX7iSBatWQaNGMGMG3HBDsKPKVrk20Z865UpVpF0MY5/P+leVK7tE3q9fSiv9yittgNSYkLB6tVv844sv3CrxM2e64mO58A84VyT6ffvObqX7Fu8qUMDNqOrePXXxrhC8AM4Ys20bPPEEvPWWu8BkwgT4299y9cfusEr0iYnuOoe0rfStW1P2ueIKl8jbtUtppVepYgtLGxPyDh1yC35MmOD65B9+2JUtiIwMdmRBFzbpbetWNyDqW7yralXXFec7QPqXvwQ3TmNMgJ0+Da+9BqNHu2mTvXvDM8+47hoD+JnoRaQd8DIQAbyuqs+n2V4eeBso5u0zXFXni0hFYD2wwdt1iareE5jQUytTBu6803W5JBXvKlgwK17JGJMjqMLHH8Pw4a4YVPPmbrWn6HTXx87VMk30IhIBTAbaAPHAMhGZq6qxPruNBGar6hQRqQHMByp6235V1bqBDftsERHw8stZ/SrGmBzhp5/cQOt337kpknPnQseOuXKg1R/+XJk8OV4AABmKSURBVLrTCNisqltU9RQwE+iSZh8FkoYuiwLbAxeiMcZ4tmxxJVqbNHHlC/7zH3dRS6dOluTPwZ9EXxbwGc4k3nvM12igr4jE41rzQ322VRKRn0Xk/0Qk3cmrIjJYRGJEJGa3b+1dY4wBN3XuoYdc633ePDerZtMmd0GLzaTIVKAuxu8NvKWq5YAOwDsikgfYAZRX1XrAQ8D7InLWpEVVnaqq0aoaXapUqQCFZIwJeSdOuH73ypVd32y/fi7BjxljixefB38S/TbgSp/75bzHfN0FzAZQ1R+BAkBJVT2pqnu9x5cDvwLXXGzQxpgwl5gI77/vWvCPPgrXXuvmSr/+upt5Yc6LP4l+GVBFRCqJSH6gFzA3zT5/AK0BRKQ6LtHvFpFS3mAuInIVUAXYEqjgjTFh6P/+z9Xs7tPHzYH/6iuYP9+VeTUXJNNEr6oJwBDgc9xUydmquk5ExohIZ2+3h4FBIrIKmAH0V1UFmgGrRWQlMAe4R1X3nf0qxphcb/166NwZWrSAnTth+nRYvhxatw52ZCFPXD7OOaKjozUmJibYYRhjssuff7qLnV5/3S3M8Nhj8MADdiHMeRKR5aqa7kUENlxtjAmOo0fhpZdc2YKTJ109mieeAJuQEXCW6I0x2evMGXjzTXjySbdST/fu8NxzruiUyRKW6I0x2UPVLbo9bBisXetm0syZA9ddF+zIwp4tameMyXo//+yWYOvQwc2NnzMHvv/eknw2sURvjMk6f/zhLnJq0MDVDX/5ZVi3znXXWMmCbGNdN8aYwDt40PW7T5zo7g8b5mbTFC0a3LhyKUv0xpjAOXXKFRobMwb27oXbb4enn4by5YMdWa5mXTfGmIun6vrda9Z0c+Dr1oUVK9xFT5bkg84SvTHm4vzwAzRtCrfc4tZlnT8fvvwS6tULdmTGY4neGHNhNm+GHj1cko+Lc8v5rVwJ7dvbQGsOY4neGHN+9uyB+++H6tXdvPinnnKlgwcOtNrwOZT9VIwx/jl+HCZNgmefhSNHYNAgV6PmiiuCHZnJhCV6Y8y5JSbCe+/BiBGwdatbtu+FF1yL3oQE67oxxmTs668hOtpd9HT55bBwoVuI25J8SLFEb4w529q1rlzBjTe69Vrfew+WLnW14k3IsURvjEmxfbsbVI2Kgh9/hHHj4Jdf4LbbII+li1BlffTGGDe4Om6cW4j79Gl30dOIEVCiRLAjMwFgid6Y3CwhAd54A0aNcsv39ezpZtVcdVWwIzMBZInemNxIFT75BP7xD7dW6/XXw8cfu0W5Tdjxq9NNRNqJyAYR2Swiw9PZXl5EForIzyKyWkQ6+Gx7zDtug4jcFMjgjTEXICYGWrZ0C3GfOQMffgiLFlmSD2OZJnoRiQAmA+2BGkBvEamRZreRwGxVrQf0Al7xjq3h3a8JtANe8Z7PGJPd4uLcoGrDhhAbC5Mnu9k1N99sJQvCnD8t+kbAZlXdoqqngJlAlzT7KFDEu10U2O7d7gLMVNWTqvobsNl7PmNMdtm/Hx55BKpWhY8+coOsmze7xbjz5Qt2dCYb+NNHXxbY6nM/Hkj7GW808IWIDAUuA270OXZJmmPLpn0BERkMDAYobyVNjQmMkyfhlVdg7Fg4cAD693d14suVC3ZkJpsFamJsb+AtVS0HdADeERG/n1tVp6pqtKpGlypVKkAhGZNLqcKsWe7q1YcegkaNXFXJadMsyedS/iTjbcCVPvfLeY/5uguYDaCqPwIFgJJ+HmuMCZTvvoMmTaBXLyhcGD7/3FWYrFMn2JGZIPIn0S8DqohIJRHJjxtcnZtmnz+A1gAiUh2X6Hd7+/USkUtEpBJQBVgaqOCNMZ4NG9ygarNmsG0bvPmmW+GpbdtgR2ZygEz76FU1QUSGAJ8DEcA0VV0nImOAGFWdCzwMvCYiD+IGZvurqgLrRGQ2EAskAPep6pmsOhljcp1du1yp4KlT4dJL4Zln4O9/d7eN8YjLxzlHdHS0xsTEBDsMY3K2Y8fgn/+E5593deLvuQeefNJVmDS5kogsV9Xo9LbZlbHGhJIzZ9yC20884bpounaF555zUyeNyYCVozMmVHz+uVtw+8473eyZ776D//3PkrzJlCV6Y3K6VavcoGq7dnD0qJs6+eOPrj6NMX6wRG9MThUf7y5yqlcPli93ffKxsXDrrVaywJwX66M3Jqc5dMityTphgluv9ZFH4LHHIDIy2JGZEGWJ3pic4vRpN03yqadg925XgOyZZ6BixWBHZkKcdd0YE2yqrlRwrVowZAjUrAnLlrl1Wi3JmwCwRG9MMC1Z4q5m7dYNIiJg3jz45huITnc6tDEXxBK9McHw669uUPXaa2HTJnj1VVi9Gjp2tIFWE3DWR29Mdtq7F55+2i36kS+fW6v1kUegUKFgR2bCmCV6Y7LDiRPwr3+5wdXDh91FT089BWXKBDsykwtYojcmKyUmwowZblWn33+HDh3gxRfdgKsx2cT66I3JKgsXukU/+vaF4sXh66/h008tyZtsZ4nemECLjXWDqq1aufnw77wDMTHuvjFBYInemEDZsQPuvhtq14bFi93VrRs2uBZ9HvtTM8FjffTGXKwjR+Cll2DcOLcg99ChMHIklCwZ7MiMASzRG3PhEhLckn1PPgl//gk9erja8FdfHezIjEnFEr0x50sV5s+Hf/wD1q2D665zdeGvvTbYkRmTLus4NOZ8rFgBrVu7wdaTJ+GDD1x/vCV5k4NZojfGH7//DrffDg0awJo17uKn2FhXo8ZKFpgczq9ELyLtRGSDiGwWkeHpbP+niKz0vjaKyAGfbWd8ts0NZPDGZLkDB1wXTdWqMGcODB8Omze7KpP58gU7OmP8kmkfvYhEAJOBNkA8sExE5qpqbNI+qvqgz/5DgXo+T3FcVesGLmRjssGpUzBlCowdC/v2udb800/DlVcGOzJjzps/LfpGwGZV3aKqp4CZQJdz7N8bmBGI4IzJdqrw3/9CjRrw97+nLOP39tuW5E3I8ifRlwW2+tyP9x47i4hUACoB3/g8XEBEYkRkiYjcnMFxg719Ynbv3u1n6MYE2A8/QNOmrnxwwYLw2WfwxRcu2RsTwgI9GNsLmKOqZ3weq6Cq0cBtwEQRqZz2IFWdqqrRqhpdqlSpAIdkTCY2bYLu3V2Sj4uD11+HlSuhXTsbaDVhwZ9Evw3w/cxaznssPb1I022jqtu871uAb0ndf29M8Oze7a5irVHDtdzHjHFJ/6673GpPxoQJfxL9MqCKiFQSkfy4ZH7W7BkRqQZEAj/6PBYpIpd4t0sCTYHYtMcak62OH0+5gnXKFBg40M2keeIJuOyyYEdnTMBlOutGVRNEZAjwORABTFPVdSIyBohR1aSk3wuYqarqc3h14FURScT9U3ned7aOMdkqMdFVkhw5EuLjoXNnV3isWrVgR2ZMlpLUeTn4oqOjNSYmJthhmHDz5Zfw6KOwahU0bOgKkDVvHuyojAkYEVnujYeexa6MNeFtzRpo3x7atoWDB+H992HJEkvyJlexRG/C07ZtblC1bl2X2MePh19+gd69rTa8yXWseqUJL4cPuzVZX3oJzpxxFz2NGOGW8jMml7JEb8JDQgK89hqMHg27dkGvXvDss1CpUrAjMyboLNGb0KYKc+e6wmMbNkCzZjBvnluU2xgDWB+9CWXLlkGLFnCzV1nj44/h228tyRuThiV6E3p++80NqjZq5AZYX3nFza7p3NlKFhiTDuu6MaFj3z545hn4979diYKRI2HYMChcONiRGZOjWaI3Od/Jky65P/OMWwhkwABXl6ZsukVUjTFpWNeNybkSE2HGDFei4JFHoHFjd2XrG29YkjfmPFiiNznTokXQpAncdhsULeqqS372GdSuHezIjAk5luhNzvLLL9CliytRsGMHvPWWW+GpTZtgR2ZMyLJEb3KGnTvh3nuhVi1YuNBd7LRxI9xxh9WGN+Yi2WCsCa5jx2DCBFcu+MQJl+yffBJspTFjAsYSvQmOM2fcgttPPAHbt0O3bm4xkGuuCXZkxoQd67ox2UsVFixwC27fdReULw+LF8MHH1iSNyaLWKI32WflSlcXvn1712Uzezb88INblNsYk2Us0Zust3WrG1StXx9WrICJEyE2Fm65xUoWGJMNrI/eZJ2DB+H5511iV3VL+T32GBQrFuzIjMlVLNGbwDt9Gl59FZ56Cvbsgb594emnoUKFYEdmTK7kV9eNiLQTkQ0isllEhqez/Z8istL72igiB3y23SEim7yvOwIZvMlhVOF//4OaNWHoUHcVa0wMvPOOJXljgijTFr2IRACTgTZAPLBMROaqamzSPqr6oM/+Q4F63u3iwCggGlBguXfs/oCehQm+H390XTPffw81asAnn0CHDtYHb0wO4E+LvhGwWVW3qOopYCbQ5Rz79wZmeLdvAr5U1X1ecv8SaHcxAZscZvNmN6h63XXw668wdaorPPbXv1qSNyaH8CfRlwW2+tyP9x47i4hUACoB35zPsSIyWERiRCRm9+7d/sRtgm3PHnjgAdd6nz/frdW6aRMMGgR5bejHmJwk0NMrewFzVPXM+RykqlNVNVpVo0vZpe8524kT8OKLcPXVrkZ8//6uVT9qFBQqFOzojDHp8CfRbwOu9LlfznssPb1I6bY532NNTpaYCO++C1WruoW4r78eVq92XTWlSwc7OmPMOfiT6JcBVUSkkojkxyXzuWl3EpFqQCTwo8/DnwNtRSRSRCKBtt5jJpR88w00bAi33w4lS7r7n3ziZtcYY3K8TBO9qiYAQ3AJej0wW1XXicgYEenss2svYKaqqs+x+4CxuH8Wy4Ax3mMmFKxb5wZVW7d2ffLvvgvLlkHLlsGOzBhzHsQnL+cI0dHRGhMTE+wwcrcdO1yp4GnT3MLbI0a4efEFCgQ7MmNMBkRkuapGp7fNpkeYFEeOwPjxMG6cu7r1/vth5EgoUSLYkRljLoIlegMJCa71PmoU/Pmnmxf/3HNQuXKwIzPGBIAl+txMFT79FIYNg/XrXbngDz90i3IbY8KGlSnOrZYvh1atoFMn16L/3//gu+8syRsThizR5zZxcdCnD0RHw9q17qKndeuga1crWWBMmLKum9ziwAF49lmYNMkl9Mcfdxc+FSkS7MiMMVnMEn24O3UKXnkFxo6F/fuhXz93+8orMz/WGBMWrOsmXKm6NVmrV4cHH4QGDeDnn+GttyzJG5PLWKIPR4sXw7XXQs+ecNllsGABfPEFREUFOzJjTBBYog8nGze6QdUbbnALck+b5lrxN90U7MiMMUFkiT4c7NoF993nasN/9ZVbn3XTJhgwACIigh2dMSbIbDA2lB07BhMnwvPPu9uDB7urW//yl2BHZozJQSzRh6IzZ9yC2yNHwrZt0KWLS/bVqgU7MmNMDmRdN6Hmiy/cDJoBA6BMGfi//4OPPrIkb4zJkCX6ULF6tRtUvekmOHQIZsyAJUugWbNgR2aMyeEs0ed027bBnXdC3bpu0Y+XXnIFyHr1gjz24zPGZM766HOqQ4fcItwTJrg++YcecguAREYGOzJjTIixRJ/TnD4Nr70Go0fD7t3Quzc88wxUqhTsyIwxIco+++cUqm5QtVatlDnxS5fC++9bkjfGXBS/Er2ItBORDSKyWUSGZ7DPrSISKyLrROR9n8fPiMhK72tuoAIPKz/9BM2bu6ta8+SBuXNh4UJo2DDYkRljwkCmXTciEgFMBtoA8cAyEZmrqrE++1QBHgOaqup+Ebnc5ymOq2rdAMcdHrZsceWCZ82Cyy+HKVNg4EDIaz1qxpjA8adF3wjYrKpbVPUUMBPokmafQcBkVd0PoKq7AhtmmNm3zw2uVqsG8+bBE0/A5s1wzz2W5I0xAedPoi8LbPW5H+895usa4BoR+V5ElohIO59tBUQkxnv85ouMN7SdOAHjx7tFt19+2dWG37QJxoyBwoWDHZ0xJkwFqvmYF6gCtADKAYtEpLaqHgAqqOo2EbkK+EZE1qjqr74Hi8hgYDBA+fLlAxRSDpKYCDNnum6a33+H9u3hhRegdu1gR2aMyQX8adFvA3xXqijnPeYrHpirqqdV9TdgIy7xo6rbvO9bgG+BemlfQFWnqmq0qkaXKlXqvE8iR/v2W2jc2K3TGhnpqkvOn29J3hiTbfxJ9MuAKiJSSUTyA72AtLNnPsK15hGRkriunC0iEikil/g83hSIJTdYvx46dYKWLWHnTnj7bVi+HFq3DnZkxphcJtNEr6oJwBDgc2A9MFtV14nIGBHp7O32ObBXRGKBhcCjqroXqA7EiMgq7/HnfWfrhKU//3SDqrVrw6JF8NxzsGGD64+3kgXGmCAQVQ12DKlER0drTExMsMM4f0ePujo0L74IJ0/Cvfe62TTh1hVljMmRRGS5qkant83m8l2sM2fgzTfhySdhxw7o3t214qtUCXZkxhgDWKK/cKrw2WcwbBisW+cW454zB667LtiRGWNMKtZpfCF+/hnatIG//tXNjf/vf+H77y3JG2NyJEv05+OPP9ygaoMGsHKlu+gpNhZ69ACRYEdnjDHpsq4bfxw86PrdJ05094cNg+HDoVix4MZljDF+sER/LqdOwX/+40oU7N0Lt98OTz8N4Xj1rjEmbFnXTXpU3cBqzZrwwAMQFeUudpo+3ZK8MSbkWKJP64cfoGlTuOUWuOQS+PRTV7agfv1gR2aMMRfEEn2STZvcoGrTphAX55bzW7kSOnSwgVZjTEizPvo9e1wf/JQprgX/1FPw8MNw2WXBjswYYwIi9yb648dh0iR49lk4cgQGDXILcl9xRbAjM8aYgMp9iT4xEd57D0aMgK1boWNHVxu+Ro1gR2aMMVkid/XRf/01REe7i54uv9wtwD1vniV5Y0xYyx2Jfu1aN6h6441uvdb33oOlS6FFi2BHZowxWS68E/327TBwoJsH/+OPMG4c/PIL3Hab1YY3xuQa4dlHf/iwS+ovvQSnT7uLnkaMgBIlgh2ZMcZku/BK9AkJ8MYbMGqUW77v1lvdrJrKlYMdmTHGBE34JPrffnNlg9evh+uvh48/dotyG2NMLhc+HdXlyrmW+4cfurVaLckbYwwQTi36fPncVEljjDGp+NWiF5F2IrJBRDaLyPAM9rlVRGJFZJ2IvO/z+B0issn7uiNQgRtjjPFPpi16EYkAJgNtgHhgmYjMVdVYn32qAI8BTVV1v4hc7j1eHBgFRAMKLPeO3R/4UzHGGJMef1r0jYDNqrpFVU8BM4EuafYZBExOSuCqust7/CbgS1Xd5237EmgXmNCNMcb4w59EXxbY6nM/3nvM1zXANSLyvYgsEZF253EsIjJYRGJEJGb37t3+R2+MMSZTgZp1kxeoArQAegOviYjfC6qq6lRVjVbV6FKlSgUoJGOMMeBfot8GXOlzv5z3mK94YK6qnlbV34CNuMTvz7HGGGOykD+JfhlQRUQqiUh+oBcwN80+H+Fa84hISVxXzhbgc6CtiESKSCTQ1nvMGGNMNsl01o2qJojIEFyCjgCmqeo6ERkDxKjqXFISeixwBnhUVfcCiMhY3D8LgDGqui8rTsQYY0z6RFWDHUMqIrIb+P0inqIksCdA4YSK3HbOue18wc45t7iYc66gqukOcua4RH+xRCRGVaODHUd2ym3nnNvOF+ycc4usOufwqXVjjDEmXZbojTEmzIVjop8a7ACCILedc247X7Bzzi2y5JzDro/eGGNMauHYojfGGOPDEr0xxoS5kEz0mdXHF5FLRGSWt/0nEamY/VEGlh/n/JC3HsBqEflaRCoEI85A8mcdBG+/7iKiIhLyU/EuZu2HUOXH73Z5EVkoIj97v98dghFnoIjINBHZJSJrM9guIjLJez9Wi0j9i35RVQ2pL9zVub8CVwH5gVVAjTT7/A34j3e7FzAr2HFnwzm3BC71bt+bG87Z268wsAhYAkQHO+5s+DlXAX4GIr37lwc77mw456nAvd7tGkBcsOO+yHNuBtQH1mawvQPwGSBAE+Cni33NUGzR+1Mfvwvwtnd7DtBaRCQbYwy0TM9ZVReq6jHv7hJcAblQ5s/PGWAs8AJwIjuDyyIXs/ZDqPLnnBUo4t0uCmzPxvgCTlUXAecqBdMFmK7OEqCYiJS+mNcMxUTvT4375H1UNQE4CJTIluiyhl91/X3chWsRhLJMz9n7SHulqn6anYFloYtZ+yFU+XPOo4G+IhIPzAeGZk9oQXO+f++ZCp/FwQ0AItIXt3Rj82DHkpVEJA8wAegf5FCym+/aD+WARSJSW1UPBDWqrNUbeEtVXxKRa4F3RKSWqiYGO7BQEYoten9q3CfvIyJ5cR/39mZLdFnDr7r+InIjMALorKonsym2rJLZORcGagHfikgcri9zbogPyF7M2g+hyp9zvguYDaCqPwIFcMW/wlXA1/EIxUTvT338ucAd3u0ewDfqjXKEqEzPWUTqAa/iknyo99tCJuesqgdVtaSqVlTVirhxic6qGhOccAPiYtZ+CFX+nPMfQGsAEamOS/ThvOboXKCfN/umCXBQVXdczBOGXNeN+lcf/w3cx7vNuEGPXsGL+OL5ec7jgELAf71x5z9UtXPQgr5Ifp5zWPHznDNc+yEU+XnOD+OWJ30QNzDbP5QbbiIyA/fPuqQ37jAKyAegqv/BjUN0ADYDx4ABF/2aIfx+GWOM8UModt0YY4w5D5bojTEmzFmiN8aYMGeJ3hhjwpwlemOMCXOW6I0xJsxZojfGmDD3/w49Yq72blIrAAAAAElFTkSuQmCC\n", 215 | "text/plain": [ 216 | "
" 217 | ] 218 | }, 219 | "metadata": { 220 | "needs_background": "light" 221 | }, 222 | "output_type": "display_data" 223 | }, 224 | { 225 | "data": { 226 | "image/png": "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\n", 227 | "text/plain": [ 228 | "
" 229 | ] 230 | }, 231 | "metadata": { 232 | "needs_background": "light" 233 | }, 234 | "output_type": "display_data" 235 | } 236 | ], 237 | "source": [ 238 | "# Plot the chart for accuracy and loss on both training and validation\n", 239 | "%matplotlib inline\n", 240 | "import matplotlib.pyplot as plt\n", 241 | "acc = history.history['accuracy']\n", 242 | "val_acc =history.history['val_accuracy']\n", 243 | "loss = history.history['loss']\n", 244 | "val_loss =history.history['val_loss']\n", 245 | "\n", 246 | "epochs = range(len(acc))\n", 247 | "\n", 248 | "plt.plot(epochs, acc, 'r', label='Training accuracy')\n", 249 | "plt.plot(epochs, val_acc, 'b', label='Validation accuracy')\n", 250 | "plt.title('Training and validation accuracy')\n", 251 | "plt.legend()\n", 252 | "plt.figure()\n", 253 | "\n", 254 | "plt.plot(epochs, loss, 'r', label='Training Loss')\n", 255 | "plt.plot(epochs, val_loss, 'b', label='Validation Loss')\n", 256 | "plt.title('Training and validation loss')\n", 257 | "plt.legend()\n", 258 | "\n", 259 | "plt.show()" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "metadata": {}, 265 | "source": [ 266 | "# Submission Instructions" 267 | ] 268 | }, 269 | { 270 | "cell_type": "code", 271 | "execution_count": 96, 272 | "metadata": {}, 273 | "outputs": [], 274 | "source": [ 275 | "# Now click the 'Submit Assignment' button above." 276 | ] 277 | }, 278 | { 279 | "cell_type": "markdown", 280 | "metadata": {}, 281 | "source": [ 282 | "# When you're done or would like to take a break, please run the two cells below to save your work and close the Notebook. This will free up resources for your fellow learners. " 283 | ] 284 | }, 285 | { 286 | "cell_type": "code", 287 | "execution_count": null, 288 | "metadata": {}, 289 | "outputs": [], 290 | "source": [ 291 | "%%javascript\n", 292 | "\n", 293 | "IPython.notebook.save_checkpoint();" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": null, 299 | "metadata": {}, 300 | "outputs": [], 301 | "source": [ 302 | "%%javascript\n", 303 | "IPython.notebook.session.delete();\n", 304 | "window.onbeforeunload = null\n", 305 | "setTimeout(function() { window.close(); }, 1000);" 306 | ] 307 | } 308 | ], 309 | "metadata": { 310 | "colab": { 311 | "name": "Exercise 8 - Question.ipynb", 312 | "provenance": [] 313 | }, 314 | "coursera": { 315 | "course_slug": "convolutional-neural-networks-tensorflow", 316 | "graded_item_id": "8mIh8", 317 | "launcher_item_id": "gg95t" 318 | }, 319 | "kernelspec": { 320 | "display_name": "Python 3", 321 | "language": "python", 322 | "name": "python3" 323 | }, 324 | "language_info": { 325 | "codemirror_mode": { 326 | "name": "ipython", 327 | "version": 3 328 | }, 329 | "file_extension": ".py", 330 | "mimetype": "text/x-python", 331 | "name": "python", 332 | "nbconvert_exporter": "python", 333 | "pygments_lexer": "ipython3", 334 | "version": "3.6.8" 335 | } 336 | }, 337 | "nbformat": 4, 338 | "nbformat_minor": 1 339 | } 340 | --------------------------------------------------------------------------------