├── 1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning ├── Colab Notebooks │ ├── Copy_of_Course_1_Part_8_Lesson_2_Notebook.ipynb │ ├── Copy_of_Course_1_Part_8_Lesson_3_Notebook.ipynb │ ├── Copy_of_Course_1_Part_8_Lesson_4_Notebook.ipynb │ ├── Copy_of_Exercise_4_Question.ipynb │ ├── Copy_of_Course_1_Part_6_Lesson_2_Notebook.ipynb │ ├── Copy_of_Course_1_Part_6_Lesson_3_Notebook.ipynb │ ├── Copy_of_Exercise_3_Question.ipynb │ ├── Course 1 - Part 2 - Lesson 2 - Notebook.ipynb │ ├── Course 1 - Part 4 - Lesson 2 - Notebook.ipynb │ ├── Course 1 - Part 4 - Lesson 4 - Notebook.ipynb │ ├── Exercise 2 - Handwriting Recognition.ipynb │ └── Exercise_1_House_Prices_Question.ipynb ├── Coursera.pdf ├── utf-8''Excercise-3-Question.ipynb ├── utf-8''Exercise2-Question.ipynb ├── utf-8''Exercise4-Question.ipynb └── utf-8''Exercise_1_House_Prices_Question.ipynb ├── 2. Convolutional Neural Networks in TensorFlow ├── Colab Notebooks │ ├── Course 2 - Part 2 - Lesson 2 - Notebook.ipynb │ └── Exercise 5 - Question.ipynb ├── Coursera.pdf ├── utf-8''Exercise_1_Cats_vs_Dogs_Question-FINAL.ipynb ├── utf-8''Exercise_2_Cats_vs_Dogs_using_augmentation_Question-FINAL.ipynb ├── utf-8''Exercise_3_Horses_vs_humans_using_Transfer_Learning_Question-FINAL.ipynb └── utf-8''Exercise_4_Multi_class_classifier_Question-FINAL.ipynb ├── 3. Natural Language Processing in TensorFlow └── Coursera.pdf ├── 4. Sequences, Time Series and Prediction └── Coursera.pdf ├── Coursera.pdf ├── LICENSE ├── README.md └── TensorFlow_Summary.ipynb /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Colab Notebooks/ Copy_of_Course_1_Part_8_Lesson_4_Notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "accelerator": "GPU", 6 | "colab": { 7 | "name": "Copy of Course 1 - Part 8 - Lesson 4 - Notebook.ipynb", 8 | "private_outputs": true, 9 | "provenance": [], 10 | "collapsed_sections": [], 11 | "include_colab_link": true 12 | }, 13 | "kernelspec": { 14 | "display_name": "Python 3", 15 | "language": "python", 16 | "name": "python3" 17 | }, 18 | "language_info": { 19 | "codemirror_mode": { 20 | "name": "ipython", 21 | "version": 3 22 | }, 23 | "file_extension": ".py", 24 | "mimetype": "text/x-python", 25 | "name": "python", 26 | "nbconvert_exporter": "python", 27 | "pygments_lexer": "ipython3", 28 | "version": "3.7.5rc1" 29 | } 30 | }, 31 | "cells": [ 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "id": "view-in-github", 36 | "colab_type": "text" 37 | }, 38 | "source": [ 39 | "\"Open" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "id": "rX8mhOLljYeM" 46 | }, 47 | "source": [ 48 | "##### Copyright 2019 The TensorFlow Authors." 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "metadata": { 54 | "cellView": "form", 55 | "id": "BZSlp3DAjdYf" 56 | }, 57 | "source": [ 58 | "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", 59 | "# you may not use this file except in compliance with the License.\n", 60 | "# You may obtain a copy of the License at\n", 61 | "#\n", 62 | "# https://www.apache.org/licenses/LICENSE-2.0\n", 63 | "#\n", 64 | "# Unless required by applicable law or agreed to in writing, software\n", 65 | "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", 66 | "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", 67 | "# See the License for the specific language governing permissions and\n", 68 | "# limitations under the License." 69 | ], 70 | "execution_count": null, 71 | "outputs": [] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "metadata": { 76 | "id": "RXZT2UsyIVe_" 77 | }, 78 | "source": [ 79 | "!wget --no-check-certificate \\\n", 80 | " https://storage.googleapis.com/laurencemoroney-blog.appspot.com/horse-or-human.zip \\\n", 81 | " -O /tmp/horse-or-human.zip" 82 | ], 83 | "execution_count": null, 84 | "outputs": [] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "metadata": { 89 | "id": "0mLij6qde6Ox" 90 | }, 91 | "source": [ 92 | "!wget --no-check-certificate \\\n", 93 | " https://storage.googleapis.com/laurencemoroney-blog.appspot.com/validation-horse-or-human.zip \\\n", 94 | " -O /tmp/validation-horse-or-human.zip" 95 | ], 96 | "execution_count": null, 97 | "outputs": [] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": { 102 | "id": "9brUxyTpYZHy" 103 | }, 104 | "source": [ 105 | "The following python code will use the OS library to use Operating System libraries, giving you access to the file system, and the zipfile library allowing you to unzip the data. " 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "metadata": { 111 | "id": "PLy3pthUS0D2" 112 | }, 113 | "source": [ 114 | "import os\n", 115 | "import zipfile\n", 116 | "\n", 117 | "local_zip = '/tmp/horse-or-human.zip'\n", 118 | "zip_ref = zipfile.ZipFile(local_zip, 'r')\n", 119 | "zip_ref.extractall('/tmp/horse-or-human')\n", 120 | "local_zip = '/tmp/validation-horse-or-human.zip'\n", 121 | "zip_ref = zipfile.ZipFile(local_zip, 'r')\n", 122 | "zip_ref.extractall('/tmp/validation-horse-or-human')\n", 123 | "zip_ref.close()" 124 | ], 125 | "execution_count": null, 126 | "outputs": [] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": { 131 | "id": "o-qUPyfO7Qr8" 132 | }, 133 | "source": [ 134 | "The contents of the .zip are extracted to the base directory `/tmp/horse-or-human`, which in turn each contain `horses` and `humans` subdirectories.\n", 135 | "\n", 136 | "In short: The training set is the data that is used to tell the neural network model that 'this is what a horse looks like', 'this is what a human looks like' etc. \n", 137 | "\n", 138 | "One thing to pay attention to in this sample: We do not explicitly label the images as horses or humans. If you remember with the handwriting example earlier, we had labelled 'this is a 1', 'this is a 7' etc. Later you'll see something called an ImageGenerator being used -- and this is coded to read images from subdirectories, and automatically label them from the name of that subdirectory. So, for example, you will have a 'training' directory containing a 'horses' directory and a 'humans' one. ImageGenerator will label the images appropriately for you, reducing a coding step. \n", 139 | "\n", 140 | "Let's define each of these directories:" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "metadata": { 146 | "id": "NR_M9nWN-K8B" 147 | }, 148 | "source": [ 149 | "# Directory with our training horse pictures\n", 150 | "train_horse_dir = os.path.join('/tmp/horse-or-human/horses')\n", 151 | "\n", 152 | "# Directory with our training human pictures\n", 153 | "train_human_dir = os.path.join('/tmp/horse-or-human/humans')\n", 154 | "\n", 155 | "# Directory with our training horse pictures\n", 156 | "validation_horse_dir = os.path.join('/tmp/validation-horse-or-human/horses')\n", 157 | "\n", 158 | "# Directory with our training human pictures\n", 159 | "validation_human_dir = os.path.join('/tmp/validation-horse-or-human/humans')" 160 | ], 161 | "execution_count": null, 162 | "outputs": [] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "metadata": { 167 | "id": "4jORNQanMvhy" 168 | }, 169 | "source": [ 170 | "train_horse_names = os.listdir(train_horse_dir)\n", 171 | "train_human_names = os.listdir(train_human_dir)\n", 172 | "\n", 173 | "validation_horse_hames = os.listdir(validation_horse_dir)\n", 174 | "validation_human_names = os.listdir(validation_human_dir)" 175 | ], 176 | "execution_count": null, 177 | "outputs": [] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": { 182 | "id": "5oqBkNBJmtUv" 183 | }, 184 | "source": [ 185 | "## Building a Small Model from Scratch\n", 186 | "\n", 187 | "But before we continue, let's start defining the model:\n", 188 | "\n", 189 | "Step 1 will be to import tensorflow." 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "metadata": { 195 | "id": "qvfZg3LQbD-5" 196 | }, 197 | "source": [ 198 | "import tensorflow as tf" 199 | ], 200 | "execution_count": null, 201 | "outputs": [] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": { 206 | "id": "BnhYCP4tdqjC" 207 | }, 208 | "source": [ 209 | "We then add convolutional layers as in the previous example, and flatten the final result to feed into the densely connected layers." 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "metadata": { 215 | "id": "gokG5HKpdtzm" 216 | }, 217 | "source": [ 218 | "Finally we add the densely connected layers. \n", 219 | "\n", 220 | "Note that because we are facing a two-class classification problem, i.e. a *binary classification problem*, we will end our network with a [*sigmoid* activation](https://wikipedia.org/wiki/Sigmoid_function), so that the output of our network will be a single scalar between 0 and 1, encoding the probability that the current image is class 1 (as opposed to class 0)." 221 | ] 222 | }, 223 | { 224 | "cell_type": "code", 225 | "metadata": { 226 | "id": "PixZ2s5QbYQ3" 227 | }, 228 | "source": [ 229 | "model = tf.keras.models.Sequential([\n", 230 | " # Note the input shape is the desired size of the image 150x150 with 3 bytes color\n", 231 | " # This is the first convolution\n", 232 | " tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150, 150, 3)),\n", 233 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 234 | " # The second convolution\n", 235 | " tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n", 236 | " tf.keras.layers.MaxPooling2D(2,2),\n", 237 | " # The third convolution\n", 238 | " tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n", 239 | " tf.keras.layers.MaxPooling2D(2,2),\n", 240 | " # The fourth convolution\n", 241 | " #tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n", 242 | " #tf.keras.layers.MaxPooling2D(2,2),\n", 243 | " # The fifth convolution\n", 244 | " #tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n", 245 | " #tf.keras.layers.MaxPooling2D(2,2),\n", 246 | " # Flatten the results to feed into a DNN\n", 247 | " tf.keras.layers.Flatten(),\n", 248 | " # 512 neuron hidden layer\n", 249 | " tf.keras.layers.Dense(512, activation='relu'),\n", 250 | " # Only 1 output neuron. It will contain a value from 0-1 where 0 for 1 class ('horses') and 1 for the other ('humans')\n", 251 | " tf.keras.layers.Dense(1, activation='sigmoid')\n", 252 | "])" 253 | ], 254 | "execution_count": null, 255 | "outputs": [] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "metadata": { 260 | "id": "s9EaFDP5srBa" 261 | }, 262 | "source": [ 263 | "The model.summary() method call prints a summary of the NN " 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "metadata": { 269 | "id": "7ZKj8392nbgP" 270 | }, 271 | "source": [ 272 | "model.summary()" 273 | ], 274 | "execution_count": null, 275 | "outputs": [] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": { 280 | "id": "DmtkTn06pKxF" 281 | }, 282 | "source": [ 283 | "The \"output shape\" column shows how the size of your feature map evolves in each successive layer. The convolution layers reduce the size of the feature maps by a bit due to padding, and each pooling layer halves the dimensions." 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": { 289 | "id": "PEkKSpZlvJXA" 290 | }, 291 | "source": [ 292 | "Next, we'll configure the specifications for model training. We will train our model with the `binary_crossentropy` loss, because it's a binary classification problem and our final activation is a sigmoid. (For a refresher on loss metrics, see the [Machine Learning Crash Course](https://developers.google.com/machine-learning/crash-course/descending-into-ml/video-lecture).) We will use the `rmsprop` optimizer with a learning rate of `0.001`. During training, we will want to monitor classification accuracy.\n", 293 | "\n", 294 | "**NOTE**: In this case, using the [RMSprop optimization algorithm](https://wikipedia.org/wiki/Stochastic_gradient_descent#RMSProp) is preferable to [stochastic gradient descent](https://developers.google.com/machine-learning/glossary/#SGD) (SGD), because RMSprop automates learning-rate tuning for us. (Other optimizers, such as [Adam](https://wikipedia.org/wiki/Stochastic_gradient_descent#Adam) and [Adagrad](https://developers.google.com/machine-learning/glossary/#AdaGrad), also automatically adapt the learning rate during training, and would work equally well here.)" 295 | ] 296 | }, 297 | { 298 | "cell_type": "code", 299 | "metadata": { 300 | "id": "8DHWhFP_uhq3" 301 | }, 302 | "source": [ 303 | "from tensorflow.keras.optimizers import RMSprop\n", 304 | "\n", 305 | "model.compile(loss='binary_crossentropy',\n", 306 | " optimizer=RMSprop(lr=0.001),\n", 307 | " metrics=['accuracy'])" 308 | ], 309 | "execution_count": null, 310 | "outputs": [] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": { 315 | "id": "Sn9m9D3UimHM" 316 | }, 317 | "source": [ 318 | "### Data Preprocessing\n", 319 | "\n", 320 | "Let's set up data generators that will read pictures in our source folders, convert them to `float32` tensors, and feed them (with their labels) to our network. We'll have one generator for the training images and one for the validation images. Our generators will yield batches of images of size 300x300 and their labels (binary).\n", 321 | "\n", 322 | "As you may already know, data that goes into neural networks should usually be normalized in some way to make it more amenable to processing by the network. (It is uncommon to feed raw pixels into a convnet.) In our case, we will preprocess our images by normalizing the pixel values to be in the `[0, 1]` range (originally all values are in the `[0, 255]` range).\n", 323 | "\n", 324 | "In Keras this can be done via the `keras.preprocessing.image.ImageDataGenerator` class using the `rescale` parameter. This `ImageDataGenerator` class allows you to instantiate generators of augmented image batches (and their labels) via `.flow(data, labels)` or `.flow_from_directory(directory)`. These generators can then be used with the Keras model methods that accept data generators as inputs: `fit`, `evaluate_generator`, and `predict_generator`." 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "metadata": { 330 | "id": "ClebU9NJg99G" 331 | }, 332 | "source": [ 333 | "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 334 | "\n", 335 | "# All images will be rescaled by 1./255\n", 336 | "train_datagen = ImageDataGenerator(rescale=1/255)\n", 337 | "validation_datagen = ImageDataGenerator(rescale=1/255)\n", 338 | "\n", 339 | "# Flow training images in batches of 128 using train_datagen generator\n", 340 | "train_generator = train_datagen.flow_from_directory(\n", 341 | " '/tmp/horse-or-human/', # This is the source directory for training images\n", 342 | " target_size=(150, 150), # All images will be resized to 150x150\n", 343 | " batch_size=128,\n", 344 | " # Since we use binary_crossentropy loss, we need binary labels\n", 345 | " class_mode='binary')\n", 346 | "\n", 347 | "# Flow training images in batches of 128 using train_datagen generator\n", 348 | "validation_generator = validation_datagen.flow_from_directory(\n", 349 | " '/tmp/validation-horse-or-human/', # This is the source directory for training images\n", 350 | " target_size=(150, 150), # All images will be resized to 150x150\n", 351 | " batch_size=32,\n", 352 | " # Since we use binary_crossentropy loss, we need binary labels\n", 353 | " class_mode='binary')" 354 | ], 355 | "execution_count": null, 356 | "outputs": [] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": { 361 | "id": "mu3Jdwkjwax4" 362 | }, 363 | "source": [ 364 | "### Training\n", 365 | "Let's train for 15 epochs -- this may take a few minutes to run.\n", 366 | "\n", 367 | "Do note the values per epoch.\n", 368 | "\n", 369 | "The Loss and Accuracy are a great indication of progress of training. It's making a guess as to the classification of the training data, and then measuring it against the known label, calculating the result. Accuracy is the portion of correct guesses. " 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "metadata": { 375 | "id": "Fb1_lgobv81m" 376 | }, 377 | "source": [ 378 | "history = model.fit(\n", 379 | " train_generator,\n", 380 | " steps_per_epoch=8, \n", 381 | " epochs=15,\n", 382 | " verbose=1,\n", 383 | " validation_data = validation_generator,\n", 384 | " validation_steps=8)" 385 | ], 386 | "execution_count": null, 387 | "outputs": [] 388 | }, 389 | { 390 | "cell_type": "markdown", 391 | "metadata": { 392 | "id": "o6vSHzPR2ghH" 393 | }, 394 | "source": [ 395 | "### Running the Model\n", 396 | "\n", 397 | "Let's now take a look at actually running a prediction using the model. This code will allow you to choose 1 or more files from your file system, it will then upload them, and run them through the model, giving an indication of whether the object is a horse or a human." 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "metadata": { 403 | "id": "DoWp43WxJDNT" 404 | }, 405 | "source": [ 406 | "import numpy as np\n", 407 | "from google.colab import files\n", 408 | "from keras.preprocessing import image\n", 409 | "\n", 410 | "uploaded = files.upload()\n", 411 | "\n", 412 | "for fn in uploaded.keys():\n", 413 | " \n", 414 | " # predicting images\n", 415 | " path = '/content/' + fn\n", 416 | " img = image.load_img(path, target_size=(150, 150))\n", 417 | " x = image.img_to_array(img)\n", 418 | " x = np.expand_dims(x, axis=0)\n", 419 | "\n", 420 | " images = np.vstack([x])\n", 421 | " classes = model.predict(images, batch_size=10)\n", 422 | " print(classes[0])\n", 423 | " if classes[0]>0.5:\n", 424 | " print(fn + \" is a human\")\n", 425 | " else:\n", 426 | " print(fn + \" is a horse\")\n", 427 | " " 428 | ], 429 | "execution_count": null, 430 | "outputs": [] 431 | }, 432 | { 433 | "cell_type": "markdown", 434 | "metadata": { 435 | "id": "-8EHQyWGDvWz" 436 | }, 437 | "source": [ 438 | "### Visualizing Intermediate Representations\n", 439 | "\n", 440 | "To get a feel for what kind of features our convnet has learned, one fun thing to do is to visualize how an input gets transformed as it goes through the convnet.\n", 441 | "\n", 442 | "Let's pick a random image from the training set, and then generate a figure where each row is the output of a layer, and each image in the row is a specific filter in that output feature map. Rerun this cell to generate intermediate representations for a variety of training images." 443 | ] 444 | }, 445 | { 446 | "cell_type": "code", 447 | "metadata": { 448 | "id": "-5tES8rXFjux" 449 | }, 450 | "source": [ 451 | "import matplotlib.pyplot as plt\n", 452 | "import numpy as np\n", 453 | "import random\n", 454 | "from tensorflow.keras.preprocessing.image import img_to_array, load_img\n", 455 | "\n", 456 | "# Let's define a new Model that will take an image as input, and will output\n", 457 | "# intermediate representations for all layers in the previous model after\n", 458 | "# the first.\n", 459 | "successive_outputs = [layer.output for layer in model.layers[1:]]\n", 460 | "#visualization_model = Model(img_input, successive_outputs)\n", 461 | "visualization_model = tf.keras.models.Model(inputs = model.input, outputs = successive_outputs)\n", 462 | "# Let's prepare a random input image from the training set.\n", 463 | "horse_img_files = [os.path.join(train_horse_dir, f) for f in train_horse_names]\n", 464 | "human_img_files = [os.path.join(train_human_dir, f) for f in train_human_names]\n", 465 | "img_path = random.choice(horse_img_files + human_img_files)\n", 466 | "\n", 467 | "img = load_img(img_path, target_size=(150, 150)) # this is a PIL image\n", 468 | "x = img_to_array(img) # Numpy array with shape (150, 150, 3)\n", 469 | "x = x.reshape((1,) + x.shape) # Numpy array with shape (1, 150, 150, 3)\n", 470 | "\n", 471 | "# Rescale by 1/255\n", 472 | "x /= 255\n", 473 | "\n", 474 | "# Let's run our image through our network, thus obtaining all\n", 475 | "# intermediate representations for this image.\n", 476 | "successive_feature_maps = visualization_model.predict(x)\n", 477 | "\n", 478 | "# These are the names of the layers, so can have them as part of our plot\n", 479 | "layer_names = [layer.name for layer in model.layers]\n", 480 | "\n", 481 | "# Now let's display our representations\n", 482 | "for layer_name, feature_map in zip(layer_names, successive_feature_maps):\n", 483 | " if len(feature_map.shape) == 4:\n", 484 | " # Just do this for the conv / maxpool layers, not the fully-connected layers\n", 485 | " n_features = feature_map.shape[-1] # number of features in feature map\n", 486 | " # The feature map has shape (1, size, size, n_features)\n", 487 | " size = feature_map.shape[1]\n", 488 | " # We will tile our images in this matrix\n", 489 | " display_grid = np.zeros((size, size * n_features))\n", 490 | " for i in range(n_features):\n", 491 | " # Postprocess the feature to make it visually palatable\n", 492 | " x = feature_map[0, :, :, i]\n", 493 | " x -= x.mean()\n", 494 | " x /= x.std()\n", 495 | " x *= 64\n", 496 | " x += 128\n", 497 | " x = np.clip(x, 0, 255).astype('uint8')\n", 498 | " # We'll tile each filter into this big horizontal grid\n", 499 | " display_grid[:, i * size : (i + 1) * size] = x\n", 500 | " # Display the grid\n", 501 | " scale = 20. / n_features\n", 502 | " plt.figure(figsize=(scale * n_features, scale))\n", 503 | " plt.title(layer_name)\n", 504 | " plt.grid(False)\n", 505 | " plt.imshow(display_grid, aspect='auto', cmap='viridis')" 506 | ], 507 | "execution_count": null, 508 | "outputs": [] 509 | }, 510 | { 511 | "cell_type": "markdown", 512 | "metadata": { 513 | "id": "tuqK2arJL0wo" 514 | }, 515 | "source": [ 516 | "As you can see we go from the raw pixels of the images to increasingly abstract and compact representations. The representations downstream start highlighting what the network pays attention to, and they show fewer and fewer features being \"activated\"; most are set to zero. This is called \"sparsity.\" Representation sparsity is a key feature of deep learning.\n", 517 | "\n", 518 | "\n", 519 | "These representations carry increasingly less information about the original pixels of the image, but increasingly refined information about the class of the image. You can think of a convnet (or a deep network in general) as an information distillation pipeline." 520 | ] 521 | }, 522 | { 523 | "cell_type": "markdown", 524 | "metadata": { 525 | "id": "j4IBgYCYooGD" 526 | }, 527 | "source": [ 528 | "## Clean Up\n", 529 | "\n", 530 | "Before running the next exercise, run the following cell to terminate the kernel and free memory resources:" 531 | ] 532 | }, 533 | { 534 | "cell_type": "code", 535 | "metadata": { 536 | "id": "651IgjLyo-Jx" 537 | }, 538 | "source": [ 539 | "import os, signal\n", 540 | "os.kill(os.getpid(), signal.SIGKILL)" 541 | ], 542 | "execution_count": null, 543 | "outputs": [] 544 | } 545 | ] 546 | } -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Colab Notebooks/ Copy_of_Exercise_4_Question.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Copy of Exercise 4-Question.ipynb", 7 | "provenance": [], 8 | "include_colab_link": true 9 | }, 10 | "kernelspec": { 11 | "display_name": "Python 3", 12 | "name": "python3" 13 | } 14 | }, 15 | "cells": [ 16 | { 17 | "cell_type": "markdown", 18 | "metadata": { 19 | "id": "view-in-github", 20 | "colab_type": "text" 21 | }, 22 | "source": [ 23 | "\"Open" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "metadata": { 29 | "id": "zX4Kg8DUTKWO" 30 | }, 31 | "source": [ 32 | "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", 33 | "# you may not use this file except in compliance with the License.\n", 34 | "# You may obtain a copy of the License at\n", 35 | "#\n", 36 | "# https://www.apache.org/licenses/LICENSE-2.0\n", 37 | "#\n", 38 | "# Unless required by applicable law or agreed to in writing, software\n", 39 | "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", 40 | "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", 41 | "# See the License for the specific language governing permissions and\n", 42 | "# limitations under the License." 43 | ], 44 | "execution_count": null, 45 | "outputs": [] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": { 50 | "id": "UncprnB0ymAE" 51 | }, 52 | "source": [ 53 | "Below is code with a link to a happy or sad dataset which contains 80 images, 40 happy and 40 sad. \n", 54 | "Create a convolutional neural network that trains to 100% accuracy on these images, which cancels training upon hitting training accuracy of >.999\n", 55 | "\n", 56 | "Hint -- it will work best with 3 convolutional layers." 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "metadata": { 62 | "colab": { 63 | "base_uri": "https://localhost:8080/" 64 | }, 65 | "id": "7Vti6p3PxmpS", 66 | "outputId": "34c14aa7-5b3f-4249-af24-23f0ec00eb3e" 67 | }, 68 | "source": [ 69 | "import tensorflow as tf\n", 70 | "import os\n", 71 | "import zipfile\n", 72 | "\n", 73 | "\n", 74 | "DESIRED_ACCURACY = 0.999\n", 75 | "\n", 76 | "!wget --no-check-certificate \\\n", 77 | " \"https://storage.googleapis.com/laurencemoroney-blog.appspot.com/happy-or-sad.zip\" \\\n", 78 | " -O \"/tmp/happy-or-sad.zip\"\n", 79 | "\n", 80 | "zip_ref = zipfile.ZipFile(\"/tmp/happy-or-sad.zip\", 'r')\n", 81 | "zip_ref.extractall(\"/tmp/h-or-s\")\n", 82 | "zip_ref.close()\n", 83 | "\n", 84 | "class myCallback(tf.keras.callbacks.Callback):\n", 85 | " def on_epoch_end(self, epoch, logs={}):\n", 86 | " if(logs.get('accuracy') >= DESIRED_ACCURACY):\n", 87 | " print(\"Reached 99.9% accuracy so cancelling training\")\n", 88 | " self.model.stop_training = True\n", 89 | "\n", 90 | "callbacks = myCallback()" 91 | ], 92 | "execution_count": null, 93 | "outputs": [ 94 | { 95 | "output_type": "stream", 96 | "text": [ 97 | "--2021-05-12 06:43:26-- https://storage.googleapis.com/laurencemoroney-blog.appspot.com/happy-or-sad.zip\n", 98 | "Resolving storage.googleapis.com (storage.googleapis.com)... 64.233.188.128, 64.233.189.128, 108.177.125.128, ...\n", 99 | "Connecting to storage.googleapis.com (storage.googleapis.com)|64.233.188.128|:443... connected.\n", 100 | "HTTP request sent, awaiting response... 200 OK\n", 101 | "Length: 2670333 (2.5M) [application/zip]\n", 102 | "Saving to: ‘/tmp/happy-or-sad.zip’\n", 103 | "\n", 104 | "\r/tmp/happy-or-sad.z 0%[ ] 0 --.-KB/s \r/tmp/happy-or-sad.z 100%[===================>] 2.55M --.-KB/s in 0.03s \n", 105 | "\n", 106 | "2021-05-12 06:43:26 (83.6 MB/s) - ‘/tmp/happy-or-sad.zip’ saved [2670333/2670333]\n", 107 | "\n" 108 | ], 109 | "name": "stdout" 110 | } 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "metadata": { 116 | "id": "6DLGbXXI1j_V" 117 | }, 118 | "source": [ 119 | "# This Code Block should Define and Compile the Model\n", 120 | "model = tf.keras.models.Sequential([\n", 121 | "tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(150, 150, 3)),\n", 122 | "tf.keras.layers.MaxPooling2D(2, 2),\n", 123 | "tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),\n", 124 | "tf.keras.layers.MaxPooling2D(2, 2),\n", 125 | "#tf.keras.layers.Conv2D(16, (3, 3), input_shape=(150, 150, 3)),\n", 126 | "#tf.keras.layers.MaxPooling2D(2, 2),\n", 127 | "#tf.keras.layers.Conv2D(16, (3, 3), input_shape=(150, 150, 3)),\n", 128 | "#tf.keras.layers.MaxPooling2D(2, 2),\n", 129 | "tf.keras.layers.Flatten(),\n", 130 | "tf.keras.layers.Dense(128, activation='relu'),\n", 131 | "tf.keras.layers.Dense(1, activation='sigmoid')\n", 132 | "])\n", 133 | "\n", 134 | "from tensorflow.keras.optimizers import RMSprop\n", 135 | "\n", 136 | "model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['accuracy'])" 137 | ], 138 | "execution_count": null, 139 | "outputs": [] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "metadata": { 144 | "colab": { 145 | "base_uri": "https://localhost:8080/" 146 | }, 147 | "id": "4Ap9fUJE1vVu", 148 | "outputId": "1bdf9804-d7d7-4d37-e150-2e3297c56a33" 149 | }, 150 | "source": [ 151 | "# This code block should create an instance of an ImageDataGenerator called train_datagen \n", 152 | "# And a train_generator by calling train_datagen.flow_from_directory\n", 153 | "\n", 154 | "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 155 | "\n", 156 | "train_datagen = ImageDataGenerator(rescale=1/255)\n", 157 | "\n", 158 | "train_generator = train_datagen.flow_from_directory(\n", 159 | " '/tmp/h-or-s',\n", 160 | " target_size=(150, 150),\n", 161 | " batch_size=10,\n", 162 | " class_mode='binary')\n", 163 | "\n", 164 | "# Expected output: 'Found 80 images belonging to 2 classes'" 165 | ], 166 | "execution_count": null, 167 | "outputs": [ 168 | { 169 | "output_type": "stream", 170 | "text": [ 171 | "Found 80 images belonging to 2 classes.\n" 172 | ], 173 | "name": "stdout" 174 | } 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "metadata": { 180 | "colab": { 181 | "base_uri": "https://localhost:8080/" 182 | }, 183 | "id": "48dLm13U1-Le", 184 | "outputId": "75d2c56c-dcc4-4771-a657-8a9734b860b4" 185 | }, 186 | "source": [ 187 | "# This code block should call model.fit and train for\n", 188 | "# a number of epochs. \n", 189 | "history = model.fit(\n", 190 | " train_generator,\n", 191 | " steps_per_epoch=2,\n", 192 | " epochs=15,\n", 193 | " #verbose=1,\n", 194 | " callbacks=[callbacks])\n", 195 | " \n", 196 | "# Expected output: \"Reached 99.9% accuracy so cancelling training!\"\"" 197 | ], 198 | "execution_count": null, 199 | "outputs": [ 200 | { 201 | "output_type": "stream", 202 | "text": [ 203 | "Epoch 1/15\n", 204 | "2/2 [==============================] - 1s 209ms/step - loss: 3.4293 - accuracy: 0.4667\n", 205 | "Epoch 2/15\n", 206 | "2/2 [==============================] - 0s 198ms/step - loss: 8.0954 - accuracy: 0.4000\n", 207 | "Epoch 3/15\n", 208 | "2/2 [==============================] - 0s 205ms/step - loss: 0.7211 - accuracy: 0.8000\n", 209 | "Epoch 4/15\n", 210 | "2/2 [==============================] - 0s 196ms/step - loss: 0.7788 - accuracy: 0.5333\n", 211 | "Epoch 5/15\n", 212 | "2/2 [==============================] - 0s 192ms/step - loss: 0.5349 - accuracy: 0.7000\n", 213 | "Epoch 6/15\n", 214 | "2/2 [==============================] - 0s 196ms/step - loss: 0.4326 - accuracy: 0.9000\n", 215 | "Epoch 7/15\n", 216 | "2/2 [==============================] - 0s 195ms/step - loss: 0.5008 - accuracy: 0.5000\n", 217 | "Epoch 8/15\n", 218 | "2/2 [==============================] - 0s 203ms/step - loss: 0.3993 - accuracy: 0.8667\n", 219 | "Epoch 9/15\n", 220 | "2/2 [==============================] - 0s 198ms/step - loss: 0.2404 - accuracy: 0.9333\n", 221 | "Epoch 10/15\n", 222 | "2/2 [==============================] - 0s 196ms/step - loss: 0.4369 - accuracy: 0.7000\n", 223 | "Epoch 11/15\n", 224 | "2/2 [==============================] - 0s 204ms/step - loss: 0.1500 - accuracy: 1.0000\n", 225 | "Reached 99.9% accuracy so cancelling training\n" 226 | ], 227 | "name": "stdout" 228 | } 229 | ] 230 | } 231 | ] 232 | } -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Colab Notebooks/Copy_of_Exercise_3_Question.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Copy of Exercise 3 - Question.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "display_name": "Python 3", 13 | "name": "python3" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "view-in-github", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "\"Open" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "metadata": { 30 | "id": "zX4Kg8DUTKWO" 31 | }, 32 | "source": [ 33 | "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", 34 | "# you may not use this file except in compliance with the License.\n", 35 | "# You may obtain a copy of the License at\n", 36 | "#\n", 37 | "# https://www.apache.org/licenses/LICENSE-2.0\n", 38 | "#\n", 39 | "# Unless required by applicable law or agreed to in writing, software\n", 40 | "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", 41 | "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", 42 | "# See the License for the specific language governing permissions and\n", 43 | "# limitations under the License." 44 | ], 45 | "execution_count": null, 46 | "outputs": [] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": { 51 | "id": "iQjHqsmTAVLU" 52 | }, 53 | "source": [ 54 | "## Exercise 3\n", 55 | "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", 56 | "\n", 57 | "I've started the code for you -- you need to finish it!\n", 58 | "\n", 59 | "When 99.8% accuracy has been hit, you should print out the string \"Reached 99.8% accuracy so cancelling training!\"\n" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "metadata": { 65 | "id": "sfQRyaJWAIdg", 66 | "colab": { 67 | "base_uri": "https://localhost:8080/" 68 | }, 69 | "outputId": "0a43f354-f69e-413a-a71d-3bc986bc921c" 70 | }, 71 | "source": [ 72 | "import tensorflow as tf\n", 73 | "\n", 74 | "# YOUR CODE STARTS HERE\n", 75 | "\n", 76 | "class myCallbacks(tf.keras.callbacks.Callback):\n", 77 | " def on_epoch_end(self, epoch, logs={}):\n", 78 | " if(logs.get('accuracy') >= 0.998):\n", 79 | " print(\"Reached 99.8% accuracy so cancelling training!\")\n", 80 | " self.model.stop_training = True\n", 81 | "\n", 82 | "callbacks = myCallbacks()\n", 83 | "\n", 84 | "# YOUR CODE ENDS HERE\n", 85 | "\n", 86 | "mnist = tf.keras.datasets.mnist\n", 87 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n", 88 | "\n", 89 | "# YOUR CODE STARTS HERE\n", 90 | "\n", 91 | "training_images = training_images.reshape(60000, 28, 28, 1)\n", 92 | "test_images = test_images.reshape(10000, 28, 28, 1)\n", 93 | "training_images, test_images = training_images / 255.0, test_images / 255.0\n", 94 | "\n", 95 | "# YOUR CODE ENDS HERE\n", 96 | "\n", 97 | "model = tf.keras.models.Sequential([\n", 98 | " # YOUR CODE STARTS HERE\n", 99 | " tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),\n", 100 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 101 | " tf.keras.layers.Flatten(),\n", 102 | " tf.keras.layers.Dense(128, activation='relu'),\n", 103 | " tf.keras.layers.Dense(10, activation='softmax')\n", 104 | " # YOUR CODE ENDS HERE\n", 105 | "])\n", 106 | "\n", 107 | "# YOUR CODE STARTS HERE\n", 108 | "\n", 109 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n", 110 | "model.summary()\n", 111 | "model.fit(training_images, training_labels, epochs=20, callbacks=[callbacks])\n", 112 | "model.evaluate(test_images, test_labels)\n", 113 | "# YOUR CODE ENDS HERE\n" 114 | ], 115 | "execution_count": 3, 116 | "outputs": [ 117 | { 118 | "output_type": "stream", 119 | "text": [ 120 | "Model: \"sequential_1\"\n", 121 | "_________________________________________________________________\n", 122 | "Layer (type) Output Shape Param # \n", 123 | "=================================================================\n", 124 | "conv2d_2 (Conv2D) (None, 26, 26, 32) 320 \n", 125 | "_________________________________________________________________\n", 126 | "max_pooling2d_2 (MaxPooling2 (None, 13, 13, 32) 0 \n", 127 | "_________________________________________________________________\n", 128 | "flatten_2 (Flatten) (None, 5408) 0 \n", 129 | "_________________________________________________________________\n", 130 | "dense_4 (Dense) (None, 128) 692352 \n", 131 | "_________________________________________________________________\n", 132 | "dense_5 (Dense) (None, 10) 1290 \n", 133 | "=================================================================\n", 134 | "Total params: 693,962\n", 135 | "Trainable params: 693,962\n", 136 | "Non-trainable params: 0\n", 137 | "_________________________________________________________________\n", 138 | "Epoch 1/20\n", 139 | "1875/1875 [==============================] - 37s 20ms/step - loss: 0.2894 - accuracy: 0.9133\n", 140 | "Epoch 2/20\n", 141 | "1875/1875 [==============================] - 36s 19ms/step - loss: 0.0503 - accuracy: 0.9844\n", 142 | "Epoch 3/20\n", 143 | "1875/1875 [==============================] - 36s 19ms/step - loss: 0.0291 - accuracy: 0.9910\n", 144 | "Epoch 4/20\n", 145 | "1875/1875 [==============================] - 35s 19ms/step - loss: 0.0187 - accuracy: 0.9941\n", 146 | "Epoch 5/20\n", 147 | "1875/1875 [==============================] - 35s 19ms/step - loss: 0.0138 - accuracy: 0.9954\n", 148 | "Epoch 6/20\n", 149 | "1875/1875 [==============================] - 36s 19ms/step - loss: 0.0078 - accuracy: 0.9975\n", 150 | "Epoch 7/20\n", 151 | "1875/1875 [==============================] - 36s 19ms/step - loss: 0.0075 - accuracy: 0.9979\n", 152 | "Epoch 8/20\n", 153 | "1875/1875 [==============================] - 36s 19ms/step - loss: 0.0034 - accuracy: 0.9991\n", 154 | "Reached 99.8% accuracy so cancelling training!\n", 155 | "313/313 [==============================] - 2s 7ms/step - loss: 0.0566 - accuracy: 0.9859\n" 156 | ], 157 | "name": "stdout" 158 | }, 159 | { 160 | "output_type": "execute_result", 161 | "data": { 162 | "text/plain": [ 163 | "[0.056566473096609116, 0.9858999848365784]" 164 | ] 165 | }, 166 | "metadata": { 167 | "tags": [] 168 | }, 169 | "execution_count": 3 170 | } 171 | ] 172 | } 173 | ] 174 | } -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Colab Notebooks/Course 1 - Part 4 - Lesson 2 - Notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Course 1 - Part 4 - Lesson 2 - Notebook.ipynb", 7 | "private_outputs": true, 8 | "provenance": [], 9 | "collapsed_sections": [], 10 | "include_colab_link": true 11 | }, 12 | "kernelspec": { 13 | "display_name": "Python 3", 14 | "language": "python", 15 | "name": "python3" 16 | }, 17 | "language_info": { 18 | "codemirror_mode": { 19 | "name": "ipython", 20 | "version": 3 21 | }, 22 | "file_extension": ".py", 23 | "mimetype": "text/x-python", 24 | "name": "python", 25 | "nbconvert_exporter": "python", 26 | "pygments_lexer": "ipython3", 27 | "version": "3.7.5rc1" 28 | }, 29 | "accelerator": "GPU" 30 | }, 31 | "cells": [ 32 | { 33 | "cell_type": "markdown", 34 | "metadata": { 35 | "id": "view-in-github", 36 | "colab_type": "text" 37 | }, 38 | "source": [ 39 | "\"Open" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "id": "rX8mhOLljYeM" 46 | }, 47 | "source": [ 48 | "##### Copyright 2019 The TensorFlow Authors." 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "metadata": { 54 | "cellView": "form", 55 | "id": "BZSlp3DAjdYf" 56 | }, 57 | "source": [ 58 | "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", 59 | "# you may not use this file except in compliance with the License.\n", 60 | "# You may obtain a copy of the License at\n", 61 | "#\n", 62 | "# https://www.apache.org/licenses/LICENSE-2.0\n", 63 | "#\n", 64 | "# Unless required by applicable law or agreed to in writing, software\n", 65 | "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", 66 | "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", 67 | "# See the License for the specific language governing permissions and\n", 68 | "# limitations under the License." 69 | ], 70 | "execution_count": null, 71 | "outputs": [] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": { 76 | "id": "qnyTxjK_GbOD" 77 | }, 78 | "source": [ 79 | "# Beyond Hello World, A Computer Vision Example\n", 80 | "In the previous exercise you saw how to create a neural network that figured out the problem you were trying to solve. This gave an explicit example of learned behavior. Of course, in that instance, it was a bit of overkill because it would have been easier to write the function Y=2x-1 directly, instead of bothering with using Machine Learning to learn the relationship between X and Y for a fixed set of values, and extending that for all values.\n", 81 | "\n", 82 | "But what about a scenario where writing rules like that is much more difficult -- for example a computer vision problem? Let's take a look at a scenario where we can recognize different items of clothing, trained from a dataset containing 10 different types." 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": { 88 | "id": "H41FYgtlHPjW" 89 | }, 90 | "source": [ 91 | "## Start Coding\n", 92 | "\n", 93 | "Let's start with our import of TensorFlow" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "metadata": { 99 | "id": "q3KzJyjv3rnA" 100 | }, 101 | "source": [ 102 | "import tensorflow as tf\n", 103 | "print(tf.__version__)" 104 | ], 105 | "execution_count": null, 106 | "outputs": [] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": { 111 | "id": "n_n1U5do3u_F" 112 | }, 113 | "source": [ 114 | "The Fashion MNIST data is available directly in the tf.keras datasets API. You load it like this:" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "metadata": { 120 | "id": "PmxkHFpt31bM" 121 | }, 122 | "source": [ 123 | "mnist = tf.keras.datasets.fashion_mnist" 124 | ], 125 | "execution_count": null, 126 | "outputs": [] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": { 131 | "id": "GuoLQQBT4E-_" 132 | }, 133 | "source": [ 134 | "Calling load_data on this object will give you two sets of two lists, these will be the training and testing values for the graphics that contain the clothing items and their labels.\n" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "metadata": { 140 | "id": "BTdRgExe4TRB" 141 | }, 142 | "source": [ 143 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()" 144 | ], 145 | "execution_count": null, 146 | "outputs": [] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "metadata": { 151 | "id": "rw395ROx4f5Q" 152 | }, 153 | "source": [ 154 | "What does these values look like? Let's print a training image, and a training label to see...Experiment with different indices in the array. For example, also take a look at index 42...that's a a different boot than the one at index 0\n" 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "metadata": { 160 | "id": "FPc9d3gJ3jWF" 161 | }, 162 | "source": [ 163 | "import numpy as np\n", 164 | "np.set_printoptions(linewidth=200)\n", 165 | "import matplotlib.pyplot as plt\n", 166 | "plt.imshow(training_images[42])\n", 167 | "print(training_labels[42])\n", 168 | "print(training_images[42])" 169 | ], 170 | "execution_count": null, 171 | "outputs": [] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": { 176 | "id": "3cbrdH225_nH" 177 | }, 178 | "source": [ 179 | "You'll notice that all of the values in the number are between 0 and 255. If we are training a neural network, for various reasons it's easier if we treat all values as between 0 and 1, a process called '**normalizing**'...and fortunately in Python it's easy to normalize a list like this without looping. You do it like this:" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "metadata": { 185 | "id": "kRH19pWs6ZDn" 186 | }, 187 | "source": [ 188 | "training_images = training_images / 255.0\n", 189 | "test_images = test_images / 255.0" 190 | ], 191 | "execution_count": null, 192 | "outputs": [] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "metadata": { 197 | "id": "3DkO0As46lRn" 198 | }, 199 | "source": [ 200 | "Now you might be wondering why there are 2 sets...training and testing -- remember we spoke about this in the intro? The idea is to have 1 set of data for training, and then another set of data...that the model hasn't yet seen...to see how good it would be at classifying values. After all, when you're done, you're going to want to try it out with data that it hadn't previously seen!" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": { 206 | "id": "dIn7S9gf62ie" 207 | }, 208 | "source": [ 209 | "Let's now design the model. There's quite a few new concepts here, but don't worry, you'll get the hang of them. " 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "metadata": { 215 | "id": "7mAyndG3kVlK" 216 | }, 217 | "source": [ 218 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(), \n", 219 | " tf.keras.layers.Dense(128, activation=tf.nn.relu), \n", 220 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])" 221 | ], 222 | "execution_count": null, 223 | "outputs": [] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": { 228 | "id": "-lUcWaiX7MFj" 229 | }, 230 | "source": [ 231 | "**Sequential**: That defines a SEQUENCE of layers in the neural network\n", 232 | "\n", 233 | "**Flatten**: Remember earlier where our images were a square, when you printed them out? Flatten just takes that square and turns it into a 1 dimensional set.\n", 234 | "\n", 235 | "**Dense**: Adds a layer of neurons\n", 236 | "\n", 237 | "Each layer of neurons need an **activation function** to tell them what to do. There's lots of options, but just use these for now. \n", 238 | "\n", 239 | "**Relu** effectively means \"If X>0 return X, else return 0\" -- so what it does it it only passes values 0 or greater to the next layer in the network.\n", 240 | "\n", 241 | "**Softmax** takes a set of values, and effectively picks the biggest one, so, for example, if the output of the last layer looks like [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05], it saves you from fishing through it looking for the biggest value, and turns it into [0,0,0,0,1,0,0,0,0] -- The goal is to save a lot of coding!\n" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "metadata": { 247 | "id": "c8vbMCqb9Mh6" 248 | }, 249 | "source": [ 250 | "The next thing to do, now the model is defined, is to actually build it. You do this by compiling it with an optimizer and loss function as before -- and then you train it by calling **model.fit ** asking it to fit your training data to your training labels -- i.e. have it figure out the relationship between the training data and its actual labels, so in future if you have data that looks like the training data, then it can make a prediction for what that data would look like. " 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "metadata": { 256 | "id": "BLMdl9aP8nQ0" 257 | }, 258 | "source": [ 259 | "model.compile(optimizer = tf.optimizers.Adam(),\n", 260 | " loss = 'sparse_categorical_crossentropy',\n", 261 | " metrics=['accuracy'])\n", 262 | "\n", 263 | "model.fit(training_images, training_labels, epochs=5)" 264 | ], 265 | "execution_count": null, 266 | "outputs": [] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "metadata": { 271 | "id": "-JJMsvSB-1UY" 272 | }, 273 | "source": [ 274 | "Once it's done training -- you should see an accuracy value at the end of the final epoch. It might look something like 0.9098. This tells you that your neural network is about 91% accurate in classifying the training data. I.E., it figured out a pattern match between the image and the labels that worked 91% of the time. Not great, but not bad considering it was only trained for 5 epochs and done quite quickly.\n", 275 | "\n", 276 | "But how would it work with unseen data? That's why we have the test images. We can call model.evaluate, and pass in the two sets, and it will report back the loss for each. Let's give it a try:" 277 | ] 278 | }, 279 | { 280 | "cell_type": "code", 281 | "metadata": { 282 | "id": "WzlqsEzX9s5P" 283 | }, 284 | "source": [ 285 | "model.evaluate(test_images, test_labels)" 286 | ], 287 | "execution_count": null, 288 | "outputs": [] 289 | }, 290 | { 291 | "cell_type": "markdown", 292 | "metadata": { 293 | "id": "6tki-Aro_Uax" 294 | }, 295 | "source": [ 296 | "For me, that returned a accuracy of about .8838, which means it was about 88% accurate. As expected it probably would not do as well with *unseen* data as it did with data it was trained on! As you go through this course, you'll look at ways to improve this. \n", 297 | "\n", 298 | "To explore further, try the below exercises:\n" 299 | ] 300 | }, 301 | { 302 | "cell_type": "markdown", 303 | "metadata": { 304 | "id": "htldZNWcIPSN" 305 | }, 306 | "source": [ 307 | "# Exploration Exercises" 308 | ] 309 | }, 310 | { 311 | "cell_type": "markdown", 312 | "metadata": { 313 | "id": "rquQqIx4AaGR" 314 | }, 315 | "source": [ 316 | "###Exercise 1:\n", 317 | "For this first exercise run the below code: It creates a set of classifications for each of the test images, and then prints the first entry in the classifications. The output, after you run it is a list of numbers. Why do you think this is, and what do those numbers represent? " 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "metadata": { 323 | "id": "RyEIki0z_hAD" 324 | }, 325 | "source": [ 326 | "classifications = model.predict(test_images)\n", 327 | "\n", 328 | "print(classifications[0])" 329 | ], 330 | "execution_count": null, 331 | "outputs": [] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": { 336 | "id": "MdzqbQhRArzm" 337 | }, 338 | "source": [ 339 | "Hint: try running print(test_labels[0]) -- and you'll get a 9. Does that help you understand why this list looks the way it does? " 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "metadata": { 345 | "id": "WnBGOrMiA1n5" 346 | }, 347 | "source": [ 348 | "print(test_labels[0])" 349 | ], 350 | "execution_count": null, 351 | "outputs": [] 352 | }, 353 | { 354 | "cell_type": "markdown", 355 | "metadata": { 356 | "id": "uUs7eqr7uSvs" 357 | }, 358 | "source": [ 359 | "### What does this list represent?\n", 360 | "\n", 361 | "\n", 362 | "1. It's 10 random meaningless values\n", 363 | "2. It's the first 10 classifications that the computer made\n", 364 | "3. It's the probability that this item is each of the 10 classes\n" 365 | ] 366 | }, 367 | { 368 | "cell_type": "markdown", 369 | "metadata": { 370 | "id": "wAbr92RTA67u" 371 | }, 372 | "source": [ 373 | "####Answer: \n", 374 | "The correct answer is (3)\n", 375 | "\n", 376 | "The output of the model is a list of 10 numbers. These numbers are a probability that the value being classified is the corresponding value (https://github.com/zalandoresearch/fashion-mnist#labels), i.e. the first value in the list is the probability that the image is of a '0' (T-shirt/top), the next is a '1' (Trouser) etc. Notice that they are all VERY LOW probabilities.\n", 377 | "\n", 378 | "For the 9 (Ankle boot), the probability was in the 90's, i.e. the neural network is telling us that it's almost certainly a 7." 379 | ] 380 | }, 381 | { 382 | "cell_type": "markdown", 383 | "metadata": { 384 | "id": "CD4kC6TBu-69" 385 | }, 386 | "source": [ 387 | "### How do you know that this list tells you that the item is an ankle boot?\n", 388 | "\n", 389 | "\n", 390 | "1. There's not enough information to answer that question\n", 391 | "2. The 10th element on the list is the biggest, and the ankle boot is labelled 9\n", 392 | "2. The ankle boot is label 9, and there are 0->9 elements in the list\n" 393 | ] 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "metadata": { 398 | "id": "I-haLncrva5L" 399 | }, 400 | "source": [ 401 | "####Answer\n", 402 | "The correct answer is (2). Both the list and the labels are 0 based, so the ankle boot having label 9 means that it is the 10th of the 10 classes. The list having the 10th element being the highest value means that the Neural Network has predicted that the item it is classifying is most likely an ankle boot" 403 | ] 404 | }, 405 | { 406 | "cell_type": "markdown", 407 | "metadata": { 408 | "id": "OgQSIfDSOWv6" 409 | }, 410 | "source": [ 411 | "##Exercise 2: \n", 412 | "Let's now look at the layers in your model. Experiment with different values for the dense layer with 512 neurons. What different results do you get for loss, training time etc? Why do you think that's the case? \n" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "metadata": { 418 | "id": "GSZSwV5UObQP" 419 | }, 420 | "source": [ 421 | "import tensorflow as tf\n", 422 | "print(tf.__version__)\n", 423 | "\n", 424 | "mnist = tf.keras.datasets.mnist\n", 425 | "\n", 426 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n", 427 | "\n", 428 | "training_images = training_images/255.0\n", 429 | "test_images = test_images/255.0\n", 430 | "\n", 431 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),\n", 432 | " tf.keras.layers.Dense(1024, activation=tf.nn.relu),\n", 433 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])\n", 434 | "\n", 435 | "model.compile(optimizer = 'adam',\n", 436 | " loss = 'sparse_categorical_crossentropy')\n", 437 | "\n", 438 | "model.fit(training_images, training_labels, epochs=5)\n", 439 | "\n", 440 | "model.evaluate(test_images, test_labels)\n", 441 | "\n", 442 | "classifications = model.predict(test_images)\n", 443 | "\n", 444 | "print(classifications[0])\n", 445 | "print(test_labels[0])" 446 | ], 447 | "execution_count": null, 448 | "outputs": [] 449 | }, 450 | { 451 | "cell_type": "markdown", 452 | "metadata": { 453 | "id": "bOOEnHZFv5cS" 454 | }, 455 | "source": [ 456 | "###Question 1. Increase to 1024 Neurons -- What's the impact?\n", 457 | "\n", 458 | "1. Training takes longer, but is more accurate\n", 459 | "2. Training takes longer, but no impact on accuracy\n", 460 | "3. Training takes the same time, but is more accurate\n" 461 | ] 462 | }, 463 | { 464 | "cell_type": "markdown", 465 | "metadata": { 466 | "id": "U73MUP2lwrI2" 467 | }, 468 | "source": [ 469 | "####Answer\n", 470 | "The correct answer is (1) by adding more Neurons we have to do more calculations, slowing down the process, but in this case they have a good impact -- we do get more accurate. That doesn't mean it's always a case of 'more is better', you can hit the law of diminishing returns very quickly!" 471 | ] 472 | }, 473 | { 474 | "cell_type": "markdown", 475 | "metadata": { 476 | "id": "WtWxK16hQxLN" 477 | }, 478 | "source": [ 479 | "##Exercise 3: \n", 480 | "\n", 481 | "What would happen if you remove the Flatten() layer. Why do you think that's the case? \n", 482 | "\n", 483 | "You get an error about the shape of the data. It may seem vague right now, but it reinforces the rule of thumb that the first layer in your network should be the same shape as your data. Right now our data is 28x28 images, and 28 layers of 28 neurons would be infeasible, so it makes more sense to 'flatten' that 28,28 into a 784x1. Instead of wriitng all the code to handle that ourselves, we add the Flatten() layer at the begining, and when the arrays are loaded into the model later, they'll automatically be flattened for us." 484 | ] 485 | }, 486 | { 487 | "cell_type": "code", 488 | "metadata": { 489 | "id": "ExNxCwhcQ18S" 490 | }, 491 | "source": [ 492 | "import tensorflow as tf\n", 493 | "print(tf.__version__)\n", 494 | "\n", 495 | "mnist = tf.keras.datasets.mnist\n", 496 | "\n", 497 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n", 498 | "\n", 499 | "training_images = training_images/255.0\n", 500 | "test_images = test_images/255.0\n", 501 | "\n", 502 | "model = tf.keras.models.Sequential([#tf.keras.layers.Flatten(),\n", 503 | " tf.keras.layers.Dense(64, activation=tf.nn.relu),\n", 504 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])\n", 505 | "\n", 506 | "model.compile(optimizer = 'adam',\n", 507 | " loss = 'sparse_categorical_crossentropy')\n", 508 | "\n", 509 | "model.fit(training_images, training_labels, epochs=5)\n", 510 | "\n", 511 | "model.evaluate(test_images, test_labels)\n", 512 | "\n", 513 | "classifications = model.predict(test_images)\n", 514 | "\n", 515 | "print(classifications[0])\n", 516 | "print(test_labels[0])" 517 | ], 518 | "execution_count": null, 519 | "outputs": [] 520 | }, 521 | { 522 | "cell_type": "markdown", 523 | "metadata": { 524 | "id": "VqoCR-ieSGDg" 525 | }, 526 | "source": [ 527 | "##Exercise 4: \n", 528 | "\n", 529 | "Consider the final (output) layers. Why are there 10 of them? What would happen if you had a different amount than 10? For example, try training the network with 5\n", 530 | "\n", 531 | "You get an error as soon as it finds an unexpected value. Another rule of thumb -- the number of neurons in the last layer should match the number of classes you are classifying for. In this case it's the digits 0-9, so there are 10 of them, hence you should have 10 neurons in your final layer." 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "metadata": { 537 | "id": "MMckVntcSPvo" 538 | }, 539 | "source": [ 540 | "import tensorflow as tf\n", 541 | "print(tf.__version__)\n", 542 | "\n", 543 | "mnist = tf.keras.datasets.mnist\n", 544 | "\n", 545 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n", 546 | "\n", 547 | "training_images = training_images/255.0\n", 548 | "test_images = test_images/255.0\n", 549 | "\n", 550 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),\n", 551 | " tf.keras.layers.Dense(64, activation=tf.nn.relu),\n", 552 | " tf.keras.layers.Dense(5, activation=tf.nn.softmax)])\n", 553 | "\n", 554 | "model.compile(optimizer = 'adam',\n", 555 | " loss = 'sparse_categorical_crossentropy')\n", 556 | "\n", 557 | "model.fit(training_images, training_labels, epochs=5)\n", 558 | "\n", 559 | "model.evaluate(test_images, test_labels)\n", 560 | "\n", 561 | "classifications = model.predict(test_images)\n", 562 | "\n", 563 | "print(classifications[0])\n", 564 | "print(test_labels[0])" 565 | ], 566 | "execution_count": null, 567 | "outputs": [] 568 | }, 569 | { 570 | "cell_type": "markdown", 571 | "metadata": { 572 | "id": "-0lF5MuvSuZF" 573 | }, 574 | "source": [ 575 | "##Exercise 5: \n", 576 | "\n", 577 | "Consider the effects of additional layers in the network. What will happen if you add another layer between the one with 512 and the final layer with 10. \n", 578 | "\n", 579 | "Ans: There isn't a significant impact -- because this is relatively simple data. For far more complex data (including color images to be classified as flowers that you'll see in the next lesson), extra layers are often necessary. " 580 | ] 581 | }, 582 | { 583 | "cell_type": "code", 584 | "metadata": { 585 | "id": "b1YPa6UhS8Es" 586 | }, 587 | "source": [ 588 | "import tensorflow as tf\n", 589 | "print(tf.__version__)\n", 590 | "\n", 591 | "mnist = tf.keras.datasets.mnist\n", 592 | "\n", 593 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n", 594 | "\n", 595 | "training_images = training_images/255.0\n", 596 | "test_images = test_images/255.0\n", 597 | "\n", 598 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),\n", 599 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n", 600 | " tf.keras.layers.Dense(256, activation=tf.nn.relu),\n", 601 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])\n", 602 | "\n", 603 | "model.compile(optimizer = 'adam',\n", 604 | " loss = 'sparse_categorical_crossentropy')\n", 605 | "\n", 606 | "model.fit(training_images, training_labels, epochs=5)\n", 607 | "\n", 608 | "model.evaluate(test_images, test_labels)\n", 609 | "\n", 610 | "classifications = model.predict(test_images)\n", 611 | "\n", 612 | "print(classifications[0])\n", 613 | "print(test_labels[0])" 614 | ], 615 | "execution_count": null, 616 | "outputs": [] 617 | }, 618 | { 619 | "cell_type": "markdown", 620 | "metadata": { 621 | "id": "Bql9fyaNUSFy" 622 | }, 623 | "source": [ 624 | "#Exercise 6: \n", 625 | "\n", 626 | "Consider the impact of training for more or less epochs. Why do you think that would be the case? \n", 627 | "\n", 628 | "Try 15 epochs -- you'll probably get a model with a much better loss than the one with 5\n", 629 | "Try 30 epochs -- you might see the loss value stops decreasing, and sometimes increases. This is a side effect of something called 'overfitting' which you can learn about [somewhere] and it's something you need to keep an eye out for when training neural networks. There's no point in wasting your time training if you aren't improving your loss, right! :)" 630 | ] 631 | }, 632 | { 633 | "cell_type": "code", 634 | "metadata": { 635 | "id": "uE3esj9BURQe" 636 | }, 637 | "source": [ 638 | "import tensorflow as tf\n", 639 | "print(tf.__version__)\n", 640 | "\n", 641 | "mnist = tf.keras.datasets.mnist\n", 642 | "\n", 643 | "(training_images, training_labels) , (test_images, test_labels) = mnist.load_data()\n", 644 | "\n", 645 | "training_images = training_images/255.0\n", 646 | "test_images = test_images/255.0\n", 647 | "\n", 648 | "model = tf.keras.models.Sequential([tf.keras.layers.Flatten(),\n", 649 | " tf.keras.layers.Dense(128, activation=tf.nn.relu),\n", 650 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)])\n", 651 | "\n", 652 | "model.compile(optimizer = 'adam',\n", 653 | " loss = 'sparse_categorical_crossentropy')\n", 654 | "\n", 655 | "model.fit(training_images, training_labels, epochs=30)\n", 656 | "\n", 657 | "model.evaluate(test_images, test_labels)\n", 658 | "\n", 659 | "classifications = model.predict(test_images)\n", 660 | "\n", 661 | "print(classifications[34])\n", 662 | "print(test_labels[34])" 663 | ], 664 | "execution_count": null, 665 | "outputs": [] 666 | }, 667 | { 668 | "cell_type": "markdown", 669 | "metadata": { 670 | "id": "HS3vVkOgCDGZ" 671 | }, 672 | "source": [ 673 | "#Exercise 7: \n", 674 | "\n", 675 | "Before you trained, you normalized the data, going from values that were 0-255 to values that were 0-1. What would be the impact of removing that? Here's the complete code to give it a try. Why do you think you get different results? " 676 | ] 677 | }, 678 | { 679 | "cell_type": "code", 680 | "metadata": { 681 | "id": "JDqNAqrpCNg0" 682 | }, 683 | "source": [ 684 | "import tensorflow as tf\n", 685 | "print(tf.__version__)\n", 686 | "mnist = tf.keras.datasets.mnist\n", 687 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n", 688 | "#training_images=training_images/255.0\n", 689 | "#test_images=test_images/255.0\n", 690 | "model = tf.keras.models.Sequential([\n", 691 | " tf.keras.layers.Flatten(),\n", 692 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n", 693 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n", 694 | "])\n", 695 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')\n", 696 | "model.fit(training_images, training_labels, epochs=5)\n", 697 | "model.evaluate(test_images, test_labels)\n", 698 | "classifications = model.predict(test_images)\n", 699 | "print(classifications[0])\n", 700 | "print(test_labels[0])" 701 | ], 702 | "execution_count": null, 703 | "outputs": [] 704 | }, 705 | { 706 | "cell_type": "markdown", 707 | "metadata": { 708 | "id": "E7W2PT66ZBHQ" 709 | }, 710 | "source": [ 711 | "#Exercise 8: \n", 712 | "\n", 713 | "Earlier when you trained for extra epochs you had an issue where your loss might change. It might have taken a bit of time for you to wait for the training to do that, and you might have thought 'wouldn't it be nice if I could stop the training when I reach a desired value?' -- i.e. 95% accuracy might be enough for you, and if you reach that after 3 epochs, why sit around waiting for it to finish a lot more epochs....So how would you fix that? Like any other program...you have callbacks! Let's see them in action..." 714 | ] 715 | }, 716 | { 717 | "cell_type": "code", 718 | "metadata": { 719 | "id": "pkaEHHgqZbYv" 720 | }, 721 | "source": [ 722 | "import tensorflow as tf\n", 723 | "print(tf.__version__)\n", 724 | "\n", 725 | "class myCallback(tf.keras.callbacks.Callback):\n", 726 | " def on_epoch_end(self, epoch, logs={}):\n", 727 | " if(logs.get('loss')<0.4):\n", 728 | " print(\"\\nReached 60% accuracy so cancelling training!\")\n", 729 | " self.model.stop_training = True\n", 730 | "\n", 731 | "callbacks = myCallback()\n", 732 | "mnist = tf.keras.datasets.fashion_mnist\n", 733 | "(training_images, training_labels), (test_images, test_labels) = mnist.load_data()\n", 734 | "training_images=training_images/255.0\n", 735 | "test_images=test_images/255.0\n", 736 | "model = tf.keras.models.Sequential([\n", 737 | " tf.keras.layers.Flatten(),\n", 738 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n", 739 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n", 740 | "])\n", 741 | "model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')\n", 742 | "model.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])\n" 743 | ], 744 | "execution_count": null, 745 | "outputs": [] 746 | } 747 | ] 748 | } -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Colab Notebooks/Course 1 - Part 4 - Lesson 4 - Notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Course 1 - Part 4 - Lesson 4 - Notebook.ipynb", 7 | "private_outputs": true, 8 | "provenance": [], 9 | "collapsed_sections": [], 10 | "include_colab_link": true 11 | }, 12 | "kernelspec": { 13 | "display_name": "Python 3", 14 | "language": "python", 15 | "name": "python3" 16 | }, 17 | "language_info": { 18 | "codemirror_mode": { 19 | "name": "ipython", 20 | "version": 3 21 | }, 22 | "file_extension": ".py", 23 | "mimetype": "text/x-python", 24 | "name": "python", 25 | "nbconvert_exporter": "python", 26 | "pygments_lexer": "ipython3", 27 | "version": "3.7.5rc1" 28 | } 29 | }, 30 | "cells": [ 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "view-in-github", 35 | "colab_type": "text" 36 | }, 37 | "source": [ 38 | "\"Open" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": { 44 | "id": "rX8mhOLljYeM" 45 | }, 46 | "source": [ 47 | "##### Copyright 2019 The TensorFlow Authors." 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "metadata": { 53 | "cellView": "form", 54 | "id": "BZSlp3DAjdYf" 55 | }, 56 | "source": [ 57 | "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", 58 | "# you may not use this file except in compliance with the License.\n", 59 | "# You may obtain a copy of the License at\n", 60 | "#\n", 61 | "# https://www.apache.org/licenses/LICENSE-2.0\n", 62 | "#\n", 63 | "# Unless required by applicable law or agreed to in writing, software\n", 64 | "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", 65 | "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", 66 | "# See the License for the specific language governing permissions and\n", 67 | "# limitations under the License." 68 | ], 69 | "execution_count": null, 70 | "outputs": [] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "metadata": { 75 | "id": "N9-BCmi15L93" 76 | }, 77 | "source": [ 78 | "import tensorflow as tf\n", 79 | "\n", 80 | "class myCallback(tf.keras.callbacks.Callback):\n", 81 | " def on_epoch_end(self, epoch, logs={}):\n", 82 | " if(logs.get('accuracy')>0.6):\n", 83 | " print(\"\\nReached 60% accuracy so cancelling training!\")\n", 84 | " self.model.stop_training = True\n", 85 | "\n", 86 | "mnist = tf.keras.datasets.fashion_mnist\n", 87 | "\n", 88 | "(x_train, y_train),(x_test, y_test) = mnist.load_data()\n", 89 | "x_train, x_test = x_train / 255.0, x_test / 255.0\n", 90 | "\n", 91 | "callbacks = myCallback()\n", 92 | "\n", 93 | "model = tf.keras.models.Sequential([\n", 94 | " tf.keras.layers.Flatten(input_shape=(28, 28)),\n", 95 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n", 96 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n", 97 | "])\n", 98 | "model.compile(optimizer=tf.optimizers.Adam(),\n", 99 | " loss='sparse_categorical_crossentropy',\n", 100 | " metrics=['accuracy'])\n", 101 | "\n", 102 | "model.fit(x_train, y_train, epochs=10, callbacks=[callbacks])" 103 | ], 104 | "execution_count": null, 105 | "outputs": [] 106 | } 107 | ] 108 | } -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Colab Notebooks/Exercise 2 - Handwriting Recognition.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Copy of Exercise2-Question.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "display_name": "Python 3", 13 | "name": "python3" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "view-in-github", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "\"Open" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "metadata": { 30 | "id": "zX4Kg8DUTKWO" 31 | }, 32 | "source": [ 33 | "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n", 34 | "# you may not use this file except in compliance with the License.\n", 35 | "# You may obtain a copy of the License at\n", 36 | "#\n", 37 | "# https://www.apache.org/licenses/LICENSE-2.0\n", 38 | "#\n", 39 | "# Unless required by applicable law or agreed to in writing, software\n", 40 | "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", 41 | "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", 42 | "# See the License for the specific language governing permissions and\n", 43 | "# limitations under the License." 44 | ], 45 | "execution_count": null, 46 | "outputs": [] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": { 51 | "id": "tOoyQ70H00_s" 52 | }, 53 | "source": [ 54 | "## Exercise 2\n", 55 | "In the course you learned how to do classification 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", 56 | "\n", 57 | "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", 58 | "\n", 59 | "Some notes:\n", 60 | "1. It should succeed in less than 10 epochs, so it is okay to change epochs to 10, but nothing larger\n", 61 | "2. When it reaches 99% or greater it should print out the string \"Reached 99% accuracy so cancelling training!\"\n", 62 | "3. If you add any additional variables, make sure you use the same names as the ones used in the class\n", 63 | "\n", 64 | "I've started the code for you below -- how would you finish it? " 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "metadata": { 70 | "colab": { 71 | "base_uri": "https://localhost:8080/" 72 | }, 73 | "id": "9rvXQGAA0ssC", 74 | "outputId": "684fa0b2-9c38-4e6f-a774-eec8443ab5fc" 75 | }, 76 | "source": [ 77 | "# YOUR CODE SHOULD START HERE\n", 78 | "# YOUR CODE SHOULD END HERE\n", 79 | "import tensorflow as tf\n", 80 | "mnist = tf.keras.datasets.mnist\n", 81 | "\n", 82 | "(x_train, y_train),(x_test, y_test) = mnist.load_data()\n", 83 | "# YOUR CODE SHOULD START HERE\n", 84 | "class myCallback(tf.keras.callbacks.Callback):\n", 85 | " def on_epoch_end(self, epoch, logs={}):\n", 86 | " if(logs.get('accuracy') >= 0.99):\n", 87 | " print(\"\\nReached 99% accuracy so cancelling training!\")\n", 88 | " self.model.stop_training = True\n", 89 | "\n", 90 | "model = tf.keras.datasets.mnist\n", 91 | "\n", 92 | "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", 93 | "x_train, x_test = x_train / 255.0, x_test / 255.0\n", 94 | "\n", 95 | "callbacks = myCallback()\n", 96 | "\n", 97 | "# YOUR CODE SHOULD END HERE\n", 98 | "model = tf.keras.models.Sequential([\n", 99 | "# YOUR CODE SHOULD START HERE\n", 100 | " tf.keras.layers.Flatten(input_shape=(28,28)),\n", 101 | " tf.keras.layers.Dense(128, activation='relu'),\n", 102 | " tf.keras.layers.Dense(10, activation='softmax')\n", 103 | "# YOUR CODE SHOULD END HERE\n", 104 | "])\n", 105 | "\n", 106 | "model.compile(optimizer='adam',\n", 107 | " loss='sparse_categorical_crossentropy',\n", 108 | " metrics=['accuracy'])\n", 109 | "\n", 110 | "# YOUR CODE SHOULD START HERE\n", 111 | "model.fit(x_train, y_train, epochs=10, callbacks=[callbacks])\n", 112 | "# YOUR CODE SHOULD END HERE" 113 | ], 114 | "execution_count": null, 115 | "outputs": [ 116 | { 117 | "output_type": "stream", 118 | "text": [ 119 | "Epoch 1/10\n", 120 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.4269 - accuracy: 0.8795\n", 121 | "Epoch 2/10\n", 122 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.1215 - accuracy: 0.9646\n", 123 | "Epoch 3/10\n", 124 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0815 - accuracy: 0.9750\n", 125 | "Epoch 4/10\n", 126 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0584 - accuracy: 0.9828\n", 127 | "Epoch 5/10\n", 128 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0429 - accuracy: 0.9871\n", 129 | "Epoch 6/10\n", 130 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0350 - accuracy: 0.9898\n", 131 | "Epoch 7/10\n", 132 | "1875/1875 [==============================] - 4s 2ms/step - loss: 0.0269 - accuracy: 0.9919\n", 133 | "\n", 134 | "Reached 99% accuracy so cancelling training!\n" 135 | ], 136 | "name": "stdout" 137 | }, 138 | { 139 | "output_type": "execute_result", 140 | "data": { 141 | "text/plain": [ 142 | "" 143 | ] 144 | }, 145 | "metadata": { 146 | "tags": [] 147 | }, 148 | "execution_count": 5 149 | } 150 | ] 151 | } 152 | ] 153 | } -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Coursera.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palashsharma891/DeepLearning.AI-TensorFlow-Developer-Coursera/5138f4c0863d672eba25cbc60a8136a221caa784/1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/Coursera.pdf -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/utf-8''Excercise-3-Question.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": 26, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "# GRADED FUNCTION: train_mnist_conv\n", 51 | "def train_mnist_conv():\n", 52 | " # Please write your code only where you are indicated.\n", 53 | " # please do not remove model fitting inline comments.\n", 54 | "\n", 55 | " # YOUR CODE STARTS HERE\n", 56 | " class myCallback(tf.keras.callbacks.Callback):\n", 57 | " def on_epoch_end(self, epoch, logs={}):\n", 58 | " if(logs.get('acc') >= 0.998):\n", 59 | " print(\"Reached 99.8% accuracy so cancelling training!\")\n", 60 | " self.model.stop_training = True\n", 61 | " # YOUR CODE ENDS HERE\n", 62 | "\n", 63 | " mnist = tf.keras.datasets.mnist\n", 64 | " (training_images, training_labels), (test_images, test_labels) = mnist.load_data(path=path)\n", 65 | " # YOUR CODE STARTS HERE\n", 66 | " training_images=training_images.reshape(60000, 28, 28, 1)\n", 67 | " test_images = test_images.reshape(10000, 28, 28, 1)\n", 68 | " training_images, test_images = training_images / 255.0, test_images / 255.0\n", 69 | " callbacks = myCallback()\n", 70 | " # YOUR CODE ENDS HERE\n", 71 | "\n", 72 | " model = tf.keras.models.Sequential([\n", 73 | " # YOUR CODE STARTS HERE\n", 74 | " tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28, 28, 1)),\n", 75 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 76 | " tf.keras.layers.Flatten(),\n", 77 | " tf.keras.layers.Dense(128, activation='relu'),\n", 78 | " tf.keras.layers.Dense(10, activation='softmax'),\n", 79 | " # YOUR CODE ENDS HERE\n", 80 | " ])\n", 81 | "\n", 82 | " model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n", 83 | " # model fitting\n", 84 | " history = model.fit(\n", 85 | " # YOUR CODE STARTS HERE\n", 86 | " training_images, training_labels, epochs=20, callbacks=[callbacks]\n", 87 | " # YOUR CODE ENDS HERE\n", 88 | " )\n", 89 | " # model fitting\n", 90 | " return history.epoch, history.history['acc'][-1]\n", 91 | "\n" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 27, 97 | "metadata": {}, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "Epoch 1/20\n", 104 | "60000/60000 [==============================] - 16s 265us/sample - loss: 0.1466 - acc: 0.9563\n", 105 | "Epoch 2/20\n", 106 | "60000/60000 [==============================] - 15s 248us/sample - loss: 0.0523 - acc: 0.9840\n", 107 | "Epoch 3/20\n", 108 | "60000/60000 [==============================] - 15s 244us/sample - loss: 0.0327 - acc: 0.9899\n", 109 | "Epoch 4/20\n", 110 | "60000/60000 [==============================] - 15s 255us/sample - loss: 0.0223 - acc: 0.9930\n", 111 | "Epoch 5/20\n", 112 | "60000/60000 [==============================] - 16s 272us/sample - loss: 0.0157 - acc: 0.9949\n", 113 | "Epoch 6/20\n", 114 | "60000/60000 [==============================] - 16s 263us/sample - loss: 0.0108 - acc: 0.9966\n", 115 | "Epoch 7/20\n", 116 | "60000/60000 [==============================] - 15s 252us/sample - loss: 0.0081 - acc: 0.9973\n", 117 | "Epoch 8/20\n", 118 | "60000/60000 [==============================] - 14s 235us/sample - loss: 0.0071 - acc: 0.9976\n", 119 | "Epoch 9/20\n", 120 | "59936/60000 [============================>.] - ETA: 0s - loss: 0.0059 - acc: 0.9980- ETA: 0s - loss: 0.0060 - acc: 0Reached 99.8% accuracy so cancelling training!\n", 121 | "60000/60000 [==============================] - 15s 250us/sample - loss: 0.0058 - acc: 0.9980\n" 122 | ] 123 | } 124 | ], 125 | "source": [ 126 | "_, _ = train_mnist_conv()" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": null, 132 | "metadata": {}, 133 | "outputs": [], 134 | "source": [ 135 | "# Now click the 'Submit Assignment' button above.\n", 136 | "# Once that is complete, please run the following two cells to save your work and close the notebook" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "%%javascript\n", 146 | "\n", 147 | "IPython.notebook.save_checkpoint();" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": null, 153 | "metadata": {}, 154 | "outputs": [], 155 | "source": [ 156 | "%%javascript\n", 157 | "IPython.notebook.session.delete();\n", 158 | "window.onbeforeunload = null\n", 159 | "setTimeout(function() { window.close(); }, 1000);" 160 | ] 161 | } 162 | ], 163 | "metadata": { 164 | "coursera": { 165 | "course_slug": "introduction-tensorflow", 166 | "graded_item_id": "ml06H", 167 | "launcher_item_id": "hQF8A" 168 | }, 169 | "kernelspec": { 170 | "display_name": "Python 3", 171 | "language": "python", 172 | "name": "python3" 173 | }, 174 | "language_info": { 175 | "codemirror_mode": { 176 | "name": "ipython", 177 | "version": 3 178 | }, 179 | "file_extension": ".py", 180 | "mimetype": "text/x-python", 181 | "name": "python", 182 | "nbconvert_exporter": "python", 183 | "pygments_lexer": "ipython3", 184 | "version": "3.6.8" 185 | } 186 | }, 187 | "nbformat": 4, 188 | "nbformat_minor": 1 189 | } 190 | -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/utf-8''Exercise2-Question.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": 5, 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": 20, 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 | " class myCallback(tf.keras.callbacks.Callback):\n", 55 | " def on_epoch_end(self, epoch, logs={}):\n", 56 | " if(logs.get('acc') >= 0.99):\n", 57 | " print(\"Reached 99% accuracy so cancelling training!\")\n", 58 | " self.model.stop_training = True\n", 59 | " # YOUR CODE SHOULD END HERE\n", 60 | "\n", 61 | " mnist = tf.keras.datasets.mnist\n", 62 | "\n", 63 | " (x_train, y_train),(x_test, y_test) = mnist.load_data(path=path)\n", 64 | " # YOUR CODE SHOULD START HERE\n", 65 | " x_train, x_test = x_train / 255.0, x_test / 255.0\n", 66 | " callbacks = myCallback()\n", 67 | " # YOUR CODE SHOULD END HERE\n", 68 | " model = tf.keras.models.Sequential([\n", 69 | " # YOUR CODE SHOULD START HERE\n", 70 | " tf.keras.layers.Flatten(input_shape=(28, 28)),\n", 71 | " tf.keras.layers.Dense(512, activation=tf.nn.relu),\n", 72 | " tf.keras.layers.Dense(10, activation=tf.nn.softmax)\n", 73 | " # YOUR CODE SHOULD END HERE\n", 74 | " ])\n", 75 | "\n", 76 | " model.compile(optimizer='adam',\n", 77 | " loss='sparse_categorical_crossentropy',\n", 78 | " metrics=['accuracy'])\n", 79 | " \n", 80 | " # model fitting\n", 81 | " history = model.fit(# YOUR CODE SHOULD START HERE\n", 82 | " x_train, y_train, epochs=10, callbacks=[callbacks]\n", 83 | " # YOUR CODE SHOULD END HERE\n", 84 | " )\n", 85 | " # model fitting\n", 86 | " return history.epoch, history.history['acc'][-1]" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 21, 92 | "metadata": { 93 | "colab": {}, 94 | "colab_type": "code", 95 | "id": "9rvXQGAA0ssC" 96 | }, 97 | "outputs": [ 98 | { 99 | "name": "stdout", 100 | "output_type": "stream", 101 | "text": [ 102 | "Epoch 1/10\n", 103 | "60000/60000 [==============================] - 13s 211us/sample - loss: 0.2002 - acc: 0.9413\n", 104 | "Epoch 2/10\n", 105 | "60000/60000 [==============================] - 13s 218us/sample - loss: 0.0802 - acc: 0.9755\n", 106 | "Epoch 3/10\n", 107 | "60000/60000 [==============================] - 13s 212us/sample - loss: 0.0506 - acc: 0.9845\n", 108 | "Epoch 4/10\n", 109 | "60000/60000 [==============================] - 13s 213us/sample - loss: 0.0363 - acc: 0.9884\n", 110 | "Epoch 5/10\n", 111 | "59840/60000 [============================>.] - ETA: 0s - loss: 0.0254 - acc: 0.9919Reached 99% accuracy so cancelling training!\n", 112 | "60000/60000 [==============================] - 12s 203us/sample - loss: 0.0255 - acc: 0.9919\n" 113 | ] 114 | }, 115 | { 116 | "data": { 117 | "text/plain": [ 118 | "([0, 1, 2, 3, 4], 0.99188334)" 119 | ] 120 | }, 121 | "execution_count": 21, 122 | "metadata": {}, 123 | "output_type": "execute_result" 124 | } 125 | ], 126 | "source": [ 127 | "train_mnist()" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 4, 133 | "metadata": {}, 134 | "outputs": [], 135 | "source": [ 136 | "# Now click the 'Submit Assignment' button above.\n", 137 | "# Once that is complete, please run the following two cells to save your work and close the notebook" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [ 146 | "%%javascript\n", 147 | "\n", 148 | "IPython.notebook.save_checkpoint();" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": null, 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "%%javascript\n", 158 | "IPython.notebook.session.delete();\n", 159 | "window.onbeforeunload = null\n", 160 | "setTimeout(function() { window.close(); }, 1000);" 161 | ] 162 | } 163 | ], 164 | "metadata": { 165 | "coursera": { 166 | "course_slug": "introduction-tensorflow", 167 | "graded_item_id": "d6dew", 168 | "launcher_item_id": "FExZ4" 169 | }, 170 | "kernelspec": { 171 | "display_name": "Python 3", 172 | "language": "python", 173 | "name": "python3" 174 | }, 175 | "language_info": { 176 | "codemirror_mode": { 177 | "name": "ipython", 178 | "version": 3 179 | }, 180 | "file_extension": ".py", 181 | "mimetype": "text/x-python", 182 | "name": "python", 183 | "nbconvert_exporter": "python", 184 | "pygments_lexer": "ipython3", 185 | "version": "3.6.8" 186 | } 187 | }, 188 | "nbformat": 4, 189 | "nbformat_minor": 1 190 | } 191 | -------------------------------------------------------------------------------- /1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning/utf-8''Exercise4-Question.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": 11, 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 | " class myCallback(tf.keras.callbacks.Callback):\n", 51 | " def on_epoch_end(self, epoch, logs={}):\n", 52 | " if(logs.get('acc') > 0.999):\n", 53 | " print(\"\\nReached 99.9% accuracy so cancelling training!\")\n", 54 | " self.model.stop_training = True\n", 55 | "\n", 56 | " callbacks = myCallback()\n", 57 | " \n", 58 | " # This Code Block should Define and Compile the Model. Please assume the images are 150 X 150 in your implementation.\n", 59 | " model = tf.keras.models.Sequential([\n", 60 | " tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(150, 150, 3)),\n", 61 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 62 | " tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),\n", 63 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 64 | " tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),\n", 65 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 66 | " tf.keras.layers.Flatten(),\n", 67 | " tf.keras.layers.Dense(512, activation='relu'),\n", 68 | " tf.keras.layers.Dense(1, activation='sigmoid')\n", 69 | " ])\n", 70 | "\n", 71 | " from tensorflow.keras.optimizers import RMSprop\n", 72 | "\n", 73 | " model.compile(loss='binary_crossentropy',\n", 74 | " optimizer=RMSprop(lr=0.001),\n", 75 | " metrics=['accuracy']) # or 'acc'\n", 76 | " \n", 77 | "\n", 78 | " # This code block should create an instance of an ImageDataGenerator called train_datagen \n", 79 | " # And a train_generator by calling train_datagen.flow_from_directory\n", 80 | "\n", 81 | " from tensorflow.keras.preprocessing.image import ImageDataGenerator\n", 82 | "\n", 83 | " train_datagen = ImageDataGenerator(rescale=1/255)\n", 84 | "\n", 85 | " # Please use a target_size of 150 X 150.\n", 86 | " train_generator = train_datagen.flow_from_directory(\n", 87 | " '/tmp/h-or-s/',\n", 88 | " target_size=(150, 150),\n", 89 | " batch_size=128,\n", 90 | " class_mode='binary')\n", 91 | " # Expected output: 'Found 80 images belonging to 2 classes'\n", 92 | "\n", 93 | " # This code block should call model.fit_generator and train for\n", 94 | " # a number of epochs.\n", 95 | " # model fitting\n", 96 | " history = model.fit_generator(\n", 97 | " train_generator,\n", 98 | " steps_per_epoch=8,\n", 99 | " epochs=15,\n", 100 | " verbose=1,\n", 101 | " callbacks=[callbacks])\n", 102 | " # model fitting\n", 103 | " return history.history['acc'][-1]" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 12, 109 | "metadata": {}, 110 | "outputs": [ 111 | { 112 | "name": "stdout", 113 | "output_type": "stream", 114 | "text": [ 115 | "Found 80 images belonging to 2 classes.\n", 116 | "Epoch 1/15\n", 117 | "8/8 [==============================] - 4s 523ms/step - loss: 1.0367 - acc: 0.6203\n", 118 | "Epoch 2/15\n", 119 | "8/8 [==============================] - 3s 326ms/step - loss: 0.5818 - acc: 0.9000\n", 120 | "Epoch 3/15\n", 121 | "8/8 [==============================] - 3s 336ms/step - loss: 0.1696 - acc: 0.9328\n", 122 | "Epoch 4/15\n", 123 | "8/8 [==============================] - 3s 325ms/step - loss: 0.0693 - acc: 0.9781\n", 124 | "Epoch 5/15\n", 125 | "8/8 [==============================] - 3s 338ms/step - loss: 0.0397 - acc: 0.9859\n", 126 | "Epoch 6/15\n", 127 | "7/8 [=========================>....] - ETA: 0s - loss: 0.0146 - acc: 1.0000\n", 128 | "Reached 99.9% accuracy so cancelling training!\n", 129 | "8/8 [==============================] - 3s 338ms/step - loss: 0.0145 - acc: 1.0000\n" 130 | ] 131 | }, 132 | { 133 | "data": { 134 | "text/plain": [ 135 | "1.0" 136 | ] 137 | }, 138 | "execution_count": 12, 139 | "metadata": {}, 140 | "output_type": "execute_result" 141 | } 142 | ], 143 | "source": [ 144 | "# The Expected output: \"Reached 99.9% accuracy so cancelling training!\"\"\n", 145 | "train_happy_sad_model()" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 4, 151 | "metadata": {}, 152 | "outputs": [], 153 | "source": [ 154 | "# Now click the 'Submit Assignment' button above.\n", 155 | "# Once that is complete, please run the following two cells to save your work and close the notebook" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "metadata": {}, 162 | "outputs": [], 163 | "source": [ 164 | "%%javascript\n", 165 | "\n", 166 | "IPython.notebook.save_checkpoint();" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "%%javascript\n", 176 | "IPython.notebook.session.delete();\n", 177 | "window.onbeforeunload = null\n", 178 | "setTimeout(function() { window.close(); }, 1000);" 179 | ] 180 | } 181 | ], 182 | "metadata": { 183 | "coursera": { 184 | "course_slug": "introduction-tensorflow", 185 | "graded_item_id": "1kAlw", 186 | "launcher_item_id": "PNLYD" 187 | }, 188 | "kernelspec": { 189 | "display_name": "Python 3", 190 | "language": "python", 191 | "name": "python3" 192 | }, 193 | "language_info": { 194 | "codemirror_mode": { 195 | "name": "ipython", 196 | "version": 3 197 | }, 198 | "file_extension": ".py", 199 | "mimetype": "text/x-python", 200 | "name": "python", 201 | "nbconvert_exporter": "python", 202 | "pygments_lexer": "ipython3", 203 | "version": "3.6.8" 204 | } 205 | }, 206 | "nbformat": 4, 207 | "nbformat_minor": 1 208 | } 209 | -------------------------------------------------------------------------------- /2. Convolutional Neural Networks in TensorFlow/Coursera.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palashsharma891/DeepLearning.AI-TensorFlow-Developer-Coursera/5138f4c0863d672eba25cbc60a8136a221caa784/2. Convolutional Neural Networks in TensorFlow/Coursera.pdf -------------------------------------------------------------------------------- /2. Convolutional Neural Networks in TensorFlow/utf-8''Exercise_1_Cats_vs_Dogs_Question-FINAL.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 3, 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": 4, 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": 5, 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": 6, 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/testing')\n", 95 | " os.mkdir('/tmp/cats-v-dogs/training/cats')\n", 96 | " os.mkdir('/tmp/cats-v-dogs/training/dogs')\n", 97 | " os.mkdir('/tmp/cats-v-dogs/testing/cats')\n", 98 | " os.mkdir('/tmp/cats-v-dogs/testing/dogs')\n", 99 | "except OSError:\n", 100 | " pass" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 7, 106 | "metadata": { 107 | "colab": {}, 108 | "colab_type": "code", 109 | "id": "zvSODo0f9LaU" 110 | }, 111 | "outputs": [], 112 | "source": [ 113 | "# Write a python function called split_data which takes\n", 114 | "# a SOURCE directory containing the files\n", 115 | "# a TRAINING directory that a portion of the files will be copied to\n", 116 | "# a TESTING directory that a portion of the files will be copie to\n", 117 | "# a SPLIT SIZE to determine the portion\n", 118 | "# The files should also be randomized, so that the training set is a random\n", 119 | "# X% of the files, and the test set is the remaining files\n", 120 | "# SO, for example, if SOURCE is PetImages/Cat, and SPLIT SIZE is .9\n", 121 | "# Then 90% of the images in PetImages/Cat will be copied to the TRAINING dir\n", 122 | "# and 10% of the images will be copied to the TESTING dir\n", 123 | "# Also -- All images should be checked, and if they have a zero file length,\n", 124 | "# they will not be copied over\n", 125 | "#\n", 126 | "# os.listdir(DIRECTORY) gives you a listing of the contents of that directory\n", 127 | "# os.path.getsize(PATH) gives you the size of the file\n", 128 | "# copyfile(source, destination) copies a file from source to destination\n", 129 | "# random.sample(list, len(list)) shuffles a list\n", 130 | "def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):\n", 131 | " # YOUR CODE STARTS HERE\n", 132 | " files = []\n", 133 | " for filename in os.listdir(SOURCE):\n", 134 | " file = SOURCE + filename\n", 135 | " if os.path.getsize(file) > 0:\n", 136 | " files.append(filename)\n", 137 | " else:\n", 138 | " print(filename + \" is zero length, so ignoring.\")\n", 139 | "\n", 140 | " training_length = int(len(files) * SPLIT_SIZE)\n", 141 | " testing_length = int(len(files) - training_length)\n", 142 | " shuffled_set = random.sample(files, len(files))\n", 143 | " training_set = shuffled_set[0:training_length]\n", 144 | " testing_set = shuffled_set[-testing_length:]\n", 145 | "\n", 146 | " for filename in training_set:\n", 147 | " this_file = SOURCE + filename\n", 148 | " destination = TRAINING + filename\n", 149 | " copyfile(this_file, destination)\n", 150 | "\n", 151 | " for filename in testing_set:\n", 152 | " this_file = SOURCE + filename\n", 153 | " destination = TESTING + filename\n", 154 | " copyfile(this_file, destination)\n", 155 | " # YOUR CODE ENDS HERE\n", 156 | "\n", 157 | "\n", 158 | "CAT_SOURCE_DIR = \"/tmp/PetImages/Cat/\"\n", 159 | "TRAINING_CATS_DIR = \"/tmp/cats-v-dogs/training/cats/\"\n", 160 | "TESTING_CATS_DIR = \"/tmp/cats-v-dogs/testing/cats/\"\n", 161 | "DOG_SOURCE_DIR = \"/tmp/PetImages/Dog/\"\n", 162 | "TRAINING_DOGS_DIR = \"/tmp/cats-v-dogs/training/dogs/\"\n", 163 | "TESTING_DOGS_DIR = \"/tmp/cats-v-dogs/testing/dogs/\"\n", 164 | "\n", 165 | "split_size = .9\n", 166 | "split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)\n", 167 | "split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 8, 173 | "metadata": { 174 | "colab": {}, 175 | "colab_type": "code", 176 | "id": "luthalB76ufC" 177 | }, 178 | "outputs": [ 179 | { 180 | "name": "stdout", 181 | "output_type": "stream", 182 | "text": [ 183 | "1350\n", 184 | "1350\n", 185 | "150\n", 186 | "150\n" 187 | ] 188 | } 189 | ], 190 | "source": [ 191 | "print(len(os.listdir('/tmp/cats-v-dogs/training/cats/')))\n", 192 | "print(len(os.listdir('/tmp/cats-v-dogs/training/dogs/')))\n", 193 | "print(len(os.listdir('/tmp/cats-v-dogs/testing/cats/')))\n", 194 | "print(len(os.listdir('/tmp/cats-v-dogs/testing/dogs/')))\n", 195 | "\n", 196 | "# Expected output:\n", 197 | "# 1350\n", 198 | "# 1350\n", 199 | "# 150\n", 200 | "# 150" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 10, 206 | "metadata": { 207 | "colab": {}, 208 | "colab_type": "code", 209 | "id": "-BQrav4anTmj" 210 | }, 211 | "outputs": [], 212 | "source": [ 213 | "# DEFINE A KERAS MODEL TO CLASSIFY CATS V DOGS\n", 214 | "# USE AT LEAST 3 CONVOLUTION LAYERS\n", 215 | "model = tf.keras.models.Sequential([\n", 216 | "# YOUR CODE HERE\n", 217 | " tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(150, 150, 3)),\n", 218 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 219 | " tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),\n", 220 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 221 | " tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),\n", 222 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 223 | " tf.keras.layers.Flatten(),\n", 224 | " tf.keras.layers.Dense(128, activation='relu'),\n", 225 | " tf.keras.layers.Dense(1, activation='sigmoid'),\n", 226 | "])\n", 227 | "\n", 228 | "model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['acc'])" 229 | ] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": {}, 234 | "source": [ 235 | "# NOTE:\n", 236 | "\n", 237 | "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." 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": 19, 243 | "metadata": { 244 | "colab": {}, 245 | "colab_type": "code", 246 | "id": "mlNjoJ5D61N6" 247 | }, 248 | "outputs": [ 249 | { 250 | "name": "stdout", 251 | "output_type": "stream", 252 | "text": [ 253 | "Found 2700 images belonging to 2 classes.\n", 254 | "Found 300 images belonging to 2 classes.\n" 255 | ] 256 | } 257 | ], 258 | "source": [ 259 | "TRAINING_DIR = os.path.join('/tmp/cats-v-dogs', 'training')\n", 260 | "train_datagen = ImageDataGenerator(rescale=1/255)\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,\n", 265 | " batch_size=10,\n", 266 | " class_mode='binary',\n", 267 | " target_size=(150, 150))\n", 268 | "\n", 269 | "VALIDATION_DIR = os.path.join('/tmp/cats-v-dogs', 'testing')\n", 270 | "validation_datagen = ImageDataGenerator(rescale=1/255)\n", 271 | "\n", 272 | "# NOTE: YOU MUST USE A BACTH SIZE OF 10 (batch_size=10) FOR THE \n", 273 | "# VALIDATION GENERATOR.\n", 274 | "validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,\n", 275 | " batch_size=10,\n", 276 | " class_mode='binary',\n", 277 | " target_size=(150, 150))\n", 278 | "\n", 279 | "\n", 280 | "\n", 281 | "# Expected Output:\n", 282 | "# Found 2700 images belonging to 2 classes.\n", 283 | "# Found 300 images belonging to 2 classes." 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": 20, 289 | "metadata": { 290 | "colab": {}, 291 | "colab_type": "code", 292 | "id": "KyS4n53w7DxC" 293 | }, 294 | "outputs": [ 295 | { 296 | "name": "stdout", 297 | "output_type": "stream", 298 | "text": [ 299 | "Epoch 1/2\n", 300 | "270/270 [==============================] - 44s 161ms/step - loss: 0.6604 - acc: 0.6037 - val_loss: 0.8943 - val_acc: 0.5533\n", 301 | "Epoch 2/2\n", 302 | "270/270 [==============================] - 37s 138ms/step - loss: 0.5751 - acc: 0.7070 - val_loss: 0.5240 - val_acc: 0.7533\n" 303 | ] 304 | } 305 | ], 306 | "source": [ 307 | "history = model.fit_generator(train_generator,\n", 308 | " epochs=2,\n", 309 | " verbose=1,\n", 310 | " validation_data=validation_generator)\n" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": 21, 316 | "metadata": { 317 | "colab": {}, 318 | "colab_type": "code", 319 | "id": "MWZrJN4-65RC" 320 | }, 321 | "outputs": [ 322 | { 323 | "data": { 324 | "text/plain": [ 325 | "Text(0.5, 1.0, 'Training and validation loss')" 326 | ] 327 | }, 328 | "execution_count": 21, 329 | "metadata": {}, 330 | "output_type": "execute_result" 331 | }, 332 | { 333 | "data": { 334 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAccAAAEICAYAAAAqQj/TAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAe60lEQVR4nO3deZhdVZ3u8e+bFJkICSmSkIEkdQJRoAFRIqCILYIKwcugCAQnbFEbR9rWq9eRttHWB6/9tLYXpbmOyCSCcrVVFFEUAQ3zoCCkQhJCICETGcj4u3+sfahzVs6pOpVU1anh/TzPebLPPuvsvdaupN6stfdeWxGBmZmZdRjW7AqYmZn1Nw5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9GsAZKGS1ovaWZPlm0mSQdI6vF7uSSdIGlRxfuHJR3bSNld2Ndlkj6xq983q6el2RUw6w2S1le8HQNsBrYX798TET/ozvYiYjswtqfLDgUR8cKe2I6k84C3RMSrKrZ9Xk9s2yzncLRBKSKeD6eiZ3JeRPy6XnlJLRGxrS/qZtYV/31sPg+r2pAk6SJJV0u6UtKzwFskvUzS7ZLWSHpS0lcl7VGUb5EUktqK95cXn/9c0rOSbpNU6m7Z4vOTJD0iaa2kr0m6VdK5derdSB3fI+lRSaslfbXiu8Ml/bukZyQtBE7s5Ph8UtJV2bqvS/pKsXyepL8U7Xms6NXV29ZSSa8qlsdI+n5RtweBI7Kyn5K0sNjug5JOKdYfCvwncGwxZL2y4theWPH9fyza/oykH0ua2six6c5xLtdH0q8lrZK0XNL/rNjPp4tjsk7SAknTag1hS/pD+edcHM9biv2sAj4laY6km4t9rCyO2/iK788q2rii+Pw/JI0q6nxQRbmpkjZK2qdee21nDkcbyk4HrgDGA1cD24APAROBY0jh8Z5Ovn8O8GmgFVgM/Gt3y0qaDFwDfLTYbztwZCfbaaSO80ih82JS6J9QrD8feC3wIuClwJmd7OdK4PWS9izq2QK8iXS8AJ4CTgbGAe8CvibpsE62V/Y5YAYwu6jn27PPHynaNR74PHCFpH0j4n7g/cDvI2JsREzMNyzptcX2zwCmA8uAfPi83rHJ1T3ORUD9Gvh/wFTgBcBvi+99tNj/icDewHnAc50dkAovB/4CTAK+BAi4CJgCHEw6Zp8u6tAC/Ax4FGgjHdNrIuI50t+nt1Rs9xzglxHxTIP1MICI8MuvQf0CFgEnZOsuAn7Txfc+AvywWG4BAmgr3l8OfKOi7CnAA7tQ9h9Iv/DLnwl4Eji3wbbVquPRFZ9fB3ykWL6FNLxc/mxe+hVQd9u3A+cUyycBD3dS9qfA+4rlE4BFFZ8tBV5VLC+u/FkA760sW2O7DwAnF8vnAb/NPr8cuLBY/i7whYrPxpHOM+/X1bHp5nF+K/DnOuUeK9c3W39AfqyBP5R/zkXbFnZRhzPK+wWOBZYDw2uUO4b0nywV7+8B3tDT/64G+8s9RxvKllS+kXSgpJ8Vw2TrSL2QnXooFZZXLG+k84tw6pWdVlmPSL/NltbbSIN1bGhfwOOd1BdSL3F+sXwOHb1GJL1e0h3FkN8aUo+0s2NVNrWzOkg6V9K9xdDgGuDABrcLqX3Pby8i1gGrSb3IsoZ+Zl0c5xmkEKyls8+6kv99nCLpGklPFHX4TlaHRZEu/qoSEbeSer6vkHQIMJPUy7RucDjaUJbfxvBNUk/lgIgYB3yG1JPrTU+SejYASBLVv8xzu1PHJ0m/VMu6utXkGuAESdOBUynCUdJo4Frg34B9I2Jv4MYG67G8Xh0kzQYuIQ3/7lNs968V2+3qtpNlwKyK7e0FTACeaKBeuc6O8xJg/zrfq/fZhqJOYyrWTcnK5O37Eukq60OLOpyb1WGWpOF16vE90tDqW0nDrZvrlLM6HI5mHfYC1gIbigsaOjvf2FN+CrxE0v8oziN9iHTOqTfqeA1wgaTpxcUZH+uscEQsJw39fYc0pPq34qORwAhgBbBd0uuB47tRh09I2lvpPtD3V3w2lhQQK0j/T3gXqedY9hSwX+WFMZkrgXdKOkzSSFJ4/z4i6vbEO9HZcb4BmCnp/ZJGShonqXye+DLgIkn7KzlcUivpPwXLSec5h0t6NxVB3kkdNgBrJc0gDe2W3QY8A3xB6SKn0ZKOqfj8+6Rh2HNIQWnd5HA06/DPpAtEniX1HK7u7R1GxFPAWcBXSL/s9gfuJvUYerqOlwA3AfcDfyb1/rpyBekc4vNDqhGxBvgn4HpgFemX8E8brMNnST3YRcDPqfjFHRH3AV8D/lSUeSFwR8V3fwX8DXhKUuXwaPn7vyANf15ffH8m8OYG65Wre5wjYi3wGuCNpMB+BPj74uOLgR+TjvM64FJgVDFc/i7gE8BK0jnIyrbV8lnSxVlrSYH8o4o6bANeDxxE6kUuJv0cyp8vIv2cN0fEH7vZdqPjhK2Z9QPFMNky4IyI+H2z62MDl6TvkS7yubDZdRmIPAmAWZNJOpF0Zegm4H8BW0m9J7NdUpy/PRU4tNl1Gag8rGrWfK8AFpLOtb0OON0XUNiukvRvwL2k21oWN7s+A5WHVc3MzDLuOZqZmWV8znGQmDhxYrS1tTW7GmZmA8add965MiJq3jrlcBwk2traWLBgQbOrYWY2YEiqO0uUh1XNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDKdhqOkmyW9Llt3gaRLuvje+uLPaZJqTm4s6beS5naxnQsqH/Ei6b8l7d3Zd7pD0j2Sruqp7ZmZ2eDQVc/xSuDsbN3ZxfouRcSyiDij65J1XQA8H44RMa94IsBuKx5DMxw4VtKePbHNOvvx7TJmZgNMV+F4LXCypBEAktpIT9v+vaSxkm6SdJek+yWdmn9ZUpukB4rl0ZKukvQXSdcDoyvKXSJpgaQHJf1Lse6Dxb5ulnRzsW6RpInF8oclPVC8LqjY318k/VexrRuLB7PWMp/0zLMbSRP0lutygKRfF08jv0vS/sX6jxXtvFfSF4t1z/d+JU2UtKhYPlfSDZJ+A9zU2bGS9DZJ9xXb/b6kvSS1l59ZVzwr7vn3ZmbW+zrt1UTEKkl/Ak4CfkLqNV4TESHpOdIEyeuKwLpd0g1Rf7LW84GNEXGQpMOAuyo++2Sxr+GkMDksIr4q6cPAcRGxsnJDko4A3gEcRXoy9h2SfgesBuYA8yPiXZKuIT1z7fIa9TmL9Ey2A4EP0PG8uh8AX4yI6yWNAoZJOokUoEdFxMbi4aVdeQlwWNGullrHCjgY+BTw8ohYKak1Ip6V9FvgZNJz4c4GrouIrfkOigemvhtg5syuHupuZmaNauSCnMqh1cohVZGeQn0f8GtgOrBvJ9t5JUVIFQ81va/iszMl3UV6yOvfkUKjM68Aro+IDRGxHrgOOLb4rD0i7imW7wTa8i8Xvb2VxYz1NwEvltQqaS9gekRcX9TzuYjYSHrY67eLZSJiVRf1A/hVRbl6x+rVwA/L4V9R/jJS+FP8+e1aO4iISyNibkTMnTSps4fHm5lZdzQSjj8Bjpf0EmBMRNxZrH8zMAk4IiIOJz0Re1R3KyCpBHwEOD4iDgN+tivbqVD5qJ/t1O4dzwcOLIZBHwPGkXqY3bWNjmOY13lDxXK3jlVE3Aq0SXoVMDwiHtiFupmZ2S7qMhyLntnNwLeovhBnPPB0RGyVdBwwq4tN3QKcAyDpEOCwYv04UpCslbQvaQi37Flgrxrb+j1wmqQxxcU0pxfruiRpGHAmcGhEtEVEG2nIdH5EPAsslXRaUXZkcbXsr4B3lK+crRhWXQQcUSx3duFRvWP1G+BNkvbJtgvwPdJQb81eo5mZ9Z5G73O8EngR1eH4A2CupPuBtwF/7WIblwBjJf0F+BxpyJOIuJc0nPpXUhjcWvGdS4FflC/IKYuIu4DvkJ6WfgdwWUTc3WBbjgWeiIhlFetuAQ6WNBV4K/DBYgj0j8CUiPgFcAOwQNI9pJ4uwJeB8yXdDUzsZJ81j1VEPAh8HvidpHuBr2TfmUCDVwabmVnP8cOO+ylJZwCnRsRbGyk/d+7c8FM5zMwaJ+nOiKh5v73vweuHJH2NNLw8r9l1MTMbihyO/VBEfKDZdTAzG8o8t6qZmVnG4WhmZpZxOJqZmWUcjmZmZhmHo5mZWcbhaGZmlnE4mpmZZRyOZmZmGYejmZlZxuFoZmaWcTiamZllHI5mZmYZh6OZmVnG4WhmZpZxOJqZmWUcjmZmZhmHo5mZWcbhaGZmlnE4mpmZZRyOZmZmGYejmZlZxuFoZmaWcTiamZllHI5mZmYZh6OZmVnG4WhmZpZxOJqZmWUcjmZmZhmHo5mZWcbhaGZmlnE4mpmZZRyOZmZmGYejmZlZxuFoZmaWcTiamZllHI5mZmYZh6OZmVnG4WhmZpZxOJqZmWUcjmZmZpmWZlfAzMysK5s3w6JF0N7e8Vq4EHbsgOuu6/n9ORzNzKzpduyAJ57YOfzKy8uWQURH+ZEjoa0NDjqod+rjcDQzs14XAatW1Q+/xx+HLVs6ykuw334weza85jVQKqXX7NnpzylTYFgvnhh0OJqZWY/YuLF66LMy/NrbYd266vL77JPC7sUvhje8oTr8Zs6EESOa0gzA4WhmZg3atg2WLq0ffsuXV5cfPboj7F75yurwK5Vgr72a045GOBzNzAxIQ58rVtQPv8WLU0CWDR+eenilEpx88s7hN3lyGh4diByOZmZDyPr19cOvvR02bKguv+++KeiOOgrOPrs6/GbMgJZBmiKDtFlmZkPT1q2ph1cr/BYuhJUrq8uPHZsCb//94YQTqsOvrQ323LMpzWg6h6OZ2QASkc7t1er9LVyYzgnu2NFRvqUlhVyptPNFL6VSuihmoA599iaHo5lZP7N2bedDn889V11+2rT6F71Mn57ODQ5IW7fC6tXpHpDVq3d+rVqV0v/ii3t81w5HM7M+tnlzuq+v3tDn6tXV5cePT4F30EEwb151+M2ala4K7be2basfbF2tz0+A5saOTQfB4Whm1v/t2JFmdKkXfvVmeymV4Mgjq8OvVIIJE5rWlGT7dlizputwq7Xu2Wc73/aYMdDamho5YUJqfHm5cn2+bu+9YY89eq3JDkczs26KSL/364VfvdleSqWdL3oplWDq1N6d7QVIib12beO9tsp1+d37udGjqwNs5kw4/PCdg61W4DXzTv9OOBzNzGrYtCnN9lIr/OrN9lIqpUw4/fTqAJw5M/UOd9uOHWnH3Qm28vLatdXd1dzIkdWhNX06HHJI58FWfo0a1QON618cjmY2JG3fnq7srBd+tWZ7KYfdscfu3PsbN67BHUekocbunn9bvToNbVZeiprbY4/qEJsyJZ2o7CzYyuv79YnLvudwNLNBKSLd01cv/GrN9jJjRgq6/KKXUindDP/8LQ8R6WKRcmjd1eD5t/Jr+/b6FW9pqQ6viRNhzpzOz7+VX2PG+L6MHuJwNLMBq3K2l1q3PuQXO06e3HHRy9lnBaX9tlBqXUdp/DPMGLmCPZ5dVR1uf1wNP6sTeJXJmhs2bOcQq7zQpLNhyrFjHXD9gMPRzPqtytleaoXfihXV5ceO3kZp8kZmt67hhCNWUhq9nNIeSynRTtvWvzF23bIUbDevhutWV181k5PSFZGVITZzZtfn31pb04zaDrgBzeFoZk3z/GwvD2+h/cGNtD+yhYWPBe2Lh9P+5CiWPDOGHdFxGWeLtjFr5HJKwxdzejxGqeURStseoUQ7s1nIPpueQY8Dj1fspBxwlReadHWbwIQJ6SRir19Cav2Vw9HMekad2UzWLtuQenpLWmhfPpqFK8fRvraV9o2TWbRlGptiNDCieMFUllHiUY5lISXa02vM08yesJrpEzczvHV8FmyHw4Tjagfe+PEDeHoYayaHo5l12IXZTDav2sDjq/aifdO+tFNiIbPLkUY7R7GKfap2MX7YOkpjnuLA1hXM2+dRSpM3UJq+hVJb0HZAC6P3HVeE29Ew4aTU8xusj36wfst/48wGm3w2k+7c8F1jNpMdiGVMS2E34kAWjjyE9uEH0L5jFu1bpvPEc60EHcOPI1q207bvJkr7bePI2VCas57SQaMozWkprkkZB4wD5vTdMTHrJoejWX/U1WwmnQVeN2cziRkzWX3QMbRrNu3bZ7LwuWm0r59E+5oJtK8cy6InR7JlaxF+W0Bb02m7UgmOz253mD0bpk4dzrBhY3v/GJn1IoejWW/pq9lMWlu7nM1k0+hWFq2fSPuq8SxcOqL66s/7ds7T1tYUdi86Ck7Lwq/HZnsx68ccjmadGSCzmZRne6m61eHPHe9rzfbS1pbC7hWvqA6/bs32YjZIORxt8MtnM+nOMGU/mc2kPNtLezssvGXn+/7y2V6GDUuzvcyenWZ7ycOvarYXM9uJw9EGhog0E3R3nyYwgGYz2bCh/lMeas32MmlSquaRR8JZZ1WH34wZvfo0H7NBz+FofWvTpu5dXFL5vpHZTCoDrJ/NZrJ1KyxZUj/88tle9tyzI/COP746/NraUi6bWe9wOFr3bd7cvV5b5brNmzvfdq3ZTLo6/9ZPZjOJgKeeqh9+S5ZUn4JsaUn5PXs2nHbazkOfEyd66NOsWRyOQ1kEPPxw94cpN23qfLvjxlWHWPkik66GKAfAbCbr1tUPv0WLdj40U6bUv+hl+nTf227WX/mf5lAmpSez1urNjR1bHWJz5nQdbq2tKeAG8G/8zZvTU9zrTXS9alV1+XHjUtgdeCCcdNLOQ59+RJ7ZwDRwf4tZz7jiio6bwsuBt/feg/Zqjh07YNmy+uH3xBPVtxeOGJFCrlSCl760OvxKpXS4PPRpNvg4HIe6N7yh2TXocatXVwde5fLjj1d3lKWO2V5e/eqdw2/atKafyjSzJnA42oCzaVM6v1ev97d2bXX58mwvhx0Gp55aHX6zZnm2FzPbmcPR+p3K2V5qhd+TT1aXHzWqI+yOOaY6/EqldBrUzKw7HI7W5ypne6kVfosXp3sCy8qzvZRKcOKJOw99Tpni835m1rMcjtYryrO91Aq/9nZYv766/KRJKejmzoU3vak6/GbOHLTXB5lZP+VwtF1Snu2lXvg9/XR1+fJsL6USHHfczkOfnu3FzPoTh6PVVJ7tpV74LVlSPR93ebaXUglOOWXn8Js0yUOfZjZwOByHsB074P77a4dfe3vt2V5KJXj5y3cOv/32G9D3/puZVfGvsyHuqKM67vsbNy4F3Qte0HHhS/nV1paesGRmNhQ4HIewYcPguutg8uSOJzR56NPMzOE45M2b1+wamJn1P54Yy8zMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDIORzMzs4zD0czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDIORzMzs4zD0czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDIORzMzs4zD0czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDIORzMzs4zD0czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDIORzMzs4zD0czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDIORzMzs4zD0czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDIORzMzs4zD0czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7OMw9HMzCzjcDQzM8s4HM3MzDIORzMzs4zD0czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwyDkczM7PMboejpH0k3VO8lkt6ouL9iAa38W1JL+yizPskvXl361uxvX0lbZN0Xk9t08zMBoeW3d1ARDwDHA4g6UJgfUR8ubKMJAGKiB11tvGOBvbz9d2ta+ZM4DZgPnBZD2/7eZJaImJbb23fzMx6Xq8Nq0o6QNJDkn4APAhMlXSppAWSHpT0mYqyf5B0uKQWSWskfVHSvZJukzS5KHORpAsqyn9R0p8kPSzp5cX6PSX9qNjvtcW+Dq9TxfnABcBsSVMr6nKypLuK/d9YrNtL0ncl3Ve8TivXteJ7Z0u6rFi+XNIlkv4EfEHS0UVb7pZ0q6Q5RbkWSf8u6YFiu++V9FpJ11Zs9yRJP+yJn4mZmTVmt3uOXTgQeFtELACQ9PGIWCWpBbhZ0rUR8VD2nfHA7yLi45K+AvwD8MUa21ZEHCnpFOAzwInAB4DlEfFGSS8C7qpVKUltQGtE3FkEz5nAf0iaAlwCHBsRj0tqLb5yIbAiIg4resF7N9D2qcDREbFD0vhim9sknQhcBJwFnA9MA14UEduL/a0B/lPSPkWv/B3At+q0493AuwFmzpzZQJXMzKwRvX1BzmPlYCzMl3QXKbQOAg6u8Z1NEfHzYvlOoK3Otq+rUeYVwFUAEXEvqcday9nA1cXyVaReJMDLgJsj4vFiG6uK9ScAXy/WRUSsrrPdSj+sGEbeG/iRpAeALwN/V7Hdb0TE9vL+iu/8ADinCMsjgBtr7SAiLo2IuRExd9KkSQ1UyczMGtHbPccN5YViKPFDwJERsUbS5cCoGt/ZUrG8nfp13NxAmXrmAxMlvb14P03S7G5uYwegivd5WzZULH8e+GVE/B9JBwC/6GLb3wJ+VCxfXQ5PMzPrG315K8c44FlgXXGO73W9sI9bSUOkSDqUGj1TSQcDLRExPSLaIqINuJjUm/wjcJykWUXZ8rDqr4D3FeskaULRw1staY6kYcDpndRrPPBEsXxuxfpfAf8oaXjl/iJiCbAS+Djwne4cADMz2319GY53AQ8BfwW+RwqynvY1YLqkh4DPFvtbm5WZD1yfrfsRMD8iniKdB/yJpHtJw5sA/wLsWwyL3gMcW6z/GPBLUqgu7aReXwIuLoaUK3ub3wSWA/cV+zuz4rMrgPaIeKTzJpuZWU9TRDS7Dj2muNCnJSKeK4ZxbwTmDMRbKSR9A7gtIr7bSPm5c+fGggULui5oZmYASLozIubW+qy3zzn2tbHATUVICnjPAA3Ge4DVwAebXRczs6FoUIVjRKwhXd05oEVEvXszzcysD3huVTMzs4zD0czMLDOoLsgZyiStAB7fxa9PJN06MpS4zYPfUGsvuM3dNSsias6g4nA0JC2od8XWYOU2D35Drb3gNvckD6uamZllHI5mZmYZh6MBXNrsCjSB2zz4DbX2gtvcY3zO0czMLOOeo5mZWcbhaGZmlnE4DiGSTpT0sKRHJX28xucjJV1dfH6HpLa+r2XPaaC9H5b0kKT7JN1UflTZQNZVmyvKvVFSSBrwl/030mZJZxY/6wclXdHXdexpDfzdninpZkl3F3+/5zWjnj1F0rckPV08GanW55L01eJ43CfpJbu904jwawi8gOHAY8BsYARwL3BwVua9wDeK5bNJD1puet17sb3HAWOK5fMHcnsbbXNRbi/gFuB2YG6z690HP+c5wN3AhOL95GbXuw/afClwfrF8MLCo2fXezTa/EngJ8ECdz+cBPyc9cOJo4I7d3ad7jkPHkcCjEbEwIrYAVwGnZmVOBcqPyLoWOF6SGJi6bG9E3BwRG4u3twP79XEde1ojP2OAfyU9Y/S5vqxcL2mkze8Cvh4RqwEi4uk+rmNPa6TNQXrAPKSHrS/rw/r1uIi4BVjVSZFTge9Fcjuwt6Spu7NPh+PQMR1YUvF+abGuZplIj/paC+zTJ7XreY20t9I7Sf/zHMi6bHMx3DQjIn7WlxXrRY38nF8AvEDSrZJul3Rin9WudzTS5guBt0haCvw38IG+qVrTdPffe5cG1SOrzHaFpLcAc4G/b3ZdepOkYcBXgHObXJW+1kIaWn0VaXTgFkmHRnrE3WA1H/hORPxvSS8Dvi/pkIjY0eyKDRTuOQ4dTwAzKt7vV6yrWaZ4YPR44Jk+qV3Pa6S9SDoB+CRwSkRs7qO69Zau2rwXcAjwW0mLSOdmbhjgF+U08nNeCtwQEVsjoh14hBSWA1UjbX4ncA1ARNwGjCJN0D1YNfTvvTscjkPHn4E5kkqSRpAuuLkhK3MD8PZi+QzgN1Gc7R6AumyvpBcD3yQF40A/DwVdtDki1kbExIhoi4g20nnWUyJiQXOq2yMa+Xv9Y1KvEUkTScOsC/uykj2skTYvBo4HkHQQKRxX9Gkt+9YNwNuKq1aPBtZGxJO7s0EPqw4REbFN0vuBX5KudvtWRDwo6XPAgoi4Afi/pOGXR0knv89uXo13T4PtvRgYC/ywuO5ocUSc0rRK76YG2zyoNNjmXwKvlfQQsB34aEQM1BGRRtv8z8B/Sfon0sU55w7g/+gi6UrSf3AmFudRPwvsARAR3yCdV50HPApsBN6x2/scwMfLzMysV3hY1czMLONwNDMzyzgczczMMg5HMzOzjMPRzMws43A0MzPLOBzNzMwy/x+Jn+pZBcp6+AAAAABJRU5ErkJggg==\n", 335 | "text/plain": [ 336 | "
" 337 | ] 338 | }, 339 | "metadata": { 340 | "needs_background": "light" 341 | }, 342 | "output_type": "display_data" 343 | }, 344 | { 345 | "data": { 346 | "image/png": "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\n", 347 | "text/plain": [ 348 | "
" 349 | ] 350 | }, 351 | "metadata": { 352 | "needs_background": "light" 353 | }, 354 | "output_type": "display_data" 355 | } 356 | ], 357 | "source": [ 358 | "# PLOT LOSS AND ACCURACY\n", 359 | "%matplotlib inline\n", 360 | "\n", 361 | "import matplotlib.image as mpimg\n", 362 | "import matplotlib.pyplot as plt\n", 363 | "\n", 364 | "#-----------------------------------------------------------\n", 365 | "# Retrieve a list of list results on training and test data\n", 366 | "# sets for each training epoch\n", 367 | "#-----------------------------------------------------------\n", 368 | "acc=history.history['acc']\n", 369 | "val_acc=history.history['val_acc']\n", 370 | "loss=history.history['loss']\n", 371 | "val_loss=history.history['val_loss']\n", 372 | "\n", 373 | "epochs=range(len(acc)) # Get number of epochs\n", 374 | "\n", 375 | "#------------------------------------------------\n", 376 | "# Plot training and validation accuracy per epoch\n", 377 | "#------------------------------------------------\n", 378 | "plt.plot(epochs, acc, 'r', \"Training Accuracy\")\n", 379 | "plt.plot(epochs, val_acc, 'b', \"Validation Accuracy\")\n", 380 | "plt.title('Training and validation accuracy')\n", 381 | "plt.figure()\n", 382 | "\n", 383 | "#------------------------------------------------\n", 384 | "# Plot training and validation loss per epoch\n", 385 | "#------------------------------------------------\n", 386 | "plt.plot(epochs, loss, 'r', \"Training Loss\")\n", 387 | "plt.plot(epochs, val_loss, 'b', \"Validation Loss\")\n", 388 | "\n", 389 | "\n", 390 | "plt.title('Training and validation loss')\n", 391 | "\n", 392 | "# Desired output. Charts with training and validation metrics. No crash :)" 393 | ] 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "metadata": {}, 398 | "source": [ 399 | "# Submission Instructions" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": null, 405 | "metadata": {}, 406 | "outputs": [], 407 | "source": [ 408 | "# Now click the 'Submit Assignment' button above." 409 | ] 410 | }, 411 | { 412 | "cell_type": "markdown", 413 | "metadata": {}, 414 | "source": [ 415 | "# 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. " 416 | ] 417 | }, 418 | { 419 | "cell_type": "code", 420 | "execution_count": null, 421 | "metadata": {}, 422 | "outputs": [], 423 | "source": [ 424 | "%%javascript\n", 425 | "\n", 426 | "IPython.notebook.save_checkpoint();" 427 | ] 428 | }, 429 | { 430 | "cell_type": "code", 431 | "execution_count": null, 432 | "metadata": {}, 433 | "outputs": [], 434 | "source": [ 435 | "%%javascript\n", 436 | "IPython.notebook.session.delete();\n", 437 | "window.onbeforeunload = null\n", 438 | "setTimeout(function() { window.close(); }, 1000);" 439 | ] 440 | } 441 | ], 442 | "metadata": { 443 | "accelerator": "GPU", 444 | "colab": { 445 | "collapsed_sections": [], 446 | "name": "Exercise 5 - Question.ipynb", 447 | "provenance": [] 448 | }, 449 | "coursera": { 450 | "course_slug": "convolutional-neural-networks-tensorflow", 451 | "graded_item_id": "laIUG", 452 | "launcher_item_id": "jjQWM" 453 | }, 454 | "kernelspec": { 455 | "display_name": "Python 3", 456 | "language": "python", 457 | "name": "python3" 458 | }, 459 | "language_info": { 460 | "codemirror_mode": { 461 | "name": "ipython", 462 | "version": 3 463 | }, 464 | "file_extension": ".py", 465 | "mimetype": "text/x-python", 466 | "name": "python", 467 | "nbconvert_exporter": "python", 468 | "pygments_lexer": "ipython3", 469 | "version": "3.6.8" 470 | } 471 | }, 472 | "nbformat": 4, 473 | "nbformat_minor": 1 474 | } 475 | -------------------------------------------------------------------------------- /2. Convolutional Neural Networks in TensorFlow/utf-8''Exercise_2_Cats_vs_Dogs_using_augmentation_Question-FINAL.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 64, 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": 65, 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": 66, 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": 67, 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/testing')\n", 98 | " os.mkdir('/tmp/cats-v-dogs/training/cats')\n", 99 | " os.mkdir('/tmp/cats-v-dogs/training/dogs')\n", 100 | " os.mkdir('/tmp/cats-v-dogs/testing/cats')\n", 101 | " os.mkdir('/tmp/cats-v-dogs/testing/dogs')\n", 102 | "except OSError:\n", 103 | " pass" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 68, 109 | "metadata": { 110 | "colab": {}, 111 | "colab_type": "code", 112 | "id": "zvSODo0f9LaU" 113 | }, 114 | "outputs": [], 115 | "source": [ 116 | "# Write a python function called split_data which takes\n", 117 | "# a SOURCE directory containing the files\n", 118 | "# a TRAINING directory that a portion of the files will be copied to\n", 119 | "# a TESTING directory that a portion of the files will be copie to\n", 120 | "# a SPLIT SIZE to determine the portion\n", 121 | "# The files should also be randomized, so that the training set is a random\n", 122 | "# X% of the files, and the test set is the remaining files\n", 123 | "# SO, for example, if SOURCE is PetImages/Cat, and SPLIT SIZE is .9\n", 124 | "# Then 90% of the images in PetImages/Cat will be copied to the TRAINING dir\n", 125 | "# and 10% of the images will be copied to the TESTING dir\n", 126 | "# Also -- All images should be checked, and if they have a zero file length,\n", 127 | "# they will not be copied over\n", 128 | "#\n", 129 | "# os.listdir(DIRECTORY) gives you a listing of the contents of that directory\n", 130 | "# os.path.getsize(PATH) gives you the size of the file\n", 131 | "# copyfile(source, destination) copies a file from source to destination\n", 132 | "# random.sample(list, len(list)) shuffles a list\n", 133 | "def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):\n", 134 | " # YOUR CODE STARTS HERE\n", 135 | " files = []\n", 136 | " for filename in os.listdir(SOURCE):\n", 137 | " file = SOURCE + filename\n", 138 | " if os.path.getsize(file) > 0:\n", 139 | " files.append(filename)\n", 140 | " else:\n", 141 | " print(filename + \" is zero length, so ignoring.\")\n", 142 | " \n", 143 | " training_length = int(len(files) * SPLIT_SIZE) # creating two sets of given size, first finding length of sets\n", 144 | " testing_length = int(len(files) - training_length)\n", 145 | " shuffled_set = random.sample(files, len(files))\n", 146 | " training_set = shuffled_set[0:training_length] # storing source files into the two sets\n", 147 | " testing_set = shuffled_set[-testing_length:]\n", 148 | " \n", 149 | " for filename in training_set: # here we are copying the relevant files from the original source\n", 150 | " this_file = SOURCE + filename\n", 151 | " destination = TRAINING + filename\n", 152 | " copyfile(this_file, destination)\n", 153 | " \n", 154 | " for filename in testing_set:\n", 155 | " this_file = SOURCE + filename\n", 156 | " destination = TESTING + filename\n", 157 | " copyfile(this_file, destination)\n", 158 | " # YOUR CODE ENDS HERE\n", 159 | "\n", 160 | "\n", 161 | "CAT_SOURCE_DIR = \"/tmp/PetImages/Cat/\"\n", 162 | "TRAINING_CATS_DIR = \"/tmp/cats-v-dogs/training/cats/\"\n", 163 | "TESTING_CATS_DIR = \"/tmp/cats-v-dogs/testing/cats/\"\n", 164 | "DOG_SOURCE_DIR = \"/tmp/PetImages/Dog/\"\n", 165 | "TRAINING_DOGS_DIR = \"/tmp/cats-v-dogs/training/dogs/\"\n", 166 | "TESTING_DOGS_DIR = \"/tmp/cats-v-dogs/testing/dogs/\"\n", 167 | "\n", 168 | "split_size = .9\n", 169 | "split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)\n", 170 | "split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": 69, 176 | "metadata": { 177 | "colab": {}, 178 | "colab_type": "code", 179 | "id": "luthalB76ufC" 180 | }, 181 | "outputs": [ 182 | { 183 | "name": "stdout", 184 | "output_type": "stream", 185 | "text": [ 186 | "1350\n", 187 | "1350\n", 188 | "150\n", 189 | "150\n" 190 | ] 191 | } 192 | ], 193 | "source": [ 194 | "print(len(os.listdir('/tmp/cats-v-dogs/training/cats/')))\n", 195 | "print(len(os.listdir('/tmp/cats-v-dogs/training/dogs/')))\n", 196 | "print(len(os.listdir('/tmp/cats-v-dogs/testing/cats/')))\n", 197 | "print(len(os.listdir('/tmp/cats-v-dogs/testing/dogs/')))\n", 198 | "\n", 199 | "# Expected output:\n", 200 | "# 1350\n", 201 | "# 1350\n", 202 | "# 150\n", 203 | "# 150" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": 91, 209 | "metadata": { 210 | "colab": {}, 211 | "colab_type": "code", 212 | "id": "-BQrav4anTmj" 213 | }, 214 | "outputs": [], 215 | "source": [ 216 | "# DEFINE A KERAS MODEL TO CLASSIFY CATS V DOGS\n", 217 | "# USE AT LEAST 3 CONVOLUTION LAYERS\n", 218 | "model = tf.keras.models.Sequential([\n", 219 | " # YOUR CODE HERE\n", 220 | " tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)),\n", 221 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 222 | " tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),\n", 223 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 224 | " tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),\n", 225 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 226 | " tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),\n", 227 | " tf.keras.layers.MaxPooling2D(2, 2),\n", 228 | " tf.keras.layers.Flatten(),\n", 229 | " tf.keras.layers.Dense(512, activation='relu'),\n", 230 | " tf.keras.layers.Dense(1, activation='sigmoid'),\n", 231 | "])\n", 232 | "\n", 233 | "model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['acc'])" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "# NOTE:\n", 241 | "\n", 242 | "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." 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": 89, 248 | "metadata": { 249 | "colab": {}, 250 | "colab_type": "code", 251 | "id": "mlNjoJ5D61N6" 252 | }, 253 | "outputs": [ 254 | { 255 | "name": "stdout", 256 | "output_type": "stream", 257 | "text": [ 258 | "Found 2700 images belonging to 2 classes.\n", 259 | "Found 300 images belonging to 2 classes.\n" 260 | ] 261 | } 262 | ], 263 | "source": [ 264 | "TRAINING_DIR = os.path.join('/tmp/cats-v-dogs', 'training')\n", 265 | "train_datagen = ImageDataGenerator(rescale=1/255,\n", 266 | " rotation_range=40,\n", 267 | " width_shift_range=0.2,\n", 268 | " height_shift_range=0.2,\n", 269 | " shear_range=0.2,\n", 270 | " zoom_range=0.2,\n", 271 | " horizontal_flip=True,\n", 272 | " fill_mode='nearest')\n", 273 | "\n", 274 | "# NOTE: YOU MUST USE A BATCH SIZE OF 10 (batch_size=10) FOR THE \n", 275 | "# TRAIN GENERATOR.\n", 276 | "train_generator = train_datagen.flow_from_directory(TRAINING_DIR,\n", 277 | " batch_size=10,\n", 278 | " class_mode='binary',\n", 279 | " target_size=(150, 150))\n", 280 | "\n", 281 | "VALIDATION_DIR = os.path.join('/tmp/cats-v-dogs', 'testing')\n", 282 | "validation_datagen = ImageDataGenerator(rescale=1/255)\n", 283 | "\n", 284 | "# NOTE: YOU MUST USE A BACTH SIZE OF 10 (batch_size=10) FOR THE \n", 285 | "# VALIDATION GENERATOR.\n", 286 | "validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,\n", 287 | " batch_size=10,\n", 288 | " class_mode='binary',\n", 289 | " target_size=(150, 150))\n", 290 | "\n", 291 | "\n", 292 | "\n", 293 | "# Expected Output:\n", 294 | "# Found 2700 images belonging to 2 classes.\n", 295 | "# Found 300 images belonging to 2 classes." 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": 90, 301 | "metadata": { 302 | "colab": {}, 303 | "colab_type": "code", 304 | "id": "KyS4n53w7DxC" 305 | }, 306 | "outputs": [ 307 | { 308 | "name": "stdout", 309 | "output_type": "stream", 310 | "text": [ 311 | "Epoch 1/2\n", 312 | "270/270 [==============================] - 73s 272ms/step - loss: 0.7216 - acc: 0.5230 - val_loss: 0.6849 - val_acc: 0.5467\n", 313 | "Epoch 2/2\n", 314 | "270/270 [==============================] - 74s 274ms/step - loss: 0.6853 - acc: 0.5704 - val_loss: 0.6756 - val_acc: 0.5733\n" 315 | ] 316 | } 317 | ], 318 | "source": [ 319 | "history = model.fit_generator(train_generator,\n", 320 | " epochs=2,\n", 321 | " verbose=1,\n", 322 | " validation_data=validation_generator)\n" 323 | ] 324 | }, 325 | { 326 | "cell_type": "code", 327 | "execution_count": 92, 328 | "metadata": { 329 | "colab": {}, 330 | "colab_type": "code", 331 | "id": "MWZrJN4-65RC" 332 | }, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/plain": [ 337 | "Text(0.5, 1.0, 'Training and validation loss')" 338 | ] 339 | }, 340 | "execution_count": 92, 341 | "metadata": {}, 342 | "output_type": "execute_result" 343 | }, 344 | { 345 | "data": { 346 | "image/png": "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\n", 347 | "text/plain": [ 348 | "
" 349 | ] 350 | }, 351 | "metadata": { 352 | "needs_background": "light" 353 | }, 354 | "output_type": "display_data" 355 | }, 356 | { 357 | "data": { 358 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAa8AAAEICAYAAADocntXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAWOElEQVR4nO3de7RkZX3m8e/T3UCDIGYBGgSxZSQKKhLsqIk3EFRCFOKEhSAm4ogaMiYhGGdc6BgmYU3IiLrUMQQ0hgiCMiQEjIImgAEdARuQuxhEjNzkIjR3mu7+zR97NxbNuVT3qXN5T38/a9U6u6re/e7fW9Wnn9rv3qd2qgpJklqyYLYLkCRpXRlekqTmGF6SpOYYXpKk5hhekqTmGF6SpOYYXhKQZGGSB5PsMMq2synJ85OM/G9hkuyd5OaB+zckec0wbddjW59PctT6rj9Bv8ckOWnU/WrmLJrtAqT1keTBgbubAY8Bq/r776uqL61Lf1W1Cth81G03BFX1glH0k+Qw4B1VtcdA34eNom/NP4aXmlRVT4RH/8n+sKr61/HaJ1lUVStnojZJ089pQ81L/bTQV5KcluQB4B1Jfj3JxUnuS3J7kk8n2ahvvyhJJVnS3z+lf/6cJA8k+W6S561r2/7530zywyTLk3wmyXeSHDpO3cPU+L4kNya5N8mnB9ZdmOSTSe5JchOwzwSvz4eTfHmtxz6b5BP98mFJru/H86N+r2i8vm5Jske/vFmSk/vargVetlbbjyS5qe/32iT79Y+/BPg/wGv6Kdm7B17bowfW//1+7Pck+ack2w7z2kwmyVv7eu5Lcn6SFww8d1SS25Lcn+QHA2N9ZZLL+8d/luRjw25PI1BV3rw1fQNuBvZe67FjgBXAW+g+pG0K/BrwCroZhx2BHwLv79svAgpY0t8/BbgbWApsBHwFOGU92j4TeADYv3/uSOBx4NBxxjJMjWcBWwJLgJ+vGTvwfuBaYHtgK+DC7ld8zO3sCDwIPG2g7zuBpf39t/RtArweeATYtX9ub+Dmgb5uAfbol48DvgX8EvBc4Lq12h4IbNu/J2/va3hW/9xhwLfWqvMU4Oh++Y19jbsBi4G/Bs4f5rUZY/zHACf1yzv3dby+f4+OAm7ol18E/AT45b7t84Ad++XvAQf3y1sAr5jt34UN6eael+azb1fVV6tqdVU9UlXfq6pLqmplVd0EnAi8boL1z6iqZVX1OPAluv8017Xtm4HvV9VZ/XOfpAu6MQ1Z419W1fKqupkuKNZs60Dgk1V1S1XdAxw7wXZuAq6hC1WANwD3VtWy/vmvVtVN1TkfOA8Y86SMtRwIHFNV91bVT+j2pga3e3pV3d6/J6fSffBYOkS/AIcAn6+q71fVo8CHgNcl2X6gzXivzUQOAs6uqvP79+hYugB8BbCSLihf1E89/7h/7aD7ELJTkq2q6oGqumTIcWgEDC/NZz8dvJPkhUm+luSOJPcDfw5sPcH6dwwsP8zEJ2mM1/bZg3VUVdHtqYxpyBqH2hbdHsNETgUO7pff3t9fU8ebk1yS5OdJ7qPb65notVpj24lqSHJokiv76bn7gBcO2S9043uiv6q6H7gX2G6gzbq8Z+P1u5ruPdquqm4APkD3PtzZT0P/ct/0XcAuwA1JLk2y75Dj0AgYXprP1j5N/AS6vY3nV9XTgY/STYtNp9vppvEASBKe/J/t2qZS4+3AcwbuT3Yq/+nA3km2o9sDO7WvcVPgDOAv6ab0ngF8c8g67hivhiQ7AscDhwNb9f3+YKDfyU7rv41uKnJNf1vQTU/eOkRd69LvArr37FaAqjqlql5FN2W4kO51oapuqKqD6KaGPw78Q5LFU6xFQzK8tCHZAlgOPJRkZ+B9M7DNfwZ2T/KWJIuAPwa2maYaTweOSLJdkq2A/z5R46q6A/g2cBJwQ1X9e//UJsDGwF3AqiRvBvZahxqOSvKMdH8H9/6B5zanC6i76HL8PXR7Xmv8DNh+zQkqYzgNeHeSXZNsQhciF1XVuHuy61Dzfkn26Lf9QbrjlJck2TnJnv32Hulvq+kG8LtJtu731Jb3Y1s9xVo0JMNLG5IPAO+k+4/pBLoTK6ZVVf0MeBvwCeAe4D8BV9D9Xdqoazye7tjU1XQnE5wxxDqn0p2A8cSUYVXdB/wJcCbdSQ8H0IXwMP6Mbg/wZuAc4IsD/V4FfAa4tG/zAmDwONG/AP8O/CzJ4PTfmvXPpZu+O7Nffwe642BTUlXX0r3mx9MF6z7Afv3xr02A/013nPIOuj29D/er7gtcn+5s1uOAt1XViqnWo+Gkm4KXNBOSLKSbpjqgqi6a7XqkVrnnJU2zJPv002ibAP+D7iy1S2e5LKlphpc0/V4N3EQ3JfUm4K1VNd60oaQhOG0oSWqOe16SpOb4xbwzZOutt64lS5bMdhmS1JTLLrvs7qp6yp+XGF4zZMmSJSxbtmy2y5CkpiQZ85tinDaUJDXH8JIkNcfwkiQ1x/CSJDXH8JIkNWfC8EpyQZI3rfXYEUmOn2S9B/ufz04y5peDJvlWkgkvQtdva7OB+19P8oyJ1hlGkqOT/OlU+5EkzY7J9rxOo7vK6KCD+scnVVW3VdUB61NY7wjgifCqqn37b7yWJG3AJguvM4DfSrIxQJIldFcdvSjJ5knOS3J5kquT7L/2ykmWJLmmX940yZeTXJ/kTGDTgXbHJ1mW5Nok/7N/7I/6bV2Q5IL+sZuTbN0vH5nkmv52xMD2rk/yub6vb/YX1hvKOH0+rb+y7ZX942/rHz82yXVJrkpy3LDbkCRN3YR/pFxVP09yKfCbwFl0e12nV1UleZTuC0bv7wPl4iRn1/hflng48HBV7ZxkV+Dygec+3G9rIXBekl2r6tNJjgT2rKq7BztK8jK6S3C/gu4qrJck+Te6S4LvBBxcVe9JcjrwO8Apk70QE/S5I3BbVf1W327L/kJ/bwVe2L8WY05lJnkv8F6AHXaY7KK2kqRhDXPCxuDU4eCUYYD/leQq4F/pLm3+rAn6eS19iPQXpbtq4LkDk1xOd5G+FwG7TFLTq4Ezq+qhqnoQ+EfgNf1zP66q7/fLlwFLJulrsj6vBt6Q5K+SvKaqltNdNfVR4G+T/Gfg4bE6rKoTq2ppVS3dZpuJLp4rSVoXw4TXWcBeSXYHNquqy/rHD6G7nPnLqmo3ukt4L17XApI8D/hTYK+q2hX42vr0M2DwUhOrmOJXYFXVD4Hd6ULsmCQfraqVwMvpplXfDJw7lW1IktbNpOHV74VcAHyBJ5+osSVwZ1U9nmRP4LmTdHUh8HaAJC8Gdu0ffzrwELA8ybPopijXeADYYoy+LgJ+O8lmSZ5GN4U31avSjtlnkmfTTXeeAnwM2D3J5sCWVfV1usulv3SK25YkrYNh90pOA87kyWcefgn4apKrgWXADybp43jg75JcD1xPN6VHVV2Z5Ip+/Z8C3xlY50Tg3CS3VdWeax6sqsuTnMQvrkb7+aq6oj+hZFgfWXNSRt/n9uP0+SbgY0lW010B93C6QD0ryWK66dMj12G7kqQp8mKUM2Tp0qXlt8pL0rpJcllVPeVvgv2GDUlScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMWzXYBmsQJJ8C998LGG8Mmm3Q/p3pbtAiS2R6ZJK03w2uu+9Sn4PrrR9/vYJiNKhTHuk2l7402ggVODkh6KsNrrrv6anj8cVixYmq3xx5b//UeeGDyPh9/fHrGv2jR6ENxOsJ24cLpGb+kMRlec93Chd1t8eLZrmRiVbMbsitWwPLlw/VXNfrxL1gwfXugo+zXKWPNE4aXRiP5xX+Qc1kVrFo1ewG7YgU89FB3HHOy/latmp7XYLqne0fRr1PGmoThpQ1L0u19LFoEm20229VMbNWq9d+bnWrAjjVlPF6fMz1lPJNhO0zfThnPCsNLmqvm+5TxKAJ27Snjifp87LHpGf9kU8ZzZe92nk0ZG15z3BVXwCOPdL8fSfdzcHmyn6Nqs3bbNTdpXk8ZjzJgV6yAhx9+8pTxeLfZnDKejrB94xu78Bwhw2uOO+SQ6TlTflRGFYajDteW+5tPY5np/ib8QDWfp4xHHbIrVox/lvH6TBk/8ojhtaH53OfgwQe7D42rV//i5+DyZD9H1abF/sZbd67UNx0nPm7o5nK4Dt92IQsWLGTBgsXTU98mkMUjGAvFglrFglpFVq1kQa0kq1axYPXK7v7qlWT1St65YOORh43hNce96lWzXYGmW9XcDteZ6G8+jWWYNitXzu36hhe6GFkEbDJuq0M+MvqwMbykWbZmumvBgtmuROqM9YFqKmG4yfi5tt4ML0nSk7TwgWoOlyZJ0tgML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lScwwvSVJzDC9JUnMML0lSc6YcXkm2SvL9/nZHklsH7m88ZB9/l+QFk7T5r0kOmWq9fV/fTrLbKPqSJM28RVPtoKruAXYDSHI08GBVHTfYJkmAVNXqcfp41xDb+exUa5UkzQ/TNm2Y5PlJrkvyJeBaYNskJyZZluTaJB8daPvtJLslWZTkviTHJrkyyXeTPLNvc0ySIwbaH5vk0iQ3JPmN/vGnJfmHfrtn9Nsaag8ryaZJ/j7J1UkuT/La/vGXJPlevyd5VZIdk2yR5Jy+xmuSHDDq10+SNL7pPub1QuCTVbVLVd0KfKiqlgIvBd6QZJcx1tkS+LeqeinwXeC/jNN3qurlwAeBNUH4h8AdVbUL8BfAr65DrX8EPFZVLwF+Fzi5n/b8A+C4qtoN+DXgNmBf4OaqemlVvRj4lzELTN7bB+iyu+66ax1KkSRNZLrD60dVtWzg/sFJLgcuB3YGxgqvR6rqnH75MmDJOH3/4xhtXg18GaCqrqTb4xvWq4FT+nWvpQup5wP/D/hIkv8GPKeqHgWuAvbp9/5eVVXLx+qwqk6sqqVVtXSbbbZZh1IkSROZ7vB6aM1Ckp2APwZeX1W7AucCi8dYZ8XA8irGPy732BBtpqyqTgbe2m/v3CSvrarrgaV04XhskqOma/uSpKeayVPlnw48ANyfZFvgTdOwje8AB0J3rIqx9+zGcxFwSL/uzsC2wI1JdqyqG6vqU8A/A7sm2Y7uxJSTgY8Du49wDJKkSUzbHssYLgeuA34A/IQuaEbtM8AXk1zXb+s6YMwpPeAbSR7vly+iO7Z2QpKrgceB36uqFUnenuTg/rHbgKOB36Db41pNt6f4+9MwFknSOFJVs13DyCRZBCyqqkf7acpvAjtV1cpZLo2lS5fWsmXLJm8oSXpCksv6E/2eZCb3vGbC5sB5fYgFeN9cCC5J0mjNq/CqqvuAl812HZKk6eV3G0qSmmN4SZKaM69O2JjLktxFd5bl+tgauHuE5bTAMW8YNrQxb2jjhamP+blV9ZRveTC8GpBk2Vhn28xnjnnDsKGNeUMbL0zfmJ02lCQ1x/CSJDXH8GrDibNdwCxwzBuGDW3MG9p4YZrG7DEvSVJz3POSJDXH8JIkNcfwmkOS7JPkhiQ3JvnQGM9vkuQr/fOXJFky81WOzhDjPTLJdUmuSnJekufORp2jNNmYB9r9TpJK0vxp1cOMOcmB/Xt9bZJTZ7rGURvi3/YOSS5IckX/73vf2ahzVJJ8IcmdSa4Z5/kk+XT/elyVZOqXkaoqb3PgBiwEfgTsCGwMXAnsslabPwD+pl8+CPjKbNc9zePdE9isXz685fEOO+a+3RbAhcDFwNLZrnsG3uedgCuAX+rvP3O2656BMZ8IHN4v7wLcPNt1T3HMr6W7ruE14zy/L3AO3RemvxK4ZKrbdM9r7ng5cGNV3VRVK4AvA/uv1WZ/4O/75TOAvZJkBmscpUnHW1UXVNXD/d2Lge1nuMZRG+Y9BvgL4K+AR2eyuGkyzJjfA3y2qu4FqKo7Z7jGURtmzEV3gV6ALemuFdisqroQ+PkETfYHvlidi4Fn9BclXm+G19yxHfDTgfu39I+N2aa6S70sB7aakepGb5jxDno33Se3lk065n465TlV9bWZLGwaDfM+/wrwK0m+k+TiJPvMWHXTY5gxHw28I8ktwNeBP5yZ0mbNuv6+T2peXRJF81OSdwBLgdfNdi3TKckC4BPAobNcykxbRDd1uAfd3vWFSV5S3SWO5quDgZOq6uNJfh04OcmLq2r1bBfWCve85o5bgecM3N++f2zMNv0FN7cE7pmR6kZvmPGSZG/gw8B+VfXYDNU2XSYb8xbAi4FvJbmZ7tjA2Y2ftDHM+3wLcHZVPV5VPwZ+SBdmrRpmzO8GTgeoqu8Ci+m+wHa+Gur3fV0YXnPH94CdkjwvycZ0J2ScvVabs4F39ssHAOdXfzS0QZOON8mvAifQBVfrx0FgkjFX1fKq2rqqllTVErrjfPtV1bLZKXckhvl3/U90e10k2ZpuGvGmmSxyxIYZ838AewEk2ZkuvO6a0Spn1tnA7/VnHb4SWF5Vt0+lQ6cN54iqWpnk/cA36M5W+kJVXZvkz4FlVXU28Ld00ws30h0cPWj2Kp6aIcf7MWBz4P/256X8R1XtN2tFT9GQY55XhhzzN4A3JrkOWAV8sKpanVEYdswfAD6X5E/oTt44tOEPoiQ5je4DyNb9cbw/AzYCqKq/oTuuty9wI/Aw8K4pb7Ph10uStIFy2lCS1BzDS5LUHMNLktQcw0uS1BzDS5LUHMNLktQcw0uS1Jz/D8jE/sD66g2oAAAAAElFTkSuQmCC\n", 359 | "text/plain": [ 360 | "
" 361 | ] 362 | }, 363 | "metadata": { 364 | "needs_background": "light" 365 | }, 366 | "output_type": "display_data" 367 | } 368 | ], 369 | "source": [ 370 | "# PLOT LOSS AND ACCURACY\n", 371 | "%matplotlib inline\n", 372 | "\n", 373 | "import matplotlib.image as mpimg\n", 374 | "import matplotlib.pyplot as plt\n", 375 | "\n", 376 | "#-----------------------------------------------------------\n", 377 | "# Retrieve a list of list results on training and test data\n", 378 | "# sets for each training epoch\n", 379 | "#-----------------------------------------------------------\n", 380 | "acc=history.history['acc']\n", 381 | "val_acc=history.history['val_acc']\n", 382 | "loss=history.history['loss']\n", 383 | "val_loss=history.history['val_loss']\n", 384 | "\n", 385 | "epochs=range(len(acc)) # Get number of epochs\n", 386 | "\n", 387 | "#------------------------------------------------\n", 388 | "# Plot training and validation accuracy per epoch\n", 389 | "#------------------------------------------------\n", 390 | "plt.plot(epochs, acc, 'r', \"Training Accuracy\")\n", 391 | "plt.plot(epochs, val_acc, 'b', \"Validation Accuracy\")\n", 392 | "plt.title('Training and validation accuracy')\n", 393 | "plt.figure()\n", 394 | "\n", 395 | "#------------------------------------------------\n", 396 | "# Plot training and validation loss per epoch\n", 397 | "#------------------------------------------------\n", 398 | "plt.plot(epochs, loss, 'r', \"Training Loss\")\n", 399 | "plt.plot(epochs, val_loss, 'b', \"Validation Loss\")\n", 400 | "\n", 401 | "\n", 402 | "plt.title('Training and validation loss')\n", 403 | "\n", 404 | "# Desired output. Charts with training and validation metrics. No crash :)" 405 | ] 406 | }, 407 | { 408 | "cell_type": "markdown", 409 | "metadata": {}, 410 | "source": [ 411 | "# Submission Instructions" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "execution_count": null, 417 | "metadata": {}, 418 | "outputs": [], 419 | "source": [ 420 | "# Now click the 'Submit Assignment' button above." 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "# 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. " 428 | ] 429 | }, 430 | { 431 | "cell_type": "code", 432 | "execution_count": null, 433 | "metadata": {}, 434 | "outputs": [], 435 | "source": [ 436 | "%%javascript\n", 437 | "\n", 438 | "IPython.notebook.save_checkpoint();" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": null, 444 | "metadata": {}, 445 | "outputs": [], 446 | "source": [ 447 | "%%javascript\n", 448 | "IPython.notebook.session.delete();\n", 449 | "window.onbeforeunload = null\n", 450 | "setTimeout(function() { window.close(); }, 1000);" 451 | ] 452 | } 453 | ], 454 | "metadata": { 455 | "accelerator": "GPU", 456 | "colab": { 457 | "collapsed_sections": [], 458 | "name": "Exercise 6 - Question.ipynb", 459 | "provenance": [] 460 | }, 461 | "coursera": { 462 | "course_slug": "convolutional-neural-networks-tensorflow", 463 | "graded_item_id": "uAPOR", 464 | "launcher_item_id": "e9lTb" 465 | }, 466 | "kernelspec": { 467 | "display_name": "Python 3", 468 | "language": "python", 469 | "name": "python3" 470 | }, 471 | "language_info": { 472 | "codemirror_mode": { 473 | "name": "ipython", 474 | "version": 3 475 | }, 476 | "file_extension": ".py", 477 | "mimetype": "text/x-python", 478 | "name": "python", 479 | "nbconvert_exporter": "python", 480 | "pygments_lexer": "ipython3", 481 | "version": "3.6.8" 482 | } 483 | }, 484 | "nbformat": 4, 485 | "nbformat_minor": 1 486 | } 487 | -------------------------------------------------------------------------------- /3. Natural Language Processing in TensorFlow/Coursera.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palashsharma891/DeepLearning.AI-TensorFlow-Developer-Coursera/5138f4c0863d672eba25cbc60a8136a221caa784/3. Natural Language Processing in TensorFlow/Coursera.pdf -------------------------------------------------------------------------------- /4. Sequences, Time Series and Prediction/Coursera.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palashsharma891/DeepLearning.AI-TensorFlow-Developer-Coursera/5138f4c0863d672eba25cbc60a8136a221caa784/4. Sequences, Time Series and Prediction/Coursera.pdf -------------------------------------------------------------------------------- /Coursera.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palashsharma891/DeepLearning.AI-TensorFlow-Developer-Coursera/5138f4c0863d672eba25cbc60a8136a221caa784/Coursera.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeepLearning.AI-TensorFlow-Developer-Coursera 2 | Here are my solutions to the programming exercises in the TensorFlow Developer course on Coursera by deeplearning.ai 3 | 4 | The courses offered in this professional certificate program were: 5 | 6 | 1. Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning 7 | 2. Convolutional Neural Networks in TensorFlow 8 | 3. Natural Language Processing in TensorFlow 9 | 4. Sequences, Time Series and Prediction 10 | --------------------------------------------------------------------------------