{"metadata":{"accelerator":"GPU","colab":{"collapsed_sections":[],"name":"C2_W2_Lab_1_cats_v_dogs_augmentation.ipynb","private_outputs":true,"provenance":[{"file_id":"https://github.com/https-deeplearning-ai/tensorflow-1-public/blob/adding_C2/C2/W2/ungraded_labs/C2_W2_Lab_1_cats_v_dogs_augmentation.ipynb","timestamp":1639637705486}]},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30747,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<a href=\"https://colab.research.google.com/github/https-deeplearning-ai/tensorflow-1-public/blob/master/C2/W2/ungraded_labs/C2_W2_Lab_1_cats_v_dogs_augmentation.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>","metadata":{}},{"cell_type":"markdown","source":"# CAT🐱 vs 🐶DOG\nUsing **TensorFlow** , **Data augmentation** and **Image Generator**\n\nThis notebook is part of the [TensorFlow Developer Professional Certificate](http://www.coursera.org/professional-certificates/tensorflow-in-practice) by [DeepLearning.AI](h)\n\n![download (1).jpeg](attachment:c20e915e-5439-4d97-8525-24d8c8ad24c7.jpeg)","metadata":{},"attachments":{"c20e915e-5439-4d97-8525-24d8c8ad24c7.jpeg":{"image/jpeg":"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"}}},{"cell_type":"markdown","source":"## Baseline Performance\n\nYou will start with a model that's very effective at learning `Cats vs Dogs` without data augmentation. It's similar to the previous models that you have used. Note that there are four convolutional layers with 32, 64, 128 and 128 convolutions respectively.\n\nWe will train only for 20 epochs to save time but feel free to increase this if you want.","metadata":{"id":"kJJqX4DxcQs8"}},{"cell_type":"code","source":"# Download the dataset\n!wget https://storage.googleapis.com/tensorflow-1-public/course2/cats_and_dogs_filtered.zip","metadata":{"id":"zJZIF29-dIRv","execution":{"iopub.status.busy":"2024-08-20T03:57:22.173752Z","iopub.execute_input":"2024-08-20T03:57:22.174656Z","iopub.status.idle":"2024-08-20T03:57:23.703044Z","shell.execute_reply.started":"2024-08-20T03:57:22.174623Z","shell.execute_reply":"2024-08-20T03:57:23.701952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# First import the necessary libraries\nimport os\nimport tensorflow as tf\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2024-08-20T04:00:46.392024Z","iopub.execute_input":"2024-08-20T04:00:46.392473Z","iopub.status.idle":"2024-08-20T04:00:46.398026Z","shell.execute_reply.started":"2024-08-20T04:00:46.39244Z","shell.execute_reply":"2024-08-20T04:00:46.39682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport zipfile\n\n# Extract the archive\nzip_ref = zipfile.ZipFile(\"./cats_and_dogs_filtered.zip\", 'r')\nzip_ref.extractall(\"tmp/\")\nzip_ref.close()\n\n# Assign training and validation set directories\nBASE_DIR = 'tmp/cats_and_dogs_filtered'\n\ntrain_dir = os.path.join(BASE_DIR, 'train')\nvalidation_dir = os.path.join(BASE_DIR, 'validation')\n\n# Directory with training cat/dog pictures\ntrain_cats_dir = os.path.join(train_dir, 'cats')\ntrain_dogs_dir = os.path.join(train_dir, 'dogs')\n\n# Directory with validation cat/dog pictures\nvalidation_cats_dir = os.path.join(validation_dir, 'cats')\nvalidation_dogs_dir = os.path.join(validation_dir, 'dogs')\n\nprint(f\"Contents of base directory: {os.listdir(BASE_DIR)}\")\n\nprint(f\"\\nContents of train directory: {os.listdir(train_dir)}\")\n\nprint(f\"\\nContents of validation directory: {os.listdir(validation_dir)}\")","metadata":{"id":"_DyUfCTgdwa8","execution":{"iopub.status.busy":"2024-08-20T04:02:02.137905Z","iopub.execute_input":"2024-08-20T04:02:02.138278Z","iopub.status.idle":"2024-08-20T04:02:03.106544Z","shell.execute_reply.started":"2024-08-20T04:02:02.138248Z","shell.execute_reply":"2024-08-20T04:02:03.105577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You will place the model creation inside a function so you can easily initialize a new one when you use data augmentation later in this notebook.","metadata":{"id":"Ub_BdOJIfZ_Q"}},{"cell_type":"code","source":"def create_model():\n    '''Creates a CNN with 4 convolutional layers'''\n    model = tf.keras.models.Sequential([\n        tf.keras.Input(shape=(150, 150, 3)),\n        tf.keras.layers.Rescaling(1./255),\n        tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n        tf.keras.layers.MaxPooling2D(2, 2),\n        tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n        tf.keras.layers.MaxPooling2D(2,2),\n        tf.keras.layers.Conv2D(128, (3,3), activation='relu'),\n        tf.keras.layers.MaxPooling2D(2,2),\n        tf.keras.layers.Conv2D(128, (3,3), activation='relu'),\n        tf.keras.layers.MaxPooling2D(2,2),\n        tf.keras.layers.Flatten(),\n        tf.keras.layers.Dense(512, activation='relu'),\n        tf.keras.layers.Dense(1, activation='sigmoid')\n    ])\n\n    return model","metadata":{"id":"uWllK_Wad-Mx","execution":{"iopub.status.busy":"2024-08-20T04:02:55.061249Z","iopub.execute_input":"2024-08-20T04:02:55.061708Z","iopub.status.idle":"2024-08-20T04:02:55.070461Z","shell.execute_reply.started":"2024-08-20T04:02:55.061679Z","shell.execute_reply":"2024-08-20T04:02:55.069542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Instantiate the training dataset\ntrain_dataset = tf.keras.utils.image_dataset_from_directory(\n    train_dir,\n    image_size=(150, 150),\n    batch_size=20,\n    label_mode='binary'\n    )\n\n# Instantiate the validation dataset\nvalidation_dataset = tf.keras.utils.image_dataset_from_directory(\n    validation_dir,\n    image_size=(150, 150),\n    batch_size=20,\n    label_mode='binary'\n    )\n\n# Optimize the datasets for training\nSHUFFLE_BUFFER_SIZE = 1000\nPREFETCH_BUFFER_SIZE = tf.data.AUTOTUNE\n\ntrain_dataset_final = (train_dataset\n                       .cache()\n                       .shuffle(SHUFFLE_BUFFER_SIZE)\n                       .prefetch(PREFETCH_BUFFER_SIZE)\n                       )\n\nvalidation_dataset_final = (validation_dataset\n                            .cache()\n                            .prefetch(PREFETCH_BUFFER_SIZE)\n                            )","metadata":{"id":"MJPyDEzOqrKB","execution":{"iopub.status.busy":"2024-08-20T04:03:24.112138Z","iopub.execute_input":"2024-08-20T04:03:24.112511Z","iopub.status.idle":"2024-08-20T04:03:25.89957Z","shell.execute_reply.started":"2024-08-20T04:03:24.112485Z","shell.execute_reply":"2024-08-20T04:03:25.898716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Constant for epochs\nEPOCHS = 20\n\n# Create a new model\nmodel = create_model()\n\n# Setup the training parameters\nmodel.compile(loss='binary_crossentropy',\n              optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4),\n              metrics=['accuracy'])\n\n# Train the model\nhistory = model.fit(\n      train_dataset_final,\n      epochs=EPOCHS,\n      validation_data=validation_dataset_final,\n      verbose=2)","metadata":{"id":"hdqUoF44esR3","execution":{"iopub.status.busy":"2024-08-20T04:03:37.777963Z","iopub.execute_input":"2024-08-20T04:03:37.778824Z","iopub.status.idle":"2024-08-20T04:04:12.155808Z","shell.execute_reply.started":"2024-08-20T04:03:37.778765Z","shell.execute_reply":"2024-08-20T04:04:12.154864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You will then visualize the loss and accuracy with respect to the training and validation set. You will again use a convenience function so it can be reused later. This function accepts a [History](https://www.tensorflow.org/api_docs/python/tf/keras/callbacks/History) object which contains the results of the `fit()` method you ran above.","metadata":{"id":"Y-G0Am4cguNt"}},{"cell_type":"code","source":"def plot_loss_acc(history):\n    '''Plots the training and validation loss and accuracy from a history object'''\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    epochs = range(len(acc))\n\n    fig, ax = plt.subplots(1,2, figsize=(12, 6))\n    ax[0].plot(epochs, acc, 'bo', label='Training accuracy')\n    ax[0].plot(epochs, val_acc, 'b', label='Validation accuracy')\n    ax[0].set_title('Training and validation accuracy')\n    ax[0].set_xlabel('epochs')\n    ax[0].set_ylabel('accuracy')\n    ax[0].legend()\n\n    ax[1].plot(epochs, loss, 'bo', label='Training Loss')\n    ax[1].plot(epochs, val_loss, 'b', label='Validation Loss')\n    ax[1].set_title('Training and validation loss')\n    ax[1].set_xlabel('epochs')\n    ax[1].set_ylabel('loss')\n    ax[1].legend()\n\n    plt.show()","metadata":{"id":"GZWPcmKWO303","execution":{"iopub.status.busy":"2024-08-20T04:04:27.804006Z","iopub.execute_input":"2024-08-20T04:04:27.805004Z","iopub.status.idle":"2024-08-20T04:04:27.813882Z","shell.execute_reply.started":"2024-08-20T04:04:27.804969Z","shell.execute_reply":"2024-08-20T04:04:27.812946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot training results\nplot_loss_acc(history)","metadata":{"id":"Vojz4NYXiT_f","execution":{"iopub.status.busy":"2024-08-20T04:04:45.582555Z","iopub.execute_input":"2024-08-20T04:04:45.583391Z","iopub.status.idle":"2024-08-20T04:04:46.188477Z","shell.execute_reply.started":"2024-08-20T04:04:45.583355Z","shell.execute_reply":"2024-08-20T04:04:46.187389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From the results above, you'll see the training accuracy is more than 90%, and the validation accuracy is in the 70%-80% range. This is a great example of _overfitting_ -- which in short means that it can do very well with images it has seen before, but not so well with images it hasn't.\n","metadata":{"id":"zb81GvNov-Tg"}},{"cell_type":"markdown","source":"## Data augmentation\n\nOne simple method to avoid overfitting is to augment the images a bit. If you think about it, most pictures of a cat are very similar -- the ears are at the top, then the eyes, then the mouth etc. Things like the distance between the eyes and ears will always be quite similar too. \n\nWhat if you tweak with the images a bit -- rotate the image, squash it, etc.  That's what image augementation is all about. And there's an API that makes it easy!\n\nTake a look at the [ImageDataGenerator](https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator) which you have been using to rescale the image. There are other properties on it that you can use to augment the image. \n\n```\n# Updated to do image augmentation\ntrain_datagen = ImageDataGenerator(\n      rotation_range=40,\n      width_shift_range=0.2,\n      height_shift_range=0.2,\n      shear_range=0.2,\n      zoom_range=0.2,\n      horizontal_flip=True,\n      fill_mode='nearest')\n```\n\nThese are just a few of the options available. Let's quickly go over it:\n\n* `rotation_range` is a value in degrees (0–180) within which to randomly rotate pictures.\n* `width_shift` and `height_shift` are ranges (as a fraction of total width or height) within which to randomly translate pictures vertically or horizontally.\n* `shear_range` is for randomly applying shearing transformations.\n* `zoom_range` is for randomly zooming inside pictures.\n* `horizontal_flip` is for randomly flipping half of the images horizontally. This is relevant when there are no assumptions of horizontal assymmetry (e.g. real-world pictures).\n* `fill_mode` is the strategy used for filling in newly created pixels, which can appear after a rotation or a width/height shift.\n\n\nRun the next cells to see the impact on the results. The code is similar to the baseline but the definition of `train_datagen` has been updated to use the parameters described above.\n","metadata":{"id":"5KBz-vFbjLZX"}},{"cell_type":"code","source":"# Define fill mode.\nFILL_MODE = 'nearest'\n\n# Create the augmentation model.\ndata_augmentation = tf.keras.Sequential([\n    # Specify the input shape.\n    tf.keras.Input(shape=(150,150,3)),\n    # Add the augmentation layers\n    tf.keras.layers.RandomFlip(\"horizontal\"),\n    tf.keras.layers.RandomRotation(0.2, fill_mode=FILL_MODE),\n    tf.keras.layers.RandomTranslation(0.2,0.2, fill_mode=FILL_MODE),\n    tf.keras.layers.RandomZoom(0.2, fill_mode=FILL_MODE)\n    ])","metadata":{"id":"UK7_Fflgv8YC","execution":{"iopub.status.busy":"2024-08-20T04:07:38.225384Z","iopub.execute_input":"2024-08-20T04:07:38.225849Z","iopub.status.idle":"2024-08-20T04:07:38.253664Z","shell.execute_reply.started":"2024-08-20T04:07:38.225802Z","shell.execute_reply":"2024-08-20T04:07:38.252838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You will define a utility function that lets you preview how the transformed images look like. It will take in a sample image, then output a given number of augmented images using the model you defined above.","metadata":{}},{"cell_type":"code","source":"def demo_augmentation(sample_image, model, num_aug):\n    '''Takes a single image array, then uses a model to generate num_aug transformations'''\n\n    # Instantiate preview list\n    image_preview = []\n\n    # Convert input image to a PIL image instance\n    sample_image_pil = tf.keras.utils.array_to_img(sample_image)\n\n    # Append the result to the list\n    image_preview.append(sample_image_pil)\n\n    # Apply the image augmentation and append the results to the list\n    for i in range(NUM_AUG):\n        sample_image_aug = model(tf.expand_dims(sample_image, axis=0))\n        sample_image_aug_pil = tf.keras.utils.array_to_img(tf.squeeze(sample_image_aug))\n        image_preview.append(sample_image_aug_pil)\n\n    # Instantiate a subplot\n    fig, axes = plt.subplots(1, NUM_AUG + 1, figsize=(12, 12))\n\n    # Preview the images.\n    for index, ax in enumerate(axes):\n        ax.imshow(image_preview[index])\n        ax.set_axis_off()\n\n        if index == 0:\n            ax.set_title('original')\n        else:\n            ax.set_title(f'augment {index}')","metadata":{"execution":{"iopub.status.busy":"2024-08-20T04:07:41.3382Z","iopub.execute_input":"2024-08-20T04:07:41.338589Z","iopub.status.idle":"2024-08-20T04:07:41.34713Z","shell.execute_reply.started":"2024-08-20T04:07:41.338557Z","shell.execute_reply":"2024-08-20T04:07:41.346088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now get some images from the dataset.","metadata":{}},{"cell_type":"code","source":"# Get a batch of images\nsample_batch = list(train_dataset.take(1))[0][0]\nprint(f'images per batch: {len(sample_batch)}')","metadata":{"execution":{"iopub.status.busy":"2024-08-20T04:07:45.641634Z","iopub.execute_input":"2024-08-20T04:07:45.641992Z","iopub.status.idle":"2024-08-20T04:07:45.691648Z","shell.execute_reply.started":"2024-08-20T04:07:45.641965Z","shell.execute_reply":"2024-08-20T04:07:45.690515Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This will show sample transformations for the first 4 images of the sample batch. Notice that each call of the data_augmentation model yields a different output. It's like adding more images to your dataset without you having to collect them manually.","metadata":{}},{"cell_type":"code","source":"NUM_AUG = 4\n\n# Apply the transformations to the first 4 images\ndemo_augmentation(sample_batch[0], data_augmentation, NUM_AUG)\ndemo_augmentation(sample_batch[1], data_augmentation, NUM_AUG)\ndemo_augmentation(sample_batch[2], data_augmentation, NUM_AUG)\ndemo_augmentation(sample_batch[3], data_augmentation, NUM_AUG)\n\n# Uncomment the line below to delete the variable to free up some memory\n# del sample_batch","metadata":{"execution":{"iopub.status.busy":"2024-08-20T04:07:50.418853Z","iopub.execute_input":"2024-08-20T04:07:50.419349Z","iopub.status.idle":"2024-08-20T04:07:54.478726Z","shell.execute_reply.started":"2024-08-20T04:07:50.419293Z","shell.execute_reply":"2024-08-20T04:07:54.477754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now that you see what the preprocessing layers do, you can prepend these to the base model so it can generate transformed images to the base model. Do note that these layers are only active while training. They are automatically disabled during prediction and evaluation.","metadata":{}},{"cell_type":"code","source":"# Instantiate the base model\nmodel_without_aug = create_model()\n\n# Prepend the data augmentation layers to the base model\nmodel_with_aug = tf.keras.models.Sequential([\n    data_augmentation,\n    model_without_aug\n])\n\n# Compile the model\nmodel_with_aug.compile(\n    loss='binary_crossentropy',\n    optimizer=tf.keras.optimizers.RMSprop(learning_rate=1e-4),\n    metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-08-20T04:07:58.766383Z","iopub.execute_input":"2024-08-20T04:07:58.766782Z","iopub.status.idle":"2024-08-20T04:07:58.834295Z","shell.execute_reply.started":"2024-08-20T04:07:58.766732Z","shell.execute_reply":"2024-08-20T04:07:58.833292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Because you now have virtually more data, it will also take the model more time to learn the relevant features. Without data augmentation, your model already started overfitting to the training set within 20 epochs. Try training this model for 80 epochs and observe the results.","metadata":{}},{"cell_type":"code","source":"EPOCHS=80\n\n# Train the new model\nhistory_with_aug = model_with_aug.fit(\n      train_dataset_final,\n      epochs=EPOCHS,\n      validation_data=validation_dataset_final,\n      verbose=2)","metadata":{"execution":{"iopub.status.busy":"2024-08-20T04:08:03.837341Z","iopub.execute_input":"2024-08-20T04:08:03.837738Z","iopub.status.idle":"2024-08-20T04:10:49.481838Z","shell.execute_reply.started":"2024-08-20T04:08:03.837706Z","shell.execute_reply":"2024-08-20T04:10:49.481023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot the results of training with data augmentation\nplot_loss_acc(history_with_aug)","metadata":{"id":"bnyRnwopT5aW","execution":{"iopub.status.busy":"2024-08-20T04:10:52.247516Z","iopub.execute_input":"2024-08-20T04:10:52.248181Z","iopub.status.idle":"2024-08-20T04:10:52.804725Z","shell.execute_reply.started":"2024-08-20T04:10:52.248147Z","shell.execute_reply":"2024-08-20T04:10:52.803738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As you can see, the training accuracy has gone down compared to the baseline. This is expected because (as a result of data augmentation) there are more variety in the images so the model will need more runs to learn from them. The good thing is the validation accuracy is no longer stalling and is more in line with the training results. This means that the model is now performing better on unseen data. \n\n\n","metadata":{"id":"1D1hd5fqmJUx"}}]}