{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "69c73990",
   "metadata": {},
   "source": [
    "# Coursework TensorFlow\n",
    "# SPCE0038: Machine Learning with Big-Data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67cacfd6",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d428273",
   "metadata": {},
   "source": [
    "## Overview\n",
    "\n",
    "This coursework is provided as a Jupyter notebook, which you will need to complete.  \n",
    "\n",
    "Throughout the notebook you will need to complete code, analytic exercises (if equations are required please typeset your solutions using latex in the markdown cell provided) and descriptive answers. Much of the grading of the coursework will be performed automatically, so it is critical you name your variables as requested."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90b39499",
   "metadata": {},
   "source": [
    "Before you turn this coursework in, make sure everything runs as expected. First, **restart the kernel** (in the menubar, select Kernel$\\rightarrow$Restart) and then **run all cells** (in the menubar, select Cell$\\rightarrow$Run All).\n",
    "\n",
    "Make sure you fill in any place that says \"YOUR ANSWER HERE\" or `YOUR CODE HERE` and remove remove the `raise NotImplementedError()` exceptions that are thrown before you have added your answers. Do not add and remove cells but rather provide your answers in the spaces given."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "150e1000",
   "metadata": {},
   "source": [
    "Please also:\n",
    "\n",
    "- Make sure you use a python environment using the `requirements.txt` files provided by the course.\n",
    "- Make sure your notebook executes without errors.\n",
    "- Do not add and remove cells but only provide your answers in the spaces given.\n",
    "- Do not add or change code in the cells other than the ones marked with `# YOUR CODE HERE`.\n",
    "- Do not overwrite or rename any existing variables.\n",
    "- Do not install code or packages in the notebooks.\n",
    "- Do not import any libraries other than modules from `sklearn` or `tensorflow`.\n",
    "- Always label your plots.\n",
    "- Answer the questions concisely and show your work/derivations/reasoning."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f92476d1",
   "metadata": {},
   "source": [
    "**Please rename the notebook filename to include your candidate number in the filename. And please also add your candidate number below:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3593c649",
   "metadata": {},
   "outputs": [],
   "source": [
    "CANDIDATE_NUMBER = \"MCMQ7\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "322a38c5",
   "metadata": {},
   "source": [
    "You will be able to run some basic tests in the notebook to check the basic operation of your code is as expected.  Although do not assume your responses are complete or fully correct just because the basic tests pass."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9871e0f5",
   "metadata": {},
   "source": [
    "Once you have renamed the notebook file and completed the exercises, please upload the notebook to Moodle.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d38e1133",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "719f3952",
   "metadata": {},
   "source": [
    "## Dependencies\n",
    "\n",
    "- Standard course dependencies (e.g. numpy, scikit-learn, etc.)\n",
    "- [TensorFlow](https://www.tensorflow.org/)\n",
    "- [TensorFlow DataSets](https://www.tensorflow.org/datasets)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07758eeb",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2231590",
   "metadata": {},
   "source": [
    "Notes for people running the notebook in Google Colab:\n",
    "\n",
    "- This notebook uses quite a bit of RAM (the solutions run with ~8.5Gb of RAM), which means that if you are very inefficient in your memory usage, it will not fit within Colab's limits of 12Gb. If this is the case, you can try restarting the runtime to free up memory of variables you have created and that you no longer use or write your code in a more efficient way.\n",
    "- You can enable a Runtime with GPU acceleration for faster training (Runtime -> Change runtime type)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a32c7c90",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "b1a7b7723a7cd8fac9ab0856025a6d81",
     "grade": false,
     "grade_id": "cell-418daabc8f9aac61",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2025-03-14 14:07:37.610956: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n",
      "2025-03-14 14:07:37.788469: I external/local_xla/xla/tsl/cuda/cudart_stub.cc:32] Could not find cuda drivers on your machine, GPU will not be used.\n",
      "2025-03-14 14:07:37.950994: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
      "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n",
      "E0000 00:00:1741961258.106221   71564 cuda_dnn.cc:8310] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
      "E0000 00:00:1741961258.153214   71564 cuda_blas.cc:1418] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
      "2025-03-14 14:07:38.479758: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
      "To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import tensorflow as tf\n",
    "import tensorflow_datasets as tfds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "fad96611",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "83978659708fbe27b7f96f0c006862a5",
     "grade": false,
     "grade_id": "cell-0be768f33f772611",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "def check_var_defined(var):\n",
    "    try:\n",
    "        exec(var)\n",
    "    except NameError:\n",
    "        raise NameError(var + \" not defined.\")\n",
    "    else:\n",
    "        print(var + \" defined.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7e45caa0-f9fb-4f83-88df-52d5a5e649d7",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "3fbf8aa9005ee23d0ab5544a5d026671",
     "grade": true,
     "grade_id": "cell-59343806849c27ff",
     "locked": true,
     "points": 0,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "0c0e7927",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "71eeea15b0b692ba25c290608f294ae1",
     "grade": false,
     "grade_id": "cell-9ae5247a66cdf986",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "# Part 1: Data pre-processing\n",
    "\n",
    "\n",
    "In these exercises we will look at the classification of flowers into 5 different classes using convolutional neural networks (CNNs). The implementation of this will be done using TensorFlow (TF).\n",
    "\n",
    "The dataset can be loaded in using the [Tensorflow Datasets](https://www.tensorflow.org/datasets) package. Below you see how we load in the data and change it from a TF generator object into a list of the images and a list of the targets. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f9c193a0",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "c2460b788cc541a7382bee075395dbb7",
     "grade": false,
     "grade_id": "cell-5a158c5e75738fc8",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2025-03-14 14:44:13.164833: W external/local_tsl/tsl/platform/cloud/google_auth_provider.cc:184] All attempts to get a Google authentication bearer token failed, returning an empty token. Retrieving token from files failed with \"NOT_FOUND: Could not locate the credentials file.\". Retrieving token from GCE failed with \"FAILED_PRECONDITION: Error executing an HTTP request: libcurl code 6 meaning 'Couldn't resolve host name', error details: Could not resolve host: metadata.google.internal\".\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1mDownloading and preparing dataset 218.21 MiB (download: 218.21 MiB, generated: 221.83 MiB, total: 440.05 MiB) to /home/ktyl/tensorflow_datasets/tf_flowers/3.0.1...\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/ktyl/.conda/envs/mlbd/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n",
      "Dl Completed...: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:31<00:00,  6.22s/ file]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1mDataset tf_flowers downloaded and prepared to /home/ktyl/tensorflow_datasets/tf_flowers/3.0.1. Subsequent calls will reuse this data.\u001b[0m\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "W0000 00:00:1741963485.913699   71564 gpu_device.cc:2344] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.\n",
      "Skipping registering GPU devices...\n"
     ]
    }
   ],
   "source": [
    "# Load data\n",
    "data = tfds.load('tf_flowers', split=[\"train\"], as_supervised=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e438b1ef",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "d0e89c00c9c0df44f1b834b9d4391b72",
     "grade": false,
     "grade_id": "cell-1aefc40e0c7fe096",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2025-03-14 14:44:46.016395: I tensorflow/core/kernels/data/tf_record_dataset_op.cc:376] The default buffer size is 262144, which is overridden by the user specified `buffer_size` of 8388608\n",
      "2025-03-14 14:44:46.984183: I tensorflow/core/framework/local_rendezvous.cc:405] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n"
     ]
    }
   ],
   "source": [
    "images, targets = zip(*[i for i in data[0]])\n",
    "labels = [\"dandelion\", \"daisy\", \"tulips\",  \"sunflowers\", \"roses\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad3c8560",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "71525d2c752790a621a96df6f831cb50",
     "grade": false,
     "grade_id": "cell-955200c05b4bfd90",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Plot the first two images and their classes by writing a function `show_image`. Set the title of the images to be the class (use the actual label, not the number) it belongs to._ "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "69bf403d",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "044d25f825f21b72888f98026cbb419d",
     "grade": true,
     "grade_id": "cell-2ad6ec61e28d4327",
     "locked": false,
     "points": 1,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 393472 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 233372 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def show_image(image, target):\n",
    "    # YOUR CODE HERE\n",
    "\n",
    "    # Plot each image in a separate figure\n",
    "    plt.figure()\n",
    "    \n",
    "    # Plot their classes\n",
    "    # Set the title of the images to be the class the image belongs to\n",
    "    label = labels[target]\n",
    "    \n",
    "    plt.imshow(image)\n",
    "    plt.axis(\"off\")\n",
    "    plt.title(label)\n",
    "    #raise NotImplementedError()\n",
    "\n",
    "for i in range(2):\n",
    "    show_image(images[i], targets[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c091a6b0",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "39fbb3182de77dc1dfefd62803c45add",
     "grade": false,
     "grade_id": "cell-b8ee9d31572d4ef8",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "Before we can use the data to train neural networks, we need to pre-process the data such that:\n",
    "    \n",
    "- the images are all the same shape (224,224)\n",
    "- the images, originally with values (0, 255), are mapped to have values between (0, 1)\n",
    "- the labels are represented as one-hot vectors"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb856fda",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "fefdc012c93c2ff67ef9a229628f8c8c",
     "grade": false,
     "grade_id": "cell-6b5b2f4a3e9c2f2e",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Write a function to rescale and resize the images._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "id": "2f2da49d",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "cbefaa1f473a3192c47b509da825bf06",
     "grade": false,
     "grade_id": "cell-e3182b662219760c",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 302812 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def rescale_and_resize(image):\n",
    "    # YOUR CODE HERE\n",
    "    \n",
    "    # Rescale to (0, 1) range\n",
    "    preprocessed_image = image / 255\n",
    "    \n",
    "    # Resize to (224, 244)\n",
    "    preprocessed_image = tf.image.resize(preprocessed_image, [224, 224])\n",
    "    \n",
    "    return preprocessed_image\n",
    "    #raise NotImplementedError()\n",
    "\n",
    "show_image(rescale_and_resize(images[0]), targets[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5b886c27",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "1c2e2853426a640227d69892a38e8250",
     "grade": true,
     "grade_id": "cell-cfd89fb8cbcec231",
     "locked": true,
     "points": 2,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('rescale_and_resize')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "053649d0",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "4f93e8f3413c7f585d48368707148246",
     "grade": false,
     "grade_id": "cell-75388a1741e14c88",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Now use the function to pre-process the data in the variable `images` and save the preprocessed images in an np.ndarray `images_preprocessed`._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "a880cd0d",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "9403f9bc6c73d10b1e8066f7d493c251",
     "grade": false,
     "grade_id": "cell-db4f53cb45712358",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "Field elements must be 2- or 3-tuples, got '<tf.Tensor: shape=(224, 224, 3), dtype=float32, numpy=\narray([[[3.62228662e-01, 4.73393321e-01, 1.20650843e-01],\n        [3.89320761e-01, 4.96034652e-01, 1.24408752e-01],\n        [4.49940532e-01, 5.18850565e-01, 1.85068652e-01],\n        ...,\n        [8.11332941e-01, 3.68276215e-03, 5.26478793e-03],\n        [9.86966610e-01, 2.78357655e-01, 2.87368953e-01],\n        [9.92305756e-01, 3.22194844e-01, 3.17315608e-01]],\n\n       [[3.87646466e-01, 4.95932847e-01, 1.16319738e-01],\n        [4.34400409e-01, 5.34415603e-01, 1.44085839e-01],\n        [4.81179982e-01, 5.44180453e-01, 1.96134880e-01],\n        ...,\n        [9.26173091e-01, 6.05450645e-02, 9.05410126e-02],\n        [9.94685709e-01, 2.92566210e-01, 3.20070416e-01],\n        [9.90457058e-01, 2.84742385e-01, 2.66508609e-01]],\n\n       [[3.94689381e-01, 4.98479337e-01, 9.12902653e-02],\n        [4.71523941e-01, 5.51204622e-01, 1.52192295e-01],\n        [4.75770324e-01, 5.33744812e-01, 1.66272774e-01],\n        ...,\n        [9.87604916e-01, 1.82052538e-01, 2.13776961e-01],\n        [9.78043854e-01, 2.86137164e-01, 3.07751864e-01],\n        [9.78098571e-01, 2.37717673e-01, 2.22479761e-01]],\n\n       ...,\n\n       [[1.03126749e-01, 2.19832376e-01, 1.20094800e-02],\n        [1.00054115e-01, 2.09492028e-01, 9.32747556e-04],\n        [1.14610888e-01, 2.08756715e-01, 2.19178433e-03],\n        ...,\n        [8.10456812e-01, 8.48434925e-01, 1.86606199e-01],\n        [8.68858635e-01, 9.04105604e-01, 3.62934291e-01],\n        [4.58326012e-01, 4.22460288e-01, 1.57844722e-01]],\n\n       [[1.14979185e-01, 2.02157289e-01, 1.96072888e-02],\n        [8.06696564e-02, 1.90616041e-01, 3.50522343e-03],\n        [8.21165890e-02, 1.86425894e-01, 2.63230153e-03],\n        ...,\n        [8.49322319e-01, 8.73741746e-01, 4.03781593e-01],\n        [8.90273452e-01, 9.32911098e-01, 2.69185096e-01],\n        [6.21150732e-01, 6.09833181e-01, 2.01512381e-01]],\n\n       [[1.71221793e-01, 2.39245892e-01, 8.00799504e-02],\n        [7.50381127e-02, 1.82844579e-01, 2.16052402e-03],\n        [6.84331879e-02, 1.81204617e-01, 2.72904406e-03],\n        ...,\n        [8.94015372e-01, 9.01528120e-01, 2.24459663e-01],\n        [8.58611584e-01, 8.96711409e-01, 2.69037396e-01],\n        [6.57291591e-01, 7.05177069e-01, 1.04208440e-01]]], dtype=float32)>'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[62], line 2\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;66;03m# YOUR CODE HERE\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m images_preprocessed \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mndarray\u001b[49m\u001b[43m(\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mrescale_and_resize\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mimg\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mimages\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m      3\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m()\n",
      "\u001b[0;31mTypeError\u001b[0m: Field elements must be 2- or 3-tuples, got '<tf.Tensor: shape=(224, 224, 3), dtype=float32, numpy=\narray([[[3.62228662e-01, 4.73393321e-01, 1.20650843e-01],\n        [3.89320761e-01, 4.96034652e-01, 1.24408752e-01],\n        [4.49940532e-01, 5.18850565e-01, 1.85068652e-01],\n        ...,\n        [8.11332941e-01, 3.68276215e-03, 5.26478793e-03],\n        [9.86966610e-01, 2.78357655e-01, 2.87368953e-01],\n        [9.92305756e-01, 3.22194844e-01, 3.17315608e-01]],\n\n       [[3.87646466e-01, 4.95932847e-01, 1.16319738e-01],\n        [4.34400409e-01, 5.34415603e-01, 1.44085839e-01],\n        [4.81179982e-01, 5.44180453e-01, 1.96134880e-01],\n        ...,\n        [9.26173091e-01, 6.05450645e-02, 9.05410126e-02],\n        [9.94685709e-01, 2.92566210e-01, 3.20070416e-01],\n        [9.90457058e-01, 2.84742385e-01, 2.66508609e-01]],\n\n       [[3.94689381e-01, 4.98479337e-01, 9.12902653e-02],\n        [4.71523941e-01, 5.51204622e-01, 1.52192295e-01],\n        [4.75770324e-01, 5.33744812e-01, 1.66272774e-01],\n        ...,\n        [9.87604916e-01, 1.82052538e-01, 2.13776961e-01],\n        [9.78043854e-01, 2.86137164e-01, 3.07751864e-01],\n        [9.78098571e-01, 2.37717673e-01, 2.22479761e-01]],\n\n       ...,\n\n       [[1.03126749e-01, 2.19832376e-01, 1.20094800e-02],\n        [1.00054115e-01, 2.09492028e-01, 9.32747556e-04],\n        [1.14610888e-01, 2.08756715e-01, 2.19178433e-03],\n        ...,\n        [8.10456812e-01, 8.48434925e-01, 1.86606199e-01],\n        [8.68858635e-01, 9.04105604e-01, 3.62934291e-01],\n        [4.58326012e-01, 4.22460288e-01, 1.57844722e-01]],\n\n       [[1.14979185e-01, 2.02157289e-01, 1.96072888e-02],\n        [8.06696564e-02, 1.90616041e-01, 3.50522343e-03],\n        [8.21165890e-02, 1.86425894e-01, 2.63230153e-03],\n        ...,\n        [8.49322319e-01, 8.73741746e-01, 4.03781593e-01],\n        [8.90273452e-01, 9.32911098e-01, 2.69185096e-01],\n        [6.21150732e-01, 6.09833181e-01, 2.01512381e-01]],\n\n       [[1.71221793e-01, 2.39245892e-01, 8.00799504e-02],\n        [7.50381127e-02, 1.82844579e-01, 2.16052402e-03],\n        [6.84331879e-02, 1.81204617e-01, 2.72904406e-03],\n        ...,\n        [8.94015372e-01, 9.01528120e-01, 2.24459663e-01],\n        [8.58611584e-01, 8.96711409e-01, 2.69037396e-01],\n        [6.57291591e-01, 7.05177069e-01, 1.04208440e-01]]], dtype=float32)>'"
     ]
    }
   ],
   "source": [
    "# YOUR CODE HERE\n",
    "images_preprocessed = np.ndarray((1,), [rescale_and_resize(img) for img in images])\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f767e9cf",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "ab073c4d8d13a773b25c7593eb989630",
     "grade": true,
     "grade_id": "cell-3511cf050a781aab",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('images_preprocessed')\n",
    "assert type(images_preprocessed) == np.ndarray, \"Make sure to store your answer as a np.ndarray\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94226e02",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "077387018e16644826fd4e066af0bac9",
     "grade": false,
     "grade_id": "cell-0825cee2278d9239",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "One approach to represent the image labels so that they can be trainable by a neural network is to represented them as a one-hot vector. \n",
    "\n",
    "_Write a function `one_hot_encoding` that takes the integer label and returns a one-hot vector of the label._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e40efe42",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "2a20a5b6a598460960720ee49678a575",
     "grade": false,
     "grade_id": "cell-f8acfd909ba340a6",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "def one_hot_encoding(target):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()\n",
    "\n",
    "print(f\"target: {targets[0]}, encoding: {one_hot_encoding(targets[0])}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8736ec68",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "0adb27dc2f6de0791a6b8c2d3da175ec",
     "grade": false,
     "grade_id": "cell-48b78919122984cd",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Now use the function `one_hot_encoding` to create an np.ndarray of the one-hot representations of all the labels in `targets` and save them in `targets_preprocessed`._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b91925ad",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "c1b73325cca5ea5c87c016fa8679da87",
     "grade": false,
     "grade_id": "cell-66f4d1b4865c393b",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "008bf36d",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "77ce70a606155c9bd692ea157f2ba4c5",
     "grade": true,
     "grade_id": "cell-b7bd3e108b492d1a",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('targets_preprocessed')\n",
    "assert type(targets_preprocessed) == np.ndarray, \"Make sure to store your answer as a np.ndarray\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93a82e2e",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "41c81734a6061adb3960393c731fbcb8",
     "grade": false,
     "grade_id": "cell-064a192e04bbe563",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "In this notebook you will train different models and compare them against each other. \n",
    "\n",
    "Now that the data is pre-processed. We will split the data in three datasets, a train, validation and test set. \n",
    "\n",
    "_Why do we need these three sets and what do we use them for._"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a070cee1",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "e411d567e9977776b601d7b2b60e317f",
     "grade": true,
     "grade_id": "cell-a9728f3a37f9b12d",
     "locked": false,
     "points": 3,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ffd06ef7",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "e8ede38fcd2fe8b3353140b6185a939b",
     "grade": false,
     "grade_id": "cell-5f7c36786ea1ac16",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Now split the data such that we have a train set with 80\\% of the samples and a validation and test set each with 10\\% of the samples. Save the results in `x_train`, `y_train`, `x_val`, `y_val`, `x_test`, and `y_test`._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5fb75b70",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "9cc2c69bb2fa3aa04c24a14b0c7c0c4e",
     "grade": false,
     "grade_id": "cell-0d2a7323600586f0",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "tf.keras.utils.set_random_seed(371947)\n",
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()\n",
    "\n",
    "print(f\"Train samples: {len(x_train)}, Validation samples: {len(x_test)}, Test samples: {len(x_val)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "caaff270",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "14729a3cfe23681c3c0310bcf17af528",
     "grade": true,
     "grade_id": "cell-2e10a0d0c102a096",
     "locked": true,
     "points": 2,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('x_train')\n",
    "check_var_defined('y_train')\n",
    "\n",
    "check_var_defined('x_val')\n",
    "check_var_defined('y_val')\n",
    "\n",
    "check_var_defined('x_test')\n",
    "check_var_defined('y_test')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc327e32",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "6274d96a91edd7e1292a5b6355ea3bef",
     "grade": false,
     "grade_id": "cell-383c6a2fa62bb715",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "WARNING: Before we continue we delete the variable `images_preprocessed` (you don't need that anymore) to manage our RAM consumption. If you want to use that variable again you will have to rerun the cell that creates it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "156ef4a4",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "7aefd78f3a200aeea2cb44ab96d4578a",
     "grade": false,
     "grade_id": "cell-97bcc5cb67d2816b",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# Freeing up RAM by deleting this variable\n",
    "del images_preprocessed"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cccda08d",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "5c9e2a2efad571fc5c110c912ee46805",
     "grade": false,
     "grade_id": "cell-30894c26978e5d77",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "# Part 2: Training a basic CNN model \n",
    "\n",
    "Now that we have pre-processed the data and split it into different parts for training, validation and testing, you can start training some neural networks. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a19e6a8",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "f28ec881e0bb1e54f3f45c022b8774be",
     "grade": false,
     "grade_id": "cell-bff4b784586115f7",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "Our model will take as input the $224 \\times 224$ rgb (3-channel) images and will give as output a length five vector of which the different elements correspond to the five different classes. \n",
    "\n",
    "The model will start with convolutional layers followed by a hidden dense layer and then the final dense layer that gives us our output. \n",
    "\n",
    "_What kind of activation function should we use on the convolutional, dense and output layers and why these specific activation functions? (motivate your answers)_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "409a0e94",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "77b3bb801e2b3da0731abff4924aec74",
     "grade": true,
     "grade_id": "cell-50455d0a455cb88d",
     "locked": false,
     "points": 3,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a35b7d12",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "5a5e9aca09fced3bed74485bd77db7d6",
     "grade": false,
     "grade_id": "cell-bfa3eeeb3542219a",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Create a model using the `tf.keras.models.Sequential()` model and add to that:_\n",
    "\n",
    "- Input layer: A 2D convolutional layer with 8 filters, a 3x3 kernel and the ReLU activation function. Specify that this layer has an `input_shape` of (224, 224, 3)_ \n",
    "- A 2D MaxPool layer with strides 2x2\n",
    "\n",
    "- A 2D convolutional layer with 16 filters, a 3x3 kernel and a the ReLU activation function\n",
    "- A 2D MaxPool layer with strides 2x2\n",
    "\n",
    "- A 2D convolutional layer with 32 filters, a 3x3 kernel and a the ReLU activation function\n",
    "- A 2D MaxPool layer with strides 2x2\n",
    "\n",
    "- A 2D convolutional layer with 32 filters, a 3x3 kernel and a the ReLU activation function\n",
    "- A 2D MaxPool layer with strides 2x2\n",
    "\n",
    "- A Flatten layer to flatten the filters to a single vector\n",
    "- A Dense layer with 32 nodes and your chosen activation\n",
    "\n",
    "- Output layer: A Dense layer with 5 nodes and your chosen activation\n",
    "\n",
    "_Store the model in the variable `model_basic`._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b869ea33",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "9260f5cd8f6f4294a65d990d4b4811d8",
     "grade": true,
     "grade_id": "cell-07bac90b1f60520f",
     "locked": false,
     "points": 3,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "tf.keras.backend.clear_session()\n",
    "tf.keras.utils.set_random_seed(93612)\n",
    "\n",
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dfd1b4b1",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "31e5c487515b6eb896b76f01274fa4e1",
     "grade": true,
     "grade_id": "cell-6f80d53f202270f5",
     "locked": true,
     "points": 0,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('model_basic')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "732cd91b",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "0a0467c488cd028d8b4f31654da06172",
     "grade": false,
     "grade_id": "cell-fb2a62d393542d0d",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "To compile the model we need to specify a loss function. \n",
    "\n",
    "_What loss function would be appropriate for this multi-class classfication problem?_\n",
    "\n",
    "_Also, during training we would like to monitor how well our model performs on predicting the targets. What would be a good metric to track? Motivate your answers._ "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fcc8c8c",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "2c0d8befa01ec00ced7f85f0e9716399",
     "grade": true,
     "grade_id": "cell-0cdde96c1310bf02",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99fcaf9a",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "4efc96f0206afd42ee2b8b2b28952a9f",
     "grade": false,
     "grade_id": "cell-4a033537b6ee9406",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "Now compile the model using the `Adam` optimiser (with a `learning_rate` of 1e-4), your chosen loss, and your chosen metric to track. (Tip: TF has some loss function and metrics implemented in [tf.keras.losses](https://www.tensorflow.org/api_docs/python/tf/keras/losses) and [tf.keras.metrics](https://www.tensorflow.org/api_docs/python/tf/keras/metrics).)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0daef6f2",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "65e0a8df26061b87c55af408082d9018",
     "grade": true,
     "grade_id": "cell-82f41439014ffdad",
     "locked": false,
     "points": 1,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b3f30c12",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "49c1362aa1b61db1c6ba1e0b660622da",
     "grade": true,
     "grade_id": "cell-05e3602641ad48ce",
     "locked": true,
     "points": 0,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('model_basic')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9414b548",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "1f382259b7899502ac4aac68a8ac4998",
     "grade": false,
     "grade_id": "cell-a109b929fd00512d",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Now fit the train data for 10 epochs and save the training history in the variable `history_basic`. Also specify the `validation_data` and a `batch_size` of 32._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5f355c96",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "56cd98d186929b568e2f9f81368720a7",
     "grade": true,
     "grade_id": "cell-33eed7f2f5756706",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "tf.keras.utils.set_random_seed(47290)\n",
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d123574b",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "df7229f0fa928a3cc4c45fb2f2759d54",
     "grade": true,
     "grade_id": "cell-ca82ca44cd2514f0",
     "locked": true,
     "points": 0,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('history_basic')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8aae7b43",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "ef84465233211abf5df74bdd82bbdead",
     "grade": false,
     "grade_id": "cell-5e75bbc569fe9852",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Now to see how the model performs, write a function `plot_metrics` that plots the loss for the train and validation set. In the same function also create a separate plot that plots the other metric for the train and validation set._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "38bb58e0",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "a5bdb9abb70f3a6d27b0a5a96972a350",
     "grade": true,
     "grade_id": "cell-61240c7d5919394e",
     "locked": false,
     "points": 3,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "def plot_metrics(history):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()\n",
    "    \n",
    "plot_metrics(history_basic)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92bba19a",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "bd1e870f79c2e6d81c41ace194b0ebe4",
     "grade": false,
     "grade_id": "cell-19742c74e422d586",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Comment on the performance of the model based the tracked loss and metric_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e27cebe",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "8e94b63bf3b595eb26cdf1b881cc8abc",
     "grade": true,
     "grade_id": "cell-e6ba8b200c4b3147",
     "locked": false,
     "points": 1,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d15de46",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "2e655dbc985e6392b5ddbcc72ca6e229",
     "grade": false,
     "grade_id": "cell-151e07a3bf171490",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "*What happens if we were to train the model for more epochs? What will happen to the performance of the model?*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc6353ec",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "793762314007eaee2230eb75a100a0c0",
     "grade": true,
     "grade_id": "cell-9b5a09ea6043f78b",
     "locked": false,
     "points": 1,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af62740d",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "08f400f65ad158d2f87611c7a71ba058",
     "grade": false,
     "grade_id": "cell-738ce98653d1a570",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "*Write a function `model_predict` that takes the model and some image data and returns the predicted targets (as integers corresponding to the predicted labels).* "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f22e89cb",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "e40d60ca339a73ff568d0961f7e900ff",
     "grade": false,
     "grade_id": "cell-cfb685b6f75c6006",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "def model_predict(model, x):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()\n",
    "    return predicted_targets"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aacd284a",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "f19da898555f0263ef177dc0ed28374e",
     "grade": false,
     "grade_id": "cell-e8629ecfe3f00676",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Gather the targets of the test set (scalar integer value corresponding to the labels) and save them in `test_targets`._\n",
    "\n",
    "_Compute the targets for `model_basic` and store them in the variable `test_targets_basic`._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3565c7b9",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "e9a5b17685ffee2ab1de566b7ba2b168",
     "grade": false,
     "grade_id": "cell-cbe466cfa34d7e4b",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a7f97fbb",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "aa0abefb84844c72e579327d68fd75ee",
     "grade": true,
     "grade_id": "cell-9e9b4d1d290afa50",
     "locked": true,
     "points": 2,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('test_targets')\n",
    "check_var_defined('test_targets_basic')\n",
    "\n",
    "assert test_targets.ndim == 1, \"Make sure you are only predicting the scalar label value not the one hot vectors\"\n",
    "assert test_targets_basic.ndim == 1, \"Make sure you are only predicting the scalar label value not the one hot vectors\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "841af931",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "c3fefe19959c788d51c8741c70763997",
     "grade": false,
     "grade_id": "cell-a46cb8c0103a4c02",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Calculate the precision and recall averaged over the 5 classes. (Precision and recall for each classes and then avaraged in one score)_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5047120",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "fa62df2d562bac9c7210862873ba902d",
     "grade": false,
     "grade_id": "cell-2dc0bd5540e9f26b",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "def average_recall_precision(y, y_predict):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()\n",
    "\n",
    "    print(f\"Average Recall: {recall:.3f}, Average Precision {precision:0.3f}\")\n",
    "    return recall, precision\n",
    "\n",
    "recall_basic, precision_basic = average_recall_precision(test_targets, test_targets_basic)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5d9aae79",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "8d7838e29e632bcfa1a9ce7da5218100",
     "grade": true,
     "grade_id": "cell-da4b4b840b2dd7b5",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('recall_basic')\n",
    "check_var_defined('precision_basic')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "49508417-b4f1-4880-9554-2015bc064a18",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "244174442f031c3dc061fa1552ae8919",
     "grade": true,
     "grade_id": "cell-0817deec60dce891",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "04eb1d82",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "91c5670a7abf30249e2812eb51b47444",
     "grade": false,
     "grade_id": "cell-2b085c7cf1510472",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Show the predicted targets in a confusion matrix. Show the predicted labels in percentages (percentage of the samples from true class labeled as predicted class) and add the labels to the axes._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b4795f7",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "913d7788ac41f1a1a351e0730056d72c",
     "grade": true,
     "grade_id": "cell-2399b15ba35796cd",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\n",
    "\n",
    "def plot_confusion_matrix(y, y_pred, title=\"\"):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()\n",
    "    plt.title(title)\n",
    "    plt.show()\n",
    "\n",
    "plot_confusion_matrix(test_targets, test_targets_basic, \"basic model\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd514aca",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "879d47a1563a4574537052e39ade0729",
     "grade": false,
     "grade_id": "cell-42cbefa4adf96a73",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Comment on the recall and precision of the model, as well as the predictions in the confusion matrix._"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89866352",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "3e2ac185cd5e069336a59850767c5c95",
     "grade": true,
     "grade_id": "cell-6a7fca3e2bf83f7f",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3edf45c3",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "5b767c57e15f18abc0089a5e5650afe3",
     "grade": false,
     "grade_id": "cell-d356a7145292ec49",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "# Part 3: Improving the model\n",
    "\n",
    "To improve on the model we will include some Dropout layers. \n",
    "\n",
    "_What do dropout layers do and why might this increase the performance of our models?_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4b05027",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "e91f9ddbac41c7048beebaa26453963a",
     "grade": true,
     "grade_id": "cell-d51957783a8b8f11",
     "locked": false,
     "points": 3,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c99ebc0",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "dd2566932baca09a6f679c828996194c",
     "grade": false,
     "grade_id": "cell-7f4c0f0200535322",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "Another method to improve the model is by using a technique called data augmentation. \n",
    "\n",
    "_Explain the concept data augmentation and explain how it might increase the performance of our model._"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e73d6db6",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "f11e0ec2ffa6c21658d7bcf6bbd17dec",
     "grade": true,
     "grade_id": "cell-8490281b269b4500",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "af5368bf",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "b07bc2ef06fc01df17799136bea01510",
     "grade": false,
     "grade_id": "cell-fac7ac8abd544790",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Use the exact same model as for the `model_basic`, but play around with adding in a data augmentation layer (e.g. [tf.keras.layers.RandomFlip](https://www.tensorflow.org/api_docs/python/tf/keras/layers/RandomFlip) ) and adding in dropout layers (dropout is typically only added in the dense part of the network). Store the new model in the variable `model_dropout` and compile it using the same metrics and loss as before._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cae90829",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "5a19d58043b584bf8350c53034028644",
     "grade": true,
     "grade_id": "cell-25d3daacfe968aa2",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "tf.keras.backend.clear_session()\n",
    "tf.keras.utils.set_random_seed(48263)\n",
    "\n",
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "77868aae",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "b072fbdbe92be0f3926ceaf0935a6de0",
     "grade": true,
     "grade_id": "cell-824a00bec8ece0ac",
     "locked": true,
     "points": 0,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('model_dropout')\n",
    "model_dropout.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6778a133",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "f825eb30514de109277305d52676cf9d",
     "grade": false,
     "grade_id": "cell-e6b6f0ea7ef2d37a",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Fit the new model in the same way as before and save the history in `history_dropout`. However, train for 20 epochs instead of 10._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "92ec2689",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "c89d459ee4ecefb767369c54929ecfb0",
     "grade": true,
     "grade_id": "cell-82fcca9814ec3c0e",
     "locked": false,
     "points": 1,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "tf.keras.utils.set_random_seed(103745)\n",
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5048652c",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "35d4e0daf253b3a62a9f19ff3dac107b",
     "grade": true,
     "grade_id": "cell-df6e944e1dfa0984",
     "locked": true,
     "points": 0,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('history_dropout')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "128cc76b",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "98d15e93390af85cc8b0e007b9dc242a",
     "grade": false,
     "grade_id": "cell-0ddc85bc444c422c",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "plot_metrics(history_dropout)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c10bf8c3",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "979f4033a7940ff00c6f7ca954637940",
     "grade": false,
     "grade_id": "cell-b670310c7765e587",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Comment on the performance of the improved model based on the loss and metrics during training._"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b3faf05",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "00191b16cf0e011c9d03a1129754e555",
     "grade": true,
     "grade_id": "cell-6927b7d95cf333bb",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4bc94e80",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "efc719533371854eb0212f0e5c2b10ec",
     "grade": false,
     "grade_id": "cell-ce1c537bdeaf042b",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Why did we have to train the model for more epochs than the basic model?_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d81fb816",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "7532010e993a0c2cf68ea538cc1828cb",
     "grade": true,
     "grade_id": "cell-ed5fd1fcd6d7edae",
     "locked": false,
     "points": 1,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d43af512",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "0019529f078ddad35635d799818a93a4",
     "grade": false,
     "grade_id": "cell-6fe45193734a98f1",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "Now we evaluate our model on the test set using the functions you wrote before"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5d2ea24",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "a8a74e97055b77988de9ab2d2bbe584d",
     "grade": false,
     "grade_id": "cell-dbb41e724cc87ef4",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "test_targets_dropout = model_predict(model_dropout, x_test)\n",
    "recall_dropout, precision_dropout = average_recall_precision(test_targets, test_targets_dropout)    \n",
    "plot_confusion_matrix(test_targets, test_targets_dropout, \"Dropout model\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dbae38a3",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "1ff7f78be2332484fcb2a4f42c88024b",
     "grade": true,
     "grade_id": "cell-38adf79a9623097a",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('test_targets_dropout')\n",
    "check_var_defined('recall_dropout')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "98f7bbc4",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "ef2773bada37ac2e989c915fd1c202ac",
     "grade": true,
     "grade_id": "cell-893d3a09e7d217a5",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('test_targets_dropout')\n",
    "check_var_defined('precision_dropout')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1997b4c",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "45af3ed742ffc985d3ae0d1bb0642ec9",
     "grade": false,
     "grade_id": "cell-ee9f450cfd4f28c1",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Comment on the precision and recall of the model as well as the predictions in the confusion matrix_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c67b7709",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "4fff78a473cf809da4746a10024bf93a",
     "grade": true,
     "grade_id": "cell-5e65073f0a33499f",
     "locked": false,
     "points": 1,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "916a0268",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "16a0f02889f362263892d78966b2cdf7",
     "grade": false,
     "grade_id": "cell-05958d87bacb98bb",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "# Part 4: Transfer learning\n",
    "\n",
    "In order to improve our model even further, we will make use of transfer learning. \n",
    "\n",
    "_Explain in your own words what tranfer learning means and why it would help in our particular case._"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8beb5bd3",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "008803ee61ecba25492a7b6ab82d276c",
     "grade": true,
     "grade_id": "cell-308cc1a86688dfa3",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c876e43",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "9738191e10f9792a81f9d65df11ab118",
     "grade": false,
     "grade_id": "cell-471888928c62b0bd",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "Below you can see how we load in a pre-trained MobileNet that is trained on the ImageNet datastet. By not including the top part of the network we get only the convolutional layers and can add our own dense layers after that. We set all the layers of the MobileNet as not trainable, since this would be computationally expensive to do and we also want to avoid overfitting. Instead we will only be training the dense part. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "152fe58b",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "f6cb7992b095564ec69734777844f1f2",
     "grade": false,
     "grade_id": "cell-cb1e989dcd98ff48",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "mobilenet = tf.keras.applications.mobilenet.MobileNet(\n",
    "    input_shape=(224, 224, 3),\n",
    "    include_top=False, \n",
    "    weights='imagenet'\n",
    ")\n",
    "\n",
    "for layer in mobilenet.layers:\n",
    "   layer.trainable = False\n",
    "\n",
    "print(\"Output shape of the MobileNet: \", mobilenet.output_shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "864f49e7",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "c8249bc8280f0c194b5224a4898b45d0",
     "grade": false,
     "grade_id": "cell-40d065f39b3e5f02",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Use a sequential model and add the MobileNet, followed by a MaxPool2D layer, and then the dense part of the network which you can use the same as we have used in the previous models. Store the model in the variable `model_mobilenet`. Compile the model using the same metrics, loss and optimiser as before._"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6427f088",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "8fbbe772986c6b73371072f2bdaa32f3",
     "grade": true,
     "grade_id": "cell-0e5534072707a1a9",
     "locked": false,
     "points": 3,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "tf.keras.backend.clear_session()\n",
    "tf.keras.utils.set_random_seed(387453)\n",
    "\n",
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "27b1a82a",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "3908bbc5d4a03396a323b818481eff71",
     "grade": true,
     "grade_id": "cell-1901a93a5517baf3",
     "locked": true,
     "points": 0,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('model_mobilenet')\n",
    "model_mobilenet.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32486ee9",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "74a789206fadd2fe414bb72553f5cd94",
     "grade": false,
     "grade_id": "cell-f779ec7bb8b27b20",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "*Train the model in the same way as before, for 10 epochs.*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b06557e3",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "b5a02272f53a882dc78ea8dfc863738f",
     "grade": true,
     "grade_id": "cell-aacaa24fc5614424",
     "locked": false,
     "points": 1,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "tf.keras.utils.set_random_seed(9673)\n",
    "# YOUR CODE HERE\n",
    "raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6268f779",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "ca257ea8df19cb9c0c69b5791331d558",
     "grade": true,
     "grade_id": "cell-0afec72710b80268",
     "locked": true,
     "points": 0,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('history_mobilenet')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6cbcc8b8",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "fbb6ea9e46c5fb28ddabec590a316660",
     "grade": false,
     "grade_id": "cell-d159d268c6e2d3b7",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "plot_metrics(history_mobilenet)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fd842596",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "0496a72dd46f2c72d22da989a15c2476",
     "grade": false,
     "grade_id": "cell-d87a64b79f1549a7",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "test_targets_mobilenet = model_predict(model_mobilenet, x_test)\n",
    "recall_mobilenet, precision_mobilenet = average_recall_precision(test_targets, test_targets_mobilenet)    \n",
    "plot_confusion_matrix(test_targets, test_targets_mobilenet, \"Mobilenet model\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2342a8b",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "42cb5f8e28e56b7043c36d5df75d2983",
     "grade": true,
     "grade_id": "cell-40f99ea46ff86e1b",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('test_targets_mobilenet')\n",
    "check_var_defined('recall_mobilenet')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2bb96e04",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "d14981d8b3ee887ec733ccdf2a5c4087",
     "grade": true,
     "grade_id": "cell-9cf521b9f236b452",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "check_var_defined('precision_mobilenet')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59328ebf",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "5c1cb00105466e9970116015677dc3c1",
     "grade": false,
     "grade_id": "cell-8ef0296961e07f6f",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Comment on the results from the transfer-learned model and why the results differ to the case considered previously without transfer learning._"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81595522",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "61f54494e95241953588077a482d2287",
     "grade": true,
     "grade_id": "cell-d7f4cdf7f9265a07",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "765888af",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "4e1abcc1a230cf42061638a716dde7e9",
     "grade": false,
     "grade_id": "cell-0f6125b686f4ee8e",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "_Suggest some ways the model could be improved further._"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "835f9579",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "markdown",
     "checksum": "29e376668ed2a5736535480ca1085599",
     "grade": true,
     "grade_id": "cell-316415b7bac4ae5f",
     "locked": false,
     "points": 2,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "source": [
    "YOUR ANSWER HERE"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
