diff --git a/02_activities/assignments/assignment_1.ipynb b/02_activities/assignments/assignment_1.ipynb index 6a1f0581..3e5b99fc 100644 --- a/02_activities/assignments/assignment_1.ipynb +++ b/02_activities/assignments/assignment_1.ipynb @@ -1,309 +1,805 @@ { - "cells": [ - { - "cell_type": "markdown", - "id": "927ae8f4", - "metadata": {}, - "source": [ - "# Assignment 1 - Building a Vision Model with Keras\n", - "\n", - "In this assignment, you will build a simple vision model using Keras. The goal is to classify images from the Fashion MNIST dataset, which contains images of clothing items.\n", - "\n", - "You will:\n", - "1. Load and inspect the Fashion MNIST dataset.\n", - "2. Run a simple baseline model to establish a performance benchmark.\n", - "3. Build and evaluate a simple CNN model, choosing appropriate loss and metrics.\n", - "4. Design and run controlled experiments on one hyperparameter (e.g., number of filters, kernel size, etc.) and one regularization technique (e.g., dropout, L2 regularization).\n", - "5. Analyze the results and visualize the model's performance.\n", - "\n", - "# 1. Loading and Inspecting the Dataset\n", - "\n", - "Fashion MNIST is a dataset of grayscale images of clothing items, with 10 classes. Each image is 28x28 pixels, like the MNIST dataset of handwritten digits. Keras provides a convenient way to load this dataset. \n", - "\n", - "In this section, you should:\n", - "\n", - "- [ ] Inspect the shapes of the training and test sets to confirm their size and structure.\n", - "- [ ] Convert the labels to one-hot encoded format if necessary. (There is a utility function in Keras for this.)\n", - "- [ ] Visualize a few images from the dataset to understand what the data looks like." - ] + "cells": [ + { + "cell_type": "markdown", + "id": "927ae8f4", + "metadata": { + "id": "927ae8f4" + }, + "source": [ + "# Assignment 1 - Building a Vision Model with Keras\n", + "\n", + "In this assignment, you will build a simple vision model using Keras. The goal is to classify images from the Fashion MNIST dataset, which contains images of clothing items.\n", + "\n", + "You will:\n", + "1. Load and inspect the Fashion MNIST dataset.\n", + "2. Run a simple baseline model to establish a performance benchmark.\n", + "3. Build and evaluate a simple CNN model, choosing appropriate loss and metrics.\n", + "4. Design and run controlled experiments on one hyperparameter (e.g., number of filters, kernel size, etc.) and one regularization technique (e.g., dropout, L2 regularization).\n", + "5. Analyze the results and visualize the model's performance.\n", + "\n", + "# 1. Loading and Inspecting the Dataset\n", + "\n", + "Fashion MNIST is a dataset of grayscale images of clothing items, with 10 classes. Each image is 28x28 pixels, like the MNIST dataset of handwritten digits. Keras provides a convenient way to load this dataset.\n", + "\n", + "In this section, you should:\n", + "\n", + "- [ ] Inspect the shapes of the training and test sets to confirm their size and structure.\n", + "- [ ] Convert the labels to one-hot encoded format if necessary. (There is a utility function in Keras for this.)\n", + "- [ ] Visualize a few images from the dataset to understand what the data looks like." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "420c7178", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "420c7178", + "outputId": "ea4f8213-2719-42ba-b663-2eb4bc34e08a" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz\n", + "\u001b[1m29515/29515\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 0us/step\n", + "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz\n", + "\u001b[1m26421880/26421880\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 0us/step\n", + "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz\n", + "\u001b[1m5148/5148\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 0us/step\n", + "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz\n", + "\u001b[1m4422102/4422102\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 0us/step\n" + ] + } + ], + "source": [ + "from tensorflow.keras.datasets import fashion_mnist\n", + "(X_train, y_train), (X_test, y_test) = fashion_mnist.load_data()\n", + "\n", + "# Normalize the pixel values to be between 0 and 1\n", + "X_train = X_train.astype('float32') / 255.0\n", + "X_test = X_test.astype('float32') / 255.0\n", + "\n", + "# Classes in the Fashion MNIST dataset\n", + "class_names = [\"T-shirt/top\", \"Trouser\", \"Pullover\", \"Dress\", \"Coat\", \"Sandal\", \"Shirt\", \"Sneaker\", \"Bag\", \"Ankle boot\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a6c89fe7", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "a6c89fe7", + "outputId": "6e653f4c-5b05-44f5-c12f-e5d56b3c3a54" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Shape of X_train: (60000, 28, 28)\n", + "Shape of y_train: (60000,)\n", + "Shape of X_test: (10000, 28, 28)\n", + "Shape of y_test: (10000,)\n", + "Shape of y_train after one-hot encoding: (60000, 10)\n", + "Shape of y_test after one-hot encoding: (10000, 10)\n" + ] + } + ], + "source": [ + "# Inspect the shapes of the datasets\n", + "print(\"Shape of X_train:\", X_train.shape)\n", + "print(\"Shape of y_train:\", y_train.shape)\n", + "print(\"Shape of X_test:\", X_test.shape)\n", + "print(\"Shape of y_test:\", y_test.shape)\n", + "\n", + "# Convert labels to one-hot encoding\n", + "from tensorflow.keras.utils import to_categorical\n", + "\n", + "y_train_one_hot = to_categorical(y_train, num_classes=10)\n", + "y_test_one_hot = to_categorical(y_test, num_classes=10)\n", + "\n", + "print(\"Shape of y_train after one-hot encoding:\", y_train_one_hot.shape)\n", + "print(\"Shape of y_test after one-hot encoding:\", y_test_one_hot.shape)" + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 699 + }, + "id": "51ca90c5", + "outputId": "5b18937e-60fd-45b0-9c43-2f553ab88344" + }, + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# Visualize a few images\n", + "plt.figure(figsize=(10, 10))\n", + "for i in range(25):\n", + " plt.subplot(5, 5, i + 1)\n", + " plt.xticks([])\n", + " plt.yticks([])\n", + " plt.grid(False)\n", + " plt.imshow(X_train[i], cmap=plt.cm.binary)\n", + " plt.xlabel(class_names[y_train[i]])\n", + "plt.show()" + ], + "id": "51ca90c5", + "execution_count": 5, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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b7zxRmLbKilCxl9KFHA6sm/fPlu+fLmlp6dzpw+Y2Q9nsZs3b7asrKxCv7sQ4w+uohx/ZoxBxDH+UNw4BqM4Hcz4CzrRAAAAAICDQRgcAAAAQOI40QAAAACQOE40AAAAACTusDnRuO++++zYY4/d778PHjzYqlWrdkjPcfnll1u/fv0OaRso+/Ibi2Zmp5xyit10001Fsj84/DAGARyumP+KVqk50Zg0aZIdccQRdu655xb3rhQ7vgBFKyUl5YD/u++++xJ/zmHDhtmDDz54wD45OTmWkpJiU6dOlf9+//33269+9Ssz++E1vP322wnvJYoKYxCl3eWXX543XitUqGB169a1Xr162YsvvijX4gB+xPxXugWto1ESvPDCC3bDDTfYCy+8YMuXL7esrKzi3iUcJnJzc/P+/5AhQ+yee+6x7OzsvFpaWlriz1mjRo0D/nvIQmfvvPOO3X777UntEooRYxBlQe/eve2ll16yvXv32sqVK23UqFE2aNAge+utt2zEiBFyQcDdu3dbhQoVimFvUVIw/5VupeIvGlu2bLEhQ4bYtddea+eee64NHjw49u/jxo2zlJQU+/jjj61z585WtWpV6969e2wguhYuXGjNmze366+/fr8rG77zzjvWqVMnq1y5sjVv3tzuv/9+uVqq6/7777fatWtbRkaGXXPNNbEBuXPnTrvxxhutTp06VrlyZevZs6dNmTIl9vhPP/3UunTpYpUqVbL69evb7bffnve8l19+uX366af25JNP5p3N5+Tk5LtPKLh69erl/S8zM9NSUlJiNTXJjRs3zrp06WKpqalWrVo169Gjhy1evDjW55VXXrGmTZtaZmam/eIXv4itQOr+1app06b24IMP2mWXXWYZGRl29dVXW7NmzczMrGPHjpaSkmKnnHJKXv+lS5farFmzrHfv3ta0aVMzM+vfv7+lpKTktc3Mnn32WWvRooVVrFjRWrduba+88kpsH1NSUuzZZ5+1s88+26pUqWLNmze3t956q4DvJAqKMcgYLAsqVapk9erVswYNGlinTp3szjvvtHfeecc++OCDvOP6j5/3+eefb6mpqfbwww+b2YGPx1EU2X333WeNGze2SpUqWVZWlt144415z/vMM8/YkUceaZUrV7a6devahRdeWOSvHQXH/FfK57+oFHjhhReizp07R1EURe+++27UokWLaN++fXn/Pnbs2MjMoq5du0bjxo2LZs2aFZ144olR9+7d8/rce++90THHHBNFURRNmzYtqlevXvR///d/ef/+0ksvRZmZmXntzz77LMrIyIgGDx4cLVy4MPrwww+jpk2bRvfdd99+93PgwIFRWlpadPHFF0czZ86MRo4cGdWuXTu688478/rceOONUVZWVvT+++9Hs2bNigYOHBhVr149Wrt2bRRFUbRs2bKoatWq0XXXXRfNmTMnGj58eFSrVq3o3nvvjaIoijZs2BB169Ytuuqqq6Lc3NwoNzc32rNnT4HfWxwcd5wou3fvjjIzM6Pf//730YIFC6LZs2dHgwcPjhYvXhxF0Q9jMS0tLfrZz34WzZgxI/rss8+ievXqxcbJySefHA0aNCiv3aRJkygjIyP661//Gi1YsCBasGBB9OWXX0ZmFo0ZMybKzc3NG0NRFEV///vfozPPPDOKoihatWpVZGbRSy+9FOXm5karVq2KoiiKhg0bFlWoUCF6+umno+zs7OjRRx+NjjjiiOiTTz7J246ZRTVr1oyee+65KDs7O7rrrruiI444Ipo9e/ahvpUoIMYgY7A0GjhwYNS3b1/5b8ccc0x09tlnR1H0w+ddp06d6MUXX4wWLlwYLV68ON/j8ZtvvhllZGRE77//frR48eJo8uTJ0b/+9a8oiqJoypQp0RFHHBG99tprUU5OTvTNN99ETz75ZJG8ZiSP+a/0zX+l4kSje/fu0RNPPBFF0Q8DqFatWtHYsWPz/v3HE40xY8bk1d57773IzKLt27dHUfT/TjQmTJgQVa9ePfrrX/8aew538J5++unRH/7wh1ifV155Japfv/5+93PgwIFRjRo1oq1bt+bVnn322SgtLS3au3dvtGXLlqhChQrRq6++mvfvu3btirKysqJHHnkkiqIouvPOO6PWrVvHTqSefvrpvG1Ekf8FQNEJmeTWrl0bmVk0btw4+e/33ntvVLVq1WjTpk15tVtuuSXq2rVrXltNcv369YttZ9GiRZGZRd9++633HL169Yr+/ve/57XNLBo+fHisT/fu3aOrrroqVrvooouic845J/a4a665Jtana9eu0bXXXitfGwofY5AxWBod6ETj4osvjtq2bRtF0Q+f90033RT79/yOx48++mjUqlWraNeuXd62hw4dGmVkZMTGOkov5r/SN/+V+EunsrOz7csvv7QBAwaYmVn58uXt4osvthdeeMHr26FDh7z/X79+fTMzW7VqVV5tyZIl1qtXL7vnnnvsd7/73QGfd9q0afbAAw9YWlpa3v+uuuoqy83NtW3btu33ccccc4xVrVo1r92tWzfbsmWLLV261BYuXGi7d++2Hj165P17hQoVrEuXLjZnzhwzM5szZ45169bNUlJS8vr06NHDtmzZYsuWLTvgPqPoLVmyJDZG/vCHP1iNGjXs8ssvt7POOsv69OljTz75ZOwaU7Mf/gybnp6e165fv35srCqdO3cO2qdNmzbZp59+aueff/4B+82ZMyc2Fs1+GGs/jsUfdevWzWu7fVB8GIMo7aIoih3z3HGW3/H4oosusu3bt1vz5s3tqquusuHDh+ddVtWrVy9r0qSJNW/e3C699FJ79dVXD3gMR+nC/FfylfgTjRdeeMH27NljWVlZVr58eStfvrw9++yzNnToUNu4cWOs708DYz9OWj+9m0Xt2rWtS5cu9vrrr9umTZsO+Lxbtmyx+++/36ZOnZr3vxkzZtj8+fOtcuXKCb5ClGZZWVmxMXLNNdeYmdlLL71kkyZNsu7du9uQIUOsVatW9sUXX+Q9zg03pqSk5HvnldTU1KB9+uCDD+yoo46yRo0aHeSrQWnEGERpN2fOnLzr3c38cZbf8bhRo0aWnZ1tzzzzjFWpUsWuu+46O+mkk2z37t2Wnp5u33zzjb3++utWv359u+eee+yYY46xDRs2FPGrRGFg/iv5SvSJxp49e+zll1+2Rx99NDaQpk2bZllZWfb6668f1PaqVKliI0eOtMqVK9tZZ50VC/64OnXqZNnZ2dayZUvvf+XK7f9tmzZtmm3fvj2v/cUXX1haWpo1atQoL/AzYcKEvH/fvXu3TZkyxY466igzM2vbtq1NmjQpFlCfMGGCpaenW8OGDc3MrGLFirZ3796Deu0oHOXLl4+NjZ/eqaJjx452xx132MSJE61du3b22muvJfrcFStWNDPzxsI777xjffv2jdUqVKjg9Wvbtm1sLJr9MNZ+HIs/+unk/GO7bdu2h7TvSA5jEKXZJ598YjNmzLALLrhgv31CjsdVqlSxPn362FNPPWXjxo2zSZMm2YwZM8zsh+/IGWecYY888ohNnz7dcnJy7JNPPimS14fCxfxX8pXo29uOHDnS1q9fb1deeaVlZmbG/u2CCy6wF154Ie/sNVRqaqq99957dvbZZ9vZZ59to0aNkncsuOeee+y8886zxo0b24UXXmjlypWzadOm2cyZM+2hhx7a7/Z37dplV155pd11112Wk5Nj9957r11//fVWrlw5S01NtWuvvdZuueUWq1GjhjVu3NgeeeQR27Ztm1155ZVmZnbdddfZE088YTfccINdf/31lp2dbffee6/dfPPNeRNq06ZNbfLkyZaTk2NpaWlWo0aNA578oGgtWrTI/vWvf9n5559vWVlZlp2dbfPnz7fLLrss0eepU6eOValSxUaNGmUNGza0ypUrW2pqqn3wwQf2+9//Pta3adOm9vHHH1uPHj2sUqVKVr16dbvlllvs5z//uXXs2NHOOOMMe/fdd23YsGE2ZsyY2GPffPNN69y5s/Xs2dNeffVV+/LLL+Wliyg5GIMoiXbu3GkrVqyI3d72j3/8o5133nkHHJv5HY8HDx5se/futa5du1rVqlXtP//5j1WpUsWaNGliI0eOtO+++85OOukkq169ur3//vu2b98+a926dRG+chQl5r8SprhDIgdy3nnnxUIxPzV58uTIzKJp06blhcHXr1+f9+/ffvttZGbRokWLoiiK33UqiqJo8+bNUffu3aOTTjop2rJliwwYjRo1KurevXtUpUqVKCMjI+rSpUvenSyUH8Nu99xzT1SzZs0oLS0tuuqqq6IdO3bk9dm+fXt0ww03RLVq1YoqVaoU9ejRI/ryyy9j2xk3blx0/PHHRxUrVozq1asX3XbbbdHu3bvz/j07Ozs64YQToipVqsReIwpfSBBtxYoVUb9+/aL69etHFStWjJo0aRLdc889eWF+dyxGURQ9/vjjUZMmTfLaKoj2+OOPe8/13HPPRY0aNYrKlSsXnXzyydGYMWOihg0bev1GjBgRtWzZMipfvnzseZ555pmoefPmUYUKFaJWrVpFL7/8cuxxZhY9/fTTUa9evaJKlSpFTZs2jYYMGXLA14/CxRhkDJZGAwcOjMwsMrOofPnyUe3ataMzzjgjevHFF/PGZRTp0GwUHfh4PHz48Khr165RRkZGlJqaGp1wwgl5N4cZP358dPLJJ0fVq1ePqlSpEnXo0IHxU4ox/5W++S8livaziASAUufGG2+0PXv22DPPPJPI9lJSUmz48OHWr1+/RLaHso8xCOBwxfznK9GXTgE4OO3a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1axZ08477zxbuHDhfvdr7969dsUVV1ibNm1syZIlZmb2zjvvWKdOnaxy5crWvHlzu//++2P/xTslJcWeffZZO//88y01NdUefvjhJN8qFDLmQJQUIfPiY489Zu3bt7fU1FRr1KiRXXfddXljysxs8ODBVq1aNRs9erS1bdvW0tLSrHfv3pabm5vXZ+/evXbzzTfnzYu33nqrt1rxwc6dKP0YfyVHmTrRcFWpUsV27dp1yNvZunWrnXXWWVa9enWbMmWKvfnmmzZmzBi7/vrrzczs9NNPt2rVqtnQoUPzHrN3714bMmSIXXLJJWZmtnDhQuvdu7ddcMEFNn36dBsyZIh9/vnnedv40V//+lc75phj7Ntvv7W77777kPcdhS8tLc3S0tLs7bfftp07d+633/33328///nPbfr06XbOOefYJZdcYuvWrTOzHybF0047zTp27GhfffWVjRo1ylauXGk///nP8x6/detWu/nmm+2rr76yjz/+2MqVK2f9+/e3ffv2ec+1c+dOu+iii2zq1Kk2fvx4a9y4sY0fP94uu+wyGzRokM2ePdv++c9/2uDBg72Tifvuu8/69+9vM2bMsCuuuCKhdwnFgTkQxSVkXixXrpw99dRTNmvWLPv3v/9tn3zyid16662xPtu2bbO//vWv9sorr9hnn31mS5Yssd///vd5//7oo4/a4MGD7cUXX7TPP//c1q1bZ8OHD49t42DmTpQNjL8SJCojBg4cGPXt2zeKoijat29f9NFHH0WVKlWKfv/730cnn3xyNGjQoFj/vn37RgMHDsxrN2nSJHr88cfz2mYWDR8+PIqiKPrXv/4VVa9ePdqyZUvev7/33ntRuXLlohUrVkRRFEWDBg2KTjvttLx/Hz16dFSpUqVo/fr1URRF0ZVXXhldffXVsX0YP358VK5cuWj79u15+9CvX79DeBdQXN56662oevXqUeXKlaPu3btHd9xxRzRt2rS8fzez6K677sprb9myJTKz6IMPPoiiKIoefPDB6Mwzz4xtc+nSpZGZRdnZ2fI5V69eHZlZNGPGjCiKomjRokWRmUXjx4+PTj/99Khnz57Rhg0b8vqffvrp0R/+8IfYNl555ZWofv36sf286aabCvguoDgxB6KkyW9edL355ptRzZo189ovvfRSZGbRggUL8mpPP/10VLdu3bx2/fr1o0ceeSSvvXv37qhhw4Z53wVlf3Pnt99+W4BXiZKK8VcylKm/aIwcOdLS0tKscuXKdvbZZ9vFF19s99133yFvd86cOXbMMcdYampqXq1Hjx62b98+y87ONjOzSy65xMaNG2fLly83M7NXX33Vzj33XKtWrZqZmU2bNs0GDx6cd5adlpZmZ511lu3bt88WLVqUt93OnTsf8v6i6F1wwQW2fPlyGzFihPXu3dvGjRtnnTp1ssGDB+f16dChQ97/T01NtYyMDFu1apWZ/TA+xo4dGxsfbdq0MTPL+xPr/PnzbcCAAda8eXPLyMiwpk2bmpnlXRb1owEDBtjWrVvtww8/tMzMzLz6tGnT7IEHHog9x1VXXWW5ubm2bdu2vH6MwdKLORAlSX7z4pgxY+z000+3Bg0aWHp6ul166aW2du3a2HxUtWpVa9GiRV67fv36efPmxo0bLTc317p27Zr37+XLl/fGUOjcibKF8VcylKkTjVNPPdWmTp1q8+fPt+3bt9u///1vS01NtXLlynnXzO3evTvR5z7++OOtRYsW9sYbb9j27dtt+PDheZcMmJlt2bLFfv3rX9vUqVPz/jdt2jSbP39+bBD/9ECO0qVy5crWq1cvu/vuu23ixIl2+eWX27333pv3726oOiUlJe9Pp1u2bLE+ffrExsePY/mkk04yM7M+ffrYunXr7LnnnrPJkyfb5MmTzcy8S2POOeccmz59uk2aNClW37Jli91///2x7c+YMcPmz59vlStXzuvHGCy9mANR0uxvXszJybHzzjvPOnToYEOHDrWvv/7ann76aTOLz2lq3nTHcn5C506UPYy/4lem7jqVmppqLVu29Oq1a9f2wjszZ860U089NWi7bdu2tcGDB9vWrVvzDoITJkywcuXKWevWrfP6XXLJJfbqq69aw4YNrVy5cnbuuefm/VunTp1s9uzZcv9QNh111FHB6xB06tTJhg4dak2bNrXy5f2v5dq1ay07O9uee+45O/HEE83sh2Ctcu2111q7du3s/PPPt/fee89OPvnkvOfIzs5mDJZhzIEo6X6cF7/++mvbt2+fPfroo1au3A//zfO///3vQW0rMzPT6tevb5MnT877DzJ79uyxr7/+2jp16mRmBzd3ouxj/BW9MvUXjf057bTT7L333rP33nvP5s6da9dee613d5QDueSSS6xy5co2cOBAmzlzpo0dO9ZuuOEGu/TSS61u3bqxft988409/PDDduGFF1qlSpXy/u22226ziRMn2vXXX5/3XxzfeecdLwiJ0mft2rV22mmn2X/+8x+bPn26LVq0yN5880175JFHrG/fvkHb+M1vfmPr1q2zAQMG2JQpU2zhwoU2evRo+5//+R/bu3evVa9e3WrWrGn/+te/bMGCBfbJJ5/YzTffvN/t3XDDDfbQQw/Zeeedlzep3XPPPfbyyy/b/fffb7NmzbI5c+bYG2+8YXfddVci7wNKLuZAFLX85sWWLVva7t277W9/+5t999139sorr9g//vGPg36eQYMG2Z/+9Cd7++23be7cuXbdddfFxvbBzp0oGxh/JUeZ+ovG/lxxxRU2bdo0u+yyy6x8+fL229/+Nvi/5Jn9cI3e6NGjbdCgQXb88cdb1apV7YILLrDHHnss1q9ly5bWpUsX+/LLL2Mr7Jr9cH3+p59+av/3f/9nJ554okVRZC1atLCLL744iZeIYpSWlmZdu3a1xx9/3BYuXGi7d++2Ro0a2VVXXWV33nln0DaysrJswoQJdtttt9mZZ55pO3futCZNmljv3r2tXLlylpKSYm+88YbdeOON1q5dO2vdurU99dRTdsopp+x3mzfddJPt27fPzjnnHBs1apSdddZZNnLkSHvggQfsz3/+s1WoUMHatGlj//u//5vQO4GSijkQRS2/ebFKlSr22GOP2Z///Ge744477KSTTrI//vGPdtlllx3U8/zud7+z3NxcGzhwoJUrV86uuOIK69+/v23cuNHMfriz0MHOnSj9GH8lR0p0sBebAQAAAEA+DotLpwAAAAAULU40AAAAACSOEw0AAAAAieNEAwAAAEDiONEAAAAAkDhONAAAAAAkjhMNAAAAAIkLWrBv3759tnz5cktPT7eUlJTC3ieUAlEU2ebNmy0rK8vKlSvc81XGH1xFOf7MGIOIY/yhuHEMRnE6mPEXdKKxfPlya9SoUSI7h7Jl6dKl1rBhw0J9DsYf9qcoxp8ZYxAa4w/FjWMwilPI+As60UhPT8/bYEZGxqHvWQFt3brVqz300ENebfLkybH2gAEDvD5XXXVVcjtWQMOHD/dqL7/8slfr1auXV7vuuusKZZ9Cbdq0yRo1apQ3NgpTSRl/JcH8+fO92pgxY7xa9erVvVqlSpVi7a5du3p9srKyDmHv8hdFkVcryH8hK8rxZ8YYRBzjD8WNYzCK08GMv6ATjR9/CGRkZBTrIDviiCO8mvvjycysfPn4y6pSpYrXpyR8WapWrerV3H03M6tcubJXKwn7b1awH4kFfY7iHn8lQVpamldT40ONebefmiAK+/1N6kQjiccW5HkYg/gpxh+KG8dgFKeQ8UcYHAAAAEDiONEAAAAAkLigS6eKwzXXXOPVPv30U6+2b98+r1a3bt1Y++677/b6PPXUU15NhZ2OPPLIWDszM9Prs27dOq82ceJEr7Zr165Ye9OmTV6f+vXre7Vnn33Wq7377rux9nPPPef1ad68uVdDyVDQS4iuvfZar/bll196tT179ni1nTt35rv9//3f//Vq06ZN82rbtm2LtU866SSvz6OPPurV1CVde/fujbXVJZIAAKD04S8aAAAAABLHiQYAAACAxHGiAQAAACBxJSaj8cknn8TaixYt8vp07NjRq6mcg5vbOOaYY7w+q1ev9moLFy70au7aHZ07d/b6TJ8+3aup29TWqlUr1lavZ9WqVV6tWbNmXm3Dhg2x9u9+9zuvj1qnAyVDQTMaK1as8GpqzQw3D2RmVrFixVjbHUNmZv/5z3+82o4dO7xahQoVYu1Zs2Z5fdR3QGWj3H1VOQ4AAFD68BcNAAAAAInjRAMAAABA4jjRAAAAAJA4TjQAAAAAJK7EhME/+uijWLtp06ZeH7XgmBtKNTPbvXt3rO2GsM10UFUFdN3FxFToVYVX09LSvFp6enqs/f3333t9qlatGrRfDRs2jLVVKP7zzz/3aj179vRqKHpqocly5fzzfjcovWTJEq9PamqqV1ML9rk3NlBjVAXL1Y0Z3GC5GqO//e1vvZqiXjcAACj9OMIDAAAASBwnGgAAAAASx4kGAAAAgMRxogEAAAAgcSUmDL58+fJYOyMjw+sTGgZ3A9zqcW6Y1UyHY9UKy64jjjjCq6lw9rZt22JtFfxW+6DCsu5rVKtKEwYvGVRQWoXBlU8++STWdgPdZv5NBkK3r8a22r76/rg3XOjQoUPQttTK5vXq1Yu1Q4PyAACgZOPoDQAAACBxnGgAAAAASBwnGgAAAAASx4kGAAAAgMQVSxhchT3d8HRmZqbXR9V27NiR7/O5wVUzP0xtZrZlyxav5q6wrELkavvqNbrbUn3UtipXruzVXCoMPm/evHwfh8KnPhs1jpQpU6bE2m5w2sysWrVqXi07Ozvf/VA3I1i9enXQfrk3a+jbt6/X58MPP/Rqxx13nFdzX5MKzwMAgNKHv2gAAAAASBwnGgAAAAASx4kGAAAAgMQVS0Zj0aJFXs3NK2zfvt3roxbxq169uldzcw6bN2/2+pQv7790tYCZe724yoSoa8rVQoJuRkM9Tl3PrxYrU9fXu77//vt8+6DwhX7OytixY/PtozIavXr18mrfffddvvugMhrHHnusV5s6dWqsrb47F1xwgVdr0qSJV3OpBTBRsuXk5Hi1ZcuWeTUWDAWAwwt/0QAAAACQOE40AAAAACSOEw0AAAAAieNEAwAAAEDiiiUMnpub69UqVaoUa6sAtArVqnCpuxhfenp60LbUgn1uqFvtlwp+q4X3qlSpEmur0KtayK1+/fpebevWrbG22veaNWt6NRX2rV27tldDctTikOpmBIob4N62bZvX54svvvBqNWrU8GrumFcLYJ5yyileTYV6BwwYEGv/4Q9/8PoohxKMR8nw5ptverW7777bq/Xu3duruTcuaNeuXWL7dSj+85//xNqtWrXy+nTp0qWodgcAygz+ogEAAAAgcZxoAAAAAEgcJxoAAAAAEseJBgAAAIDEFUsYfO3atV7NDTxv3LjR6/PZZ595tUsuucSrZWVlxdoqfL5z506v5oa1zXQ426WCvepx7srg6nF16tTxairs64bS27Zt6/XZtGmTV5s7d65XIwxeuEJXuh4/frxXW7VqVaytwrPq+7R+/XqvVr169Vhb3RigXr16Xm3BggVeTY03lFz79u3zaurGFt9//71Xu/HGG/Pt07x5c682ffp0r3b11VfH2hMnTvR3NpB7A4wXX3zR67NmzRqvtn37dq+WlpYWa7vHEBwc96YPh3LDh6eeeirW7tSpk9cn9LjpHus6dOjg9WnQoMHB7uIh++Mf/xhrH3300V6f888/v6h2B0gUf9EAAAAAkDhONAAAAAAkjhMNAAAAAInjRAMAAABA4oolDK5CqJs3b461x44dG/S4r7/+2quddNJJsbYKJbor1JrpALcbolSrgO/atcurucFvM7MdO3bE2u7q3mZ6pfOqVat6tcmTJx9w22ZmDRs29GrTpk3zaieeeKJXQ3JCg5Du6sRmfqhSjSu1Ary6sYE7dtW21OOUiy66KNa++eabvT6PPfaYV1PvRZLBUWhqRXZl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13irjMbh5q233vJq//M//+PV1OelrnN3qeu2Z82a5dWOO+64WHv69OlenxYtWni1mTNnejV3X9U15+p6/+HDh3s1lclwqbEWQuUqsrKygh7rjvnSvKikyhy0bt06qIaD444TlQkBABQv/qIBAAAAIHGcaAAAAABIHCcaAAAAABLHiQYAAACAxJWYMHjI4nKLFi3yaioc69qyZYtXa968uVdTwXKXCpa7i1CZ6cXj3P3Yvn2718ddoM1MB8TV4m6usr5gX25ubqx9yy23eH3cGwOY6aB+CBWUVmNm0qRJsfYJJ5zg9VGLsan9chch27p1q9enf//+Xq1fv35eLUToooduEFeFoKtVqxa0rbI+TgEAOFzxFw0AAAAAieNEAwAAAEDiONEAAAAAkDhONAAAAAAkrsSEwUOoFYMrV67s1dyQtQpYqxD5rl27vJobvlWrkzdr1ixoWy4VLlavcffu3V5NrcTsUiHysmTEiBGxtvps6tWr59VUoNr9LNRK4er9VCFoN9w8ZcoUr0/Dhg29WufOnb3aN998E2vn5OR4fYYNG+bVFDe4rr4XqampQdsKGd9169YN2hYAACib+IsGAAAAgMRxogEAAAAgcZxoAAAAAEgcJxoAAAAAEleqwuBq1WIVnnaDqnXq1PH6qBCvCse621LPV6NGDa+2bds2r+YGbdWKyCEhbzMdgnep11iWXHbZZbH2f//7X6/PnDlzvJpaKd5931XwW3326j2uUqVKvttauHChV3NXATcz27BhQ6w9duxYr08otUq6S90kIWRbe/bs8fqErsDuBvFD9hMAAJR8ZfuXKAAAAIBiwYkGAAAAgMRxogEAAAAgcaXqYuh58+Z5NfcadjP/OvP169d7fVRNLUK2du3aWHvTpk1enwULFni1lStXerWpU6fG2t26dfP6qPyAynKovMrhxs1CfPzxx16fZcuWebXBgwd7tffeey/WdhfKMwtbpO5QqEUC33///Vj7lFNOKdR9OPLII4P6ud+75s2be32OPvrooG2p7AsAACj9+IsGAAAAgMRxogEAAAAgcZxoAAAAAEgcJxoAAAAAEldiwuAhi8t17tzZq61Zs8aruQv0qYX4ateu7dVUKHX58uUHbJuZHXfccV5t586dXm3x4sWxtlqcr2rVql7NDZGbmdWrV8+rucr6gn0hGjZs6NXuuuuuoJpL3Yzgu+++82rujQbUgo4qPB0axC5Mt9xyi1c7/vjjvZr7HVOvsWbNmkHPyQJ9AACUTfwSBQAAAJA4TjQAAAAAJI4TDQAAAACJC7o4+scF49RidUnZu3dvrK3yEmpBM5WFcPvt27fP67Nt2zavpp5z+/bt+T6f2lbIfqmMhspVqIXi3M9CXefuvqdmyS2O9uPzq8UEk1YU4y+EWkxx69atXs0dDyojpLZV2K8v5DumqNfo7r+7SKaZzhslpSjH30+fp7jHIEoGxh+K2+F4DEbJcTDjL+hEY/PmzWZm1qhRo0PYLSTp1VdfLe5dMLMfxkZmZmahP4cZ4w++ohh/Pz6PGWMQcYw/FDeOwShOIeMvJQo4Hdm3b58tX77c0tPT5X+Fx+EniiLbvHmzZWVlFfrdrRh/cBXl+DNjDCKO8YfixjEYxelgxl/QiQYAAAAAHAzC4AAAAAASx4kGAAAAgMRxogEAAAAgcYflicZ9991nxx577AH7nHLKKXbTTTcVyf6g7MtvzA0ePNiqVat2SM9x+eWXW79+/Q5pG8ChOthxmJOTYykpKTZ16tRC2yccXhiDKA6MI61UnGikpKQc8H/33Xdf4s85bNgwe/DBBw/YJ79Bdf/999uvfvUrM/vhNbz99tsJ7yWKyqRJk+yII46wc889t7h3pdhxEl46rF692q699lpr3LixVapUyerVq2dnnXWWTZgwobh3DYcJxiCKCmOt5ApaR6O45ebm5v3/IUOG2D333GPZ2dl5tbS0tMSfs0aNGgf8d7WInuudd96x22+/PaldQjF64YUX7IYbbrAXXnjBli9fbllZWcW9S8ABXXDBBbZr1y7797//bc2bN7eVK1faxx9/bGvXri3uXcNhgjGIolJWx9ru3bvlgrilSan4i0a9evXy/peZmWkpKSmxmjrRGDdunHXp0sVSU1OtWrVq1qNHD1u8eHGszyuvvGJNmza1zMxM+8UvfpG3KI2Z/19tmzZtag8++KBddtlllpGRYVdffbU1a9bMzMw6duxoKSkpdsopp+T1X7p0qc2aNct69+5tTZs2NTOz/v37W0pKSl7bzOzZZ5+1Fi1aWMWKFa1169b2yiuvxPYxJSXFnn32WTv77LOtSpUq1rx5c3vrrbcK+E6iILZs2WJDhgyxa6+91s4991wbPHhw7N/HjRtnKSkp9vHHH1vnzp2tatWq1r1799jJsGvhwoXWvHlzu/766/e7suY777xjnTp1ssqVK1vz5s3t/vvvtz179uS7v/fff7/Vrl3bMjIy7JprromdFO/cudNuvPFGq1OnjlWuXNl69uxpU6ZMiT3+008/tS5dulilSpWsfv36dvvtt+c97+WXX26ffvqpPfnkk3l/UczJycl3n1C0NmzYYOPHj7c///nPduqpp1qTJk2sS5cudscdd9j5559vZmaPPfaYtW/f3lJTU61Ro0Z23XXXxVZ8//FyvtGjR1vbtm0tLS3NevfuHfsPP3v37rWbb77ZqlWrZjVr1rRbb73VG8+jRo2ynj175vU577zzbOHChUXzRqDYMAZRVELGWkpKij3//PPWv39/q1q1qh155JE2YsSI2HZmzpxpZ599tqWlpVndunXt0ksvtTVr1uT9+8GOo71799oVV1xhbdq0sSVLlphZ/sf1H3/znX/++ZaammoPP/xwkm9V8YhKmZdeeinKzMw8YJ/du3dHmZmZ0e9///towYIF0ezZs6PBgwdHixcvjqIoiu69994oLS0t+tnPfhbNmDEj+uyzz6J69epFd955Z942Tj755GjQoEF57SZNmkQZGRnRX//612jBggXRggULoi+//DIys2jMmDFRbm5utHbt2rz+f//736MzzzwziqIoWrVqVWRm0UsvvRTl5uZGq1atiqIoioYNGxZVqFAhevrpp6Ps7Ozo0UcfjY444ojok08+yduOmUU1a9aMnnvuuSg7Ozu66667oiOOOCKaPXv2ob6VCPTCCy9EnTt3jqIoit59992oRYsW0b59+/L+fezYsZGZRV27do3GjRsXzZo1KzrxxBOj7t275/W59957o2OOOSaKoiiaNm1aVK9evej//u//8v7dHdefffZZlJGREQ0ePDhauHBh9OGHH0ZNmzaN7rvvvv3u58CBA6O0tLTo4osvjmbOnBmNHDkyql27dmxc33jjjVFWVlb0/vvvR7NmzYoGDhwYVa9ePW/sLlu2LKpatWp03XXXRXPmzImGDx8e1apVK7r33nujKIqiDRs2RN26dYuuuuqqKDc3N8rNzY327NlT4PcWhWP37t1RWlpadNNNN0U7duyQfR5//PHok08+iRYtWhR9/PHHUevWraNrr702799feumlqEKFCtEZZ5wRTZkyJfr666+jtm3bRr/85S/z+vz5z3+OqlevHg0dOjSaPXt2dOWVV0bp6elR37598/q89dZb0dChQ6P58+dH3377bdSnT5+offv20d69e6MoiqJFixZFZhZ9++23hfJeoHgwBlFUQsaamUUNGzaMXnvttWj+/PnRjTfeGKWlpeUd+9avXx/Vrl07uuOOO6I5c+ZE33zzTdSrV6/o1FNPzdvGwYyjHTt2RP379486duyY95sv5LhuZlGdOnWiF198MVq4cGHe79bSrEyeaKxduzYys2jcuHHy3++9996oatWq0aZNm/Jqt9xyS9S1a9e8tjrR6NevX2w7B5qcevXqFf3973/Pa5tZNHz48Fif7t27R1dddVWsdtFFF0XnnHNO7HHXXHNNrE/Xrl1jkzEKV/fu3aMnnngiiqIfJrRatWpFY8eOzfv3H080xowZk1d77733IjOLtm/fHkXR/zvRmDBhQlS9evXor3/9a+w53HF9+umnR3/4wx9ifV555ZWofv36+93PgQMHRjVq1Ii2bt2aV3v22WejtLS0aO/evdGWLVuiChUqRK+++mrev+/atSvKysqKHnnkkSiKoujOO++MWrduHTuRevrpp/O2EUX+dwMl01tvvRVVr149qly5ctS9e/fojjvuiKZNm7bf/m+++WZUs2bNvPZLL70UmVm0YMGCvNrTTz8d1a1bN69dv379vLETRT98Pxo2bBj7kedavXp1ZGbRjBkzoijiR15ZxhhEUclvrJlZdNddd+W1t2zZEplZ9MEHH0RRFEUPPvhg3n8c/tHSpUsjM4uys7Plc+5vHI0fPz46/fTTo549e0YbNmzI6x9yXDez6Kabbirgu1AylYpLpw5kyZIllpaWlve/P/zhD1ajRg27/PLL7ayzzrI+ffrYk08+GftTq9kPl0Klp6fntevXr2+rVq064HN17tw5aJ82bdpkn376ad6f7PZnzpw51qNHj1itR48eNmfOnFitW7duXtvtg8KRnZ1tX375pQ0YMMDMzMqXL28XX3yxvfDCC17fDh065P3/+vXrm5nFxtSSJUusV69eds8999jvfve7Az7vtGnT7IEHHoiN7auuuspyc3Nt27Zt+33cMcccY1WrVs1rd+vWzbZs2WJLly61hQsX2u7du2NjrkKFCtalS5e88TRnzhzr1q2bpaSk5PXp0aOHbdmyxZYtW3bAfUbJcsEFF9jy5cttxIgR1rt3bxs3bpx16tQp79K/MWPG2Omnn24NGjSw9PR0u/TSS23t2rWx8VW1alVr0aJFXvun8+TGjRstNzfXunbtmvfv5cuX9+bJ+fPn24ABA6x58+aWkZGRd+noj5cSoOxiDKKo5DfWzOLH6NTUVMvIyMgbS9OmTbOxY8fGjrlt2rQxM8u7PCp0HA0YMMC2bt1qH374oWVmZubVQ4/rob81S4tSf6KRlZVlU6dOzfvfNddcY2ZmL730kk2aNMm6d+9uQ4YMsVatWtkXX3yR9zg3XJOSkmL79u074HOlpqYG7dMHH3xgRx11lDVq1OggXw1KmhdeeMH27NljWVlZVr58eStfvrw9++yzNnToUNu4cWOs70/H1I8/1H86pmrXrm1dunSx119/3TZt2nTA592yZYvdf//9sbE9Y8YMmz9/vlWuXDnBV4iyrHLlytarVy+7++67beLEiXb55Zfbvffeazk5OXbeeedZhw4dbOjQofb111/b008/bWbxG12oeTLaT6Zof/r06WPr1q2z5557ziZPnmyTJ0/2ngdlF2MQRWV/Y+1HB/rdt2XLFuvTp0/smDt16lSbP3++nXTSSWYWPo7OOeccmz59uk2aNClWDz2uh/7WLC1K/YlG+fLlrWXLlnn/++ndojp27Gh33HGHTZw40dq1a2evvfZaos9dsWJFM/sh8PNT77zzjvXt2zdWq1Chgtevbdu23q3XJkyYYEcddVSs9tMTpB/bbdu2PaR9R/727NljL7/8sj366KOxiWHatGmWlZVlr7/++kFtr0qVKjZy5EirXLmynXXWWbGbD7g6depk2dnZsbH94//Kldv/13batGm2ffv2vPYXX3xhaWlp1qhRo7ybDvx0zO3evdumTJmSN+batm1rkyZNih3IJ0yYYOnp6dawYUMz+2Hcu2MZpcNRRx1lW7duta+//tr27dtnjz76qJ1wwgnWqlUrW758+UFtKzMz0+rXr593sDX74Tvz9ddf57XXrl1r2dnZdtddd9npp59ubdu2tfXr1yf2elD6MAZRVH4cayE6depks2bNsqZNm3rH3NTU1IMaR9dee6396U9/svPPP98+/fTT2HMU5Lhe2pWK29serEWLFtm//vUvO//88y0rK8uys7Nt/vz5dtlllyX6PHXq1LEqVarYqFGjrGHDhla5cmVLTU21Dz74wH7/+9/H+jZt2tQ+/vhj69Gjh1WqVMmqV69ut9xyi/385z+3jh072hlnnGHvvvuuDRs2zMaMGRN77JtvvmmdO3e2nj172quvvmpffvmlvHQHyRo5cqStX7/errzyytifP81++DPtCy+8kPcXtFCpqan23nvv2dlnn21nn322jRo1St417Z577rHzzjvPGjdubBdeeKGVK1fOpk2bZjNnzrSHHnpov9vftWuXXXnllXbXXXdZTk6O3XvvvXb99ddbuXLlLDU11a699lq75ZZbrEaNGta4cWN75JFHbNu2bXbllVeamdl1111nTzzxhN1www12/fXXW3Z2tt1777128803502ETZs2tcmTJ1tOTo6lpaVZjRo1yvQkWRqtXbvWLrroIrviiiusQ4cOlp6ebl999ZU98sgj1rdvX2vZsqXt3r3b/va3v1mfPn1swoQJ9o9//OOgn2fQoEH2pz/9yY488khr06aNPfbYY7Zhw4a8f69evbrVrFnT/vWvf1n9+vVtyZIl3PL7MMEYRFHJb6yF+M1vfmPPPfecDRgwwG699VarUaOGLViwwN544w17/vnnD3oc3XDDDbZ3714777zz7IMPPrCePXsW+Lhe6hVzRuSghYTBV6xYEfXr1y+qX79+VLFixahJkybRPffckxdm/ekdgH70+OOPR02aNMlrqzD4448/7j3Xc889FzVq1CgqV65cdPLJJ0djxoyJGjZs6PUbMWJE1LJly6h8+fKx53nmmWei5s2bRxUqVIhatWoVvfzyy7HHmVn09NNPR7169YoqVaoUNW3aNBoyZMgBXz+Scd5558WC+T81efLkyMyiadOm5YXB169fn/fv3377bWRm0aJFi6Io8sfc5s2bo+7du0cnnXRStGXLFjmuR40aFXXv3j2qUqVKlJGREXXp0iX617/+td/9HThwYNS3b9/onnvuiWrWrBmlpaVFV111VewuHNu3b49uuOGGqFatWlGlSpWiHj16RF9++WVsO+PGjYuOP/74qGLFilG9evWi2267Ldq9e3fev2dnZ0cnnHBCVKVKldhrRMmxY8eO6Pbbb486deoUZWZmRlWrVo1at24d3XXXXdG2bduiKIqixx57LKpfv35UpUqV6Kyzzopefvnl2DhWY3L48OHRTw8bu3fvjgYNGhRlZGRE1apVi26++ebosssuiwVxP/roo6ht27ZRpUqVog4dOkTjxo2L3RyD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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "markdown", + "id": "989f7dd0", + "metadata": { + "id": "989f7dd0" + }, + "source": [ + "Reflection: Does the data look as expected? How is the quality of the images? Are there any issues with the dataset that you notice?\n", + "\n", + "**Your answer here**\n", + "The images are not clear but for the most part the type of image is distinguishable and corretly tagged. For example the 2 trousers are clearly distinguishable while the bag is less so. This issue with lack of clarity could potentially make it challenging for the model to correctly identify images and could lead to misclassification.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "c9e8ad60", + "metadata": { + "id": "c9e8ad60" + }, + "source": [ + "# 2. Baseline Model\n", + "\n", + "In this section, you will create a linear regression model as a baseline. This model will not use any convolutional layers, but it will help you understand the performance of a simple model on this dataset.\n", + "You should:\n", + "- [ ] Create a simple linear regression model using Keras.\n", + "- [ ] Compile the model with an appropriate loss function and optimizer.\n", + "- [ ] Train the model on the training set and evaluate it on the test set.\n", + "\n", + "A linear regression model can be created using the `Sequential` API in Keras. Using a single `Dense` layer with no activation function is equivalent to a simple linear regression model. Make sure that the number of units in the output layer matches the number of classes in the dataset.\n", + "\n", + "Note that for this step, we will need to use `Flatten` to convert the 2D images into 1D vectors before passing them to the model. Put a `Flatten()` layer as the first layer in your model so that the 2D image data can be flattened into 1D vectors." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "8563a7aa", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "8563a7aa", + "outputId": "13c59fa3-3169-4f25-8aa6-9af1ebd25f1e" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.12/dist-packages/keras/src/layers/reshaping/flatten.py:37: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", + " super().__init__(**kwargs)\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.6574 - loss: 0.0754 - val_accuracy: 0.7803 - val_loss: 0.0466\n", + "Epoch 2/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8040 - loss: 0.0422 - val_accuracy: 0.7839 - val_loss: 0.0435\n", + "Epoch 3/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8146 - loss: 0.0401 - val_accuracy: 0.8143 - val_loss: 0.0388\n", + "Epoch 4/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8133 - loss: 0.0397 - val_accuracy: 0.8153 - val_loss: 0.0388\n", + "Epoch 5/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8124 - loss: 0.0393 - val_accuracy: 0.8097 - val_loss: 0.0401\n", + "Epoch 6/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.8175 - loss: 0.0387 - val_accuracy: 0.7937 - val_loss: 0.0409\n", + "Epoch 7/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8148 - loss: 0.0388 - val_accuracy: 0.8038 - val_loss: 0.0402\n", + "Epoch 8/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.8175 - loss: 0.0385 - val_accuracy: 0.8048 - val_loss: 0.0399\n", + "Epoch 9/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.8166 - loss: 0.0389 - val_accuracy: 0.8129 - val_loss: 0.0392\n", + "Epoch 10/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m3s\u001b[0m 2ms/step - accuracy: 0.8175 - loss: 0.0391 - val_accuracy: 0.8047 - val_loss: 0.0421\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - accuracy: 0.8008 - loss: 0.0428\n", + "Test Loss: 0.0428\n", + "Test Accuracy: 0.7977\n" + ] + } + ], + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Dense, Flatten\n", + "from tensorflow.keras.optimizers import Adam\n", + "\n", + "# Create a simple linear regression model\n", + "model = Sequential()\n", + "model.add(Flatten(input_shape=(28, 28))) # Flatten the 2D images to 1D vectors\n", + "model.add(Dense(10, activation='linear')) # Output layer with 10 units for 10 classes, linear activation for linear regression\n", + "\n", + "# Compile the model using `model.compile()`\n", + "model.compile(optimizer=Adam(),\n", + " loss='mean_squared_error', # Appropriate loss for linear regression\n", + " metrics=['accuracy'])\n", + "\n", + "# Train the model with `model.fit()`\n", + "history = model.fit(X_train, y_train_one_hot, epochs=10, validation_split=0.2) # Using one-hot encoded labels for training\n", + "\n", + "# Evaluate the model with `model.evaluate()`\n", + "loss, accuracy = model.evaluate(X_test, y_test_one_hot) # Using one-hot encoded labels for evaluation\n", + "print(f\"Test Loss: {loss:.4f}\")\n", + "print(f\"Test Accuracy: {accuracy:.4f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "9a07e9f7", + "metadata": { + "id": "9a07e9f7" + }, + "source": [ + "Reflection: What is the performance of the baseline model? How does it compare to what you expected? Why do you think the performance is at this level?\n", + "\n", + "**Your answer here**\n", + "The data shows a steady decrease in loss during training with a final 0.0422 test loss, which indicates that there is a better fit to the baseline model's prediction of unseen data. decrease in both training and validation loss during training, indicating that the model was learning. The final test loss was also comparable to the validation loss, which suggests that the model did not significantly overfit the training data. The model also correctly classified the training data with 78.7% accuracy. This is likely because of the image quality and the limitations of a simpler model in accurately identifying more complex visual patterns. Accuracy however is the primary metric for classification tasks. I didnt quite know what to expect." + ] + }, + { + "cell_type": "markdown", + "id": "fa107b59", + "metadata": { + "id": "fa107b59" + }, + "source": [ + "# 3. Building and Evaluating a Simple CNN Model\n", + "\n", + "In this section, you will build a simple Convolutional Neural Network (CNN) model using Keras. A convolutional neural network is a type of deep learning model that is particularly effective for image classification tasks. Unlike the basic neural networks we have built in the labs, CNNs can accept images as input without needing to flatten them into vectors.\n", + "\n", + "You should:\n", + "- [ ] Build a simple CNN model with at least one convolutional layer (to learn spatial hierarchies in images) and one fully connected layer (to make predictions).\n", + "- [ ] Compile the model with an appropriate loss function and metrics for a multi-class classification problem.\n", + "- [ ] Train the model on the training set and evaluate it on the test set.\n", + "\n", + "Convolutional layers are designed to accept inputs with three dimensions: height, width and channels (e.g., RGB for color images). For grayscale images like those in Fashion MNIST, the input shape will be (28, 28, 1).\n", + "\n", + "When you progress from the convolutional layers to the fully connected layers, you will need to flatten the output of the convolutional layers. This can be done using the `Flatten` layer in Keras, which doesn't require any parameters." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "3513cf3d", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "3513cf3d", + "outputId": "a49fe67f-55b5-44f1-d3b8-3b976cfac5ba" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.12/dist-packages/keras/src/layers/convolutional/base_conv.py:113: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", + " super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m39s\u001b[0m 25ms/step - accuracy: 0.8055 - loss: 0.5481 - val_accuracy: 0.8779 - val_loss: 0.3371\n", + "Epoch 2/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m37s\u001b[0m 25ms/step - accuracy: 0.8965 - loss: 0.2830 - val_accuracy: 0.9001 - val_loss: 0.2806\n", + "Epoch 3/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m41s\u001b[0m 25ms/step - accuracy: 0.9170 - loss: 0.2254 - val_accuracy: 0.9061 - val_loss: 0.2642\n", + "Epoch 4/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m41s\u001b[0m 25ms/step - accuracy: 0.9259 - loss: 0.1947 - val_accuracy: 0.9112 - val_loss: 0.2485\n", + "Epoch 5/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m36s\u001b[0m 24ms/step - accuracy: 0.9396 - loss: 0.1640 - val_accuracy: 0.9143 - val_loss: 0.2432\n", + "Epoch 6/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m35s\u001b[0m 24ms/step - accuracy: 0.9478 - loss: 0.1425 - val_accuracy: 0.9133 - val_loss: 0.2595\n", + "Epoch 7/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m37s\u001b[0m 25ms/step - accuracy: 0.9554 - loss: 0.1186 - val_accuracy: 0.9096 - val_loss: 0.2749\n", + "Epoch 8/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m37s\u001b[0m 24ms/step - accuracy: 0.9634 - loss: 0.0992 - val_accuracy: 0.9093 - val_loss: 0.2958\n", + "Epoch 9/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m41s\u001b[0m 25ms/step - accuracy: 0.9679 - loss: 0.0855 - val_accuracy: 0.9137 - val_loss: 0.2692\n", + "Epoch 10/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m38s\u001b[0m 25ms/step - accuracy: 0.9761 - loss: 0.0675 - val_accuracy: 0.9150 - val_loss: 0.3142\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m2s\u001b[0m 7ms/step - accuracy: 0.9130 - loss: 0.3498\n", + "Test Loss: 0.3372\n", + "Test Accuracy: 0.9133\n" + ] + } + ], + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense\n", + "from tensorflow.keras.optimizers import Adam\n", + "from tensorflow.keras.losses import categorical_crossentropy\n", + "\n", + "# Reshape the data to include the channel dimension\n", + "X_train = X_train.reshape(-1, 28, 28, 1)\n", + "X_test = X_test.reshape(-1, 28, 28, 1)\n", + "\n", + "# Create a simple CNN model\n", + "model = Sequential()\n", + "model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))\n", + "model.add(MaxPooling2D(pool_size=(2, 2)))\n", + "model.add(Flatten())\n", + "model.add(Dense(128, activation='relu'))\n", + "model.add(Dense(10, activation='softmax')) # Output layer with softmax activation for multi-class classification\n", + "\n", + "# Compile the model\n", + "model.compile(loss=categorical_crossentropy,\n", + " optimizer=Adam(),\n", + " metrics=['accuracy'])\n", + "\n", + "# Train the model\n", + "history = model.fit(X_train, y_train_one_hot, epochs=10, validation_split=0.2)\n", + "\n", + "# Evaluate the model\n", + "loss, accuracy = model.evaluate(X_test, y_test_one_hot)\n", + "print(f\"Test Loss: {loss:.4f}\")\n", + "print(f\"Test Accuracy: {accuracy:.4f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "fabe379c", + "metadata": { + "id": "fabe379c" + }, + "source": [ + "Reflection: Did the CNN model perform better than the baseline model? If so, by how much? What do you think contributed to this improvement?\n", + "\n", + "**Your answer here**\n", + "There is a a steady decrease in loss for the cnn model with a final training loss of 0.067, a test loss of 0.3234 and an accuracy of 91.3%. The cnn model performed significantly better than the linear model approximately 12% better.\n", + "\n", + "This substantial improvement is primarily attributed to the architecture of the CNN. Unlike the linear model which flattens the image data, the convolutional layers in the CNN are able to learn spatial hierarchies and important features within the images, such as edges, shapes, and textures. The pooling layers help to reduce the spatial dimensions and make the model more robust to variations in the image.\n", + "\n", + "The gap between training accuracy of 97.6% and test accuracy of 91.3% suggests there might be some degree of overfitting, although the model still generalizes much better than the baseline. Further experimentation with regularization techniques could help mitigate this." + ] + }, + { + "cell_type": "markdown", + "id": "1a5e2463", + "metadata": { + "id": "1a5e2463" + }, + "source": [ + "# 4. Designing and Running Controlled Experiments\n", + "\n", + "In this section, you will design and run controlled experiments to improve the model's performance. You will focus on one hyperparameter and one regularization technique.\n", + "You should:\n", + "- [ ] Choose one hyperparameter to experiment with (e.g., number of filters, kernel size, number of layers, etc.) and one regularization technique (e.g., dropout, L2 regularization). For your hyperparameter, you should choose at least three different values to test (but there is no upper limit). For your regularization technique, simply test the presence or absence of the technique.\n", + "- [ ] Run experiments by modifying the model architecture or hyperparameters, and evaluate the performance of each model on the test set.\n", + "- [ ] Record the results of your experiments, including the test accuracy and any other relevant metrics.\n", + "- [ ] Visualize the results of your experiments using plots or tables to compare the performance of different models.\n", + "\n", + "The best way to run your experiments is to create a `for` loop that iterates over a range of values for the hyperparameter you are testing. For example, if you are testing different numbers of filters, you can create a loop that runs the model with 32, 64, and 128 filters. Within the loop, you can compile and train the model, then evaluate it on the test set. After each iteration, you can store the results in a list or a dictionary for later analysis.\n", + "\n", + "Note: It's critical that you re-initialize the model (by creating a new instance of the model) before each experiment. If you don't, the model will retain the weights from the previous experiment, which can lead to misleading results." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "99d6f46c", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 732 + }, + "id": "99d6f46c", + "outputId": "5e6b8169-cdc3-4aac-d38a-e4c2138138f6" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Experimenting with number of filters:\n", + "\n", + "Training with 32 filters...\n", + "Test Accuracy with 32 filters: 0.9052\n", + "\n", + "Training with 64 filters...\n", + "Test Accuracy with 64 filters: 0.9098\n", + "\n", + "Training with 128 filters...\n", + "Test Accuracy with 128 filters: 0.9108\n", + "\n", + "Hyperparameter Experiment Results (Number of Filters):\n", + "Filters: 32, Test Accuracy: 0.9052\n", + "Filters: 64, Test Accuracy: 0.9098\n", + "Filters: 128, Test Accuracy: 0.9108\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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ZGsLCQkxJBnffvutrW3t2rWGJMPHx8futZw5c6Yhydi0aZOtLSoqypBkvPjii7Y2q9VqtG/f3vD09DTOnj1rGIZhfP3114Yk44MPPrCrKSkpKUt7Zk1JSUm3fW3S0tKMwMBAo1atWsYff/xha//ss88MScbo0aOznP/27dtvO25m3+wehvG/133evHm2fbJ73X19fe3e95ly+z7M/HuoYsWKWd6bdevWzfLZBlyJZQbAHUpNTZX059exeTFy5Eilp6fneulAxYoV1bVrV82aNUsnT550+HhXrlxRQECAAgICVLlyZY0YMUJNmjTRihUrJP35tWn16tVVrVo1nTt3zvZo1aqVJGX5Or5Fixa5Xhv7+eefKzg4WJ07d7a1eXh4aNCgQbp8+bK+/PJLu/5PPfWUAgICsh2rV69etj+7u7urQYMGMgxDPXv2tLUXK1ZMVatW1W+//WbXN3PdrdVq1fnz55Wenq4GDRpk+zV6ZGSkihcvbnverFkzSbKNefbsWX311Vfq0aOH7rvvPrt9M79yNwxDH3/8sSIiImQYht3rGh4erpSUlBy/wr///vtVr149LVmyxNaWkZGhZcuWKSIiwrams1ixYrpy5cpd+bp38ODBKl68uMaOHeu0MWvUqKEmTZrYnjdq1EiS1KpVK7vXMrP9r/8dMw0cOND258zZxrS0NK1fv17Sn+9nf39//fOf/7R73cPCwlSkSJEs7+cKFSooPDz8trXv2LFDZ86cUf/+/e3WsLZv317VqlXLskbeUdOnT9e6devsHncqL+/DqKioLGuGixUrpp9//ln79++/45oAZ2CZAXCH/Pz8JEmXLl3K0/5/Dae5vfXOyJEjtXDhQsXHxzu8HtLb21uffvqppD/vbFChQgWVK1fOtn3//v3as2fPLUNk5sUsmW6+4jonR44cUZUqVbJcQFK9enXb9tyOfXNw9Pf3l7e3d5avYv39/fX777/btS1YsECTJ0/W3r17dePGjRyPd/NxMoNt5nrLzICV063Rzp49q4sXL2rWrFlZ7miR6ebX9WaRkZEaMWKEjh8/rrJly2rz5s06c+aMIiMjbX369++vjz76SO3atVPZsmXVtm1bderUSY888kiOY+eGv7+/hgwZotjYWO3atcsu4OdVdv8NJal8+fLZtt+8xtXNzU0VK1a0a7v//vsl/W/99/79+5WSkqLAwMBsa8jr+znzvZrdMoRq1arpm2++ydU4t9KwYcNbXgCWV3l5H2b3eowbN06PP/647r//ftWqVUuPPPKIunbtqjp16ji1XiC3CLPAHfLz81OZMmX0008/5XmM119/XQsXLtTEiRNzdSudihUrqkuXLg4F4Ezu7u453h7IarWqdu3amjJlSrbbbw4ad3qld05yGtvd3T1XbZLsLgh6//331b17d3Xs2FHDhg1TYGCg3N3dFRcXZ1s77OiYt2O1WiVJXbp0sV0MdLPbBYHIyEgNHz5cS5cu1ZAhQ/TRRx/J39/fLqgGBgZq9+7dWrt2rdasWaM1a9Zo3rx56tatW5aL7PIic+3s2LFjlZCQkGX7rW7cn5GRkW37rV5bZ7zmmaxWqwIDA/XBBx9ku/3mf7Tdzfezq+XlfZjd69G8eXMdPHhQn3zyib744gvNmTNHU6dOVWJiot03JkB+IcwCTtChQwfNmjVLW7dutfvaNLcqVaqkLl26aObMmbavVG9n5MiRev/9920X+jhLpUqV9P3336t169ZO/1WhkJAQ/fDDD7JarXazs3v37rVtv9uWLVumihUravny5Xbnl9f74WbODOb0j5mAgAAVLVpUGRkZub7P6M0qVKighg0basmSJRo4cKCWL1+ujh07ysvLy66fp6enIiIiFBERIavVqv79+2vmzJkaNWqUKleunKdjZ8qcnR0zZky2YShztvbixYt2t6G6ecbdWaxWq3777TfbbKwk/frrr5L+vDOB9Of7ef369WratKlTg2rme3Xfvn22JTiZ9u3bly/v5Zxk99l1xvswU4kSJRQdHa3o6GhdvnxZzZs315gxYwizcAnWzAJO8Morr8jX11e9evXS6dOns2w/ePDgbZcDjBw5Ujdu3NBbb72Vq2P+NQCfOnUqT3Vnp1OnTjp+/Lhmz56dZdsff/yhK1eu5HnsRx99VKdOnbJb+5menq63335bRYoUUYsWLfI8dm5lzvr9dZbvv//9r7Zu3Zqn8QICAtS8eXPNnTtXR48etduWeQx3d3c99dRT+vjjj7MNvWfPns3VsSIjI/Xdd99p7ty5OnfunN0SA0lZllO4ubnZZtoyb6t248YN7d27N0/rrSVpyJAhKlasmN3dAjJlXjH/1Vdf2doybxF1t7zzzju2PxuGoXfeeUceHh5q3bq1pD/fzxkZGRo/fnyWfdPT0/P8s7INGjRQYGCgEhMT7W5Zt2bNGu3Zs0ft27fP07jO4uvrm+XcnPU+vPl9VqRIEVWuXNnpvyII5BYzs4ATVKpUSYsWLbLdLuqvvwD27bff2m4/dbsxunTp4tD/+DOXJ+zbt081a9a8w7P4U9euXfXRRx/phRde0KZNm9S0aVNlZGRo7969+uijj2z34MyLPn36aObMmerevbuSk5MVGhqqZcuWacuWLUpISMjzRXSO6NChg5YvX64nnnhC7du316FDh5SYmKgaNWro8uXLeRrz3//+tx5++GE98MAD6tOnjypUqKDDhw9r9erV2r17tyQpPj5emzZtUqNGjdS7d2/VqFFD58+f186dO7V+/XqdP3/+tsfp1KmThg4dqqFDh6pEiRJZZtd69eql8+fPq1WrVipXrpyOHDmit99+W/Xq1bOtSz5+/LiqV6+uqKioHO9Veiv+/v4aPHhwtheCtW3bVvfdd5969uypYcOGyd3dXXPnzlVAQECWoO8M3t7eSkpKUlRUlBo1aqQ1a9Zo9erVGjFihG35QIsWLdS3b1/FxcVp9+7datu2rTw8PLR//34tXbpU06ZNs7tPb255eHho4sSJio6OVosWLdS5c2fbrblCQ0P10ksvOft0HRIWFqb169fbfgilQoUKatSokVPehzVq1FDLli0VFhamEiVKaMeOHVq2bJndxXhAfiLMAk7y2GOP6YcfftC//vUvffLJJ5oxY4a8vLxUp04dTZ48Wb17977tGJlLB261xvBmlStXdjgA346bm5tWrlypqVOn6j//+Y9WrFihwoULq2LFiho8eLDdV7qO8vHx0ebNm/Xaa69pwYIFSk1NVdWqVTVv3rw7upG8I7p3765Tp05p5syZWrt2rWrUqKH3339fS5cutd2w31F169bVd999p1GjRmnGjBm6du2aQkJC1KlTJ1ufoKAgbdu2TePGjdPy5cv17rvvqmTJkqpZs2aul4qUK1dODz30kLZs2aJevXpl+UnTzHXU7777ri5evKjg4GDbPWqd+atNQ4YMUUJCglJSUuzaPTw8tGLFCvXv31+jRo1ScHCwhgwZouLFiys6Otppx8/k7u6upKQk9evXT8OGDVPRokUVGxur0aNH2/VLTExUWFiYZs6cqREjRqhQoUIKDQ1Vly5d1LRp0zwfv3v37ipcuLDi4+P16quvytfXV088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EWYB3NPc3d01YcIEvf322/q///u/Oxpr48aNOnHihL766itNmTJFsbGx6tChg4oXL67//ve/euGFF9S3b98sxxk2bJhefvll7dq1S02aNFFERIR+//13SdLFixfVqlUr1a9fXzt27FBSUpJOnz6tTp062Y2xYMECeXp6asuWLUpMTMy2vmnTpmny5MmaNGmSfvjhB4WHh+uxxx7T/v37JUknT55UzZo19fLLL+vkyZMaOnToHb0eN9u+fbskad68eTp58qTt+ddff61u3bpp8ODB+uWXXzRz5kzNnz9fb775pt3+Y8aM0RNPPKEff/xRPXr00KhRo/TLL79ozZo12rNnj2bMmKFSpUo5tWYA9wADAO5RUVFRxuOPP24YhmE0btzY6NGjh2EYhrFixQrjr3/9xcbGGnXr1rXbd+rUqUZISIjdWCEhIUZGRoatrWrVqkazZs1sz9PT0w1fX1/jww8/NAzDMA4dOmRIMuLj4219bty4YZQrV86YOHGiYRiGMX78eKNt27Z2xz527Jghydi3b59hGIbRokULo379+rc93zJlyhhvvvmmXduDDz5o9O/f3/a8bt26RmxsbI7jREVFGe7u7oavr6/t8fTTT9tqGTx4sK1vSEiIMXXqVNtzScaKFSvsxmvdurUxYcIEu7aFCxcapUuXtttvyJAhdn0iIiKM6OjoHGsFgEIuTdIAkE8mTpyoVq1a3dFsZM2aNeXm9r8vtIKCglSrVi3bc3d3d5UsWVJnzpyx269Jkya2PxcqVEgNGjTQnj17JEnff/+9Nm3apCJFimQ53sGDB3X//fdLksLCwnKsLTU1VSdOnFDTpk3t2ps2barvv/8+l2f4P//4xz80Y8YM23NfX1+Hx8j0/fffa8uWLXYzsRkZGbp27ZquXr2qwoULS5IaNGhgt1+/fv301FNPaefOnWrbtq06duyohx56KM91ALg3EWYB/C00b95c4eHhGj58uLp37263zc3NTYZh2LVldwGSh4eH3XOLxZJtm9VqzXVdly9fVkREhCZOnJhlW+nSpW1/vpMwmRe+vr6qXLmyU8a6fPmyxo4dqyeffDLLNm9vb7tj/lW7du105MgRff7551q3bp1at26tAQMGaNKkSU6pC8C9gTAL4G8jPj5e9erVU9WqVe3aAwICdOrUKRmGYbtllzPvDfvdd9+pefPmkqT09HQlJydr4MCBkqQHHnhAH3/8sUJDQ1WoUN7/Svbz81OZMmW0ZcsWtWjRwta+ZcsWNWzY8M5OwAEeHh7KyMiwa3vggQe0b9++PIXjgIAARUVFKSoqSs2aNdOwYcMIswDsEGYB/G3Url1bzz//vP7973/btbds2VJnz57VW2+9paefflpJSUlas2aN/Pz8nHLc6dOnq0qVKqpevbqmTp2qCxcuqEePHpKkAQMGaPbs2ercubNeeeUVlShRQgcOHNDixYs1Z84cubu75/o4w4YNU2xsrCpVqqR69epp3rx52r17tz744AOnnEduhIaGasOGDWratKm8vLxUvHhxjR49Wh06dNB9992np59+Wm5ubvr+++/1008/6Y033rjlWKNHj1ZYWJhq1qyp69ev67PPPlP16tXz7VwAmAN3MwDwtzJu3LgsywCqV6+ud999V9OnT1fdunW1bds2p17pHx8fr/j4eNWtW1fffPONVq1aZbsqP3M2NSMjQ23btlXt2rU1ZMgQFStWzG59bm4MGjRIMTExevnll1W7dm0lJSVp1apVqlKlitPO5XYmT56sdevWqXz58qpfv74kKTw8XJ999pm++OILPfjgg2rcuLGmTp2qkJCQHMfy9PTU8OHDVadOHTVv3lzu7u5avHhxfpwGABOxGDcvFAMAAABMgplZAAAAmBZhFgAAAKZFmAUAAIBpEWYBAABgWoRZAAAAmBZhFgAAAKZFmAUAAIBpEWYBAABgWoRZAAAAmBZhFgAAAKZFmAUAAIBp/T+NuwbZXAgQcAAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ], + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense\n", + "from tensorflow.keras.optimizers import Adam\n", + "from tensorflow.keras.losses import categorical_crossentropy\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Reshape data if not already done (important if running this cell independently)\n", + "if X_train.shape[-1] != 1:\n", + " X_train = X_train.reshape(-1, 28, 28, 1)\n", + " X_test = X_test.reshape(-1, 28, 28, 1)\n", + "\n", + "# Define hyperparameters to test\n", + "filter_counts = [32, 64, 128]\n", + "results_hyperparameter = {}\n", + "\n", + "print(\"Experimenting with number of filters:\")\n", + "\n", + "for filters in filter_counts:\n", + " print(f\"\\nTraining with {filters} filters...\")\n", + "\n", + " # Re-initialize the model for each experiment\n", + " model = Sequential()\n", + " model.add(Conv2D(filters, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))\n", + " model.add(MaxPooling2D(pool_size=(2, 2)))\n", + " model.add(Flatten())\n", + " model.add(Dense(128, activation='relu'))\n", + " model.add(Dense(10, activation='softmax'))\n", + "\n", + " # Compile the model\n", + " model.compile(loss=categorical_crossentropy,\n", + " optimizer=Adam(),\n", + " metrics=['accuracy'])\n", + "\n", + " # Train the model (using fewer epochs for quicker experimentation)\n", + " history = model.fit(X_train, y_train_one_hot, epochs=5, validation_split=0.2, verbose=0) # verbose=0 to reduce output\n", + "\n", + " # Evaluate the model\n", + " loss, accuracy = model.evaluate(X_test, y_test_one_hot, verbose=0) # verbose=0 to reduce output\n", + " print(f\"Test Accuracy with {filters} filters: {accuracy:.4f}\")\n", + "\n", + " # Store the results\n", + " results_hyperparameter[filters] = accuracy\n", + "\n", + "# Print summary of hyperparameter experiments\n", + "print(\"\\nHyperparameter Experiment Results (Number of Filters):\")\n", + "for filters, accuracy in results_hyperparameter.items():\n", + " print(f\"Filters: {filters}, Test Accuracy: {accuracy:.4f}\")\n", + "\n", + "# Optional: Visualize the results\n", + "plt.figure(figsize=(8, 5))\n", + "plt.bar(list(map(str, results_hyperparameter.keys())), list(results_hyperparameter.values())) # Convert keys and values to lists\n", + "plt.xlabel(\"Number of Filters\")\n", + "plt.ylabel(\"Test Accuracy\")\n", + "plt.title(\"CNN Performance vs. Number of Filters\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "dc43ac81", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 652 + }, + "id": "dc43ac81", + "outputId": "40de629f-8242-4ef1-8274-924171a7e7f6" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Experimenting with Dropout regularization:\n", + "\n", + "Training model No Dropout...\n", + "Test Accuracy No Dropout: 0.9098\n", + "\n", + "Training model With Dropout...\n", + "Test Accuracy With Dropout: 0.8947\n", + "\n", + "Regularization Experiment Results (Dropout):\n", + "No Dropout: Test Accuracy: 0.9098\n", + "With Dropout: Test Accuracy: 0.8947\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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me428fzzz9s8/+qrr+To6KgXX3zRpvzll1+WYRjmkp10wcHBql+/vvm8XLly6tSpk7755hulpaUpLS1N//d//6fOnTurYsWKZj1fX191795d27dvN99ngbxGIAbukoeHhyTd9bZFdxNwcxqib+Xq6qqNGzdq48aN+vbbb3XmzBnt2LHD/B/R8ePH9dNPP5mhOf3x0EMPSfprDfCtKlSokO2+T58+rSpVqtiEAknmP1enB4jstP338Onp6SlXV1eVKlUqQ/nly5dtyt59913VqVNHrq6uKlmypLy8vLR+/XolJibesZ/0cJzeZnpQvN22dxcvXtSVK1f01ltvZXhd+/TpIynj63orR0dHBQcHm0Fu27Ztat68uZo1a6a0tDTt3r1bP//8s37//fd7Dnd3mm9W/vzzT02YMMFcU1qqVCl5eXnpypUrd/W6pv8sVKlSxaael5eXzR8oWfH29laVKlUyvGYtWrTQuXPn9Msvv2jHjh2yWq15/pqlz6Vq1ao29ZydnVWxYsUMP/f55erVqxn+sC9UqJDKli1rU3b69Gn5+fllqJvV7/Hfv4eS9NBDD+natWu6ePGiLl68qGvXrmV4fdLbtFqtOnPmzF3NCcgp1hADd8nDw0N+fn46fPjwXbcxduxYrVixQjNmzFDnzp3vWL9ixYp67rnn9NZbb2nUqFE56svR0VFt27bN8rjValXt2rU1a9asTI/7+/vbPL/dHen36nZtZ7YTQFa7Axi33OizcuVK9e7dW507d9Yrr7yi0qVLy9HRUREREeZa6py2eSdWq1WS9NxzzyksLCzTOnfa7qpZs2aaOnWqrl+/rm3btmns2LEqVqyYatWqpW3btpnrI+813N3tfIcOHaply5Zp2LBhCg4OlqenpywWi5599llz/rnRT040a9ZMUVFR+vPPP7V//35NmDBBtWrVUrFixbRt2zYdOXJE7u7uqlev3j31k5tzyeyGMUlKS0vL090vfv31VyUmJqpy5co25S4uLhn+gM1Pt3t9gNxAIAbuweOPP6633npLu3btUnBwcI7Pr1Spkp577jktXrw42zePjBs3TitXrtSMGTNy3N+dxvLDDz/o4YcfzvJ/PnerfPnyOnTokKxWq83/ZI8ePWoez2sff/yxKlasqLVr19rM7273S06/sn67P4i8vLxUtGhRpaWl3faPkdtp3ry5UlNT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G2rQoIG+//57vfDCC3r++ecVExOT43G2adNGdevW1dq1a23KJ02apCeffFI//vij+vbtq08//VQvvfSSXn75ZR0+fFj//ve/1adPH5s5StL48eMVGhqqH374QT169NCzzz6rI0eOSJKSk5MVEhKi4sWLa9++fVqzZo02bdqkIUOGZHu8a9euVdmyZTVlyhTzdcE/kAHYubCwMKNTp06GYRhG48aNjb59+xqGYRiffvqpceuvSPfu3Y1HHnnE5txXXnnFqFGjRpZtL1u2zPD09Mz02MKFCw1Jxvnz5w3DMIyWLVsa9erVs6kzZswYo2rVqobVajXL5s+fb7i7uxtpaWnmedWrV7ep8+qrrxrVq1c3DMMwjh07ZkgyduzYYR6/dOmS4ebmZnz00UeGYRjGxIkTjbp169r0PXv2bKN8+fLm81tfJwAFz9tvv20UKVLEuHHjhpGUlGQUKlTIuHDhgrFq1SqjRYsWhmEYRlRUlCHJOH36tGEYhhEdHW1IMi5fvmwYRtbvWeXLlzeee+4587nVajVKly5tLFy4MMvx3O49o2vXruZ7lGEYhiRj2LBhNnWaNGliDBgwwKasS5cuRvv27W3OGzRokE2doKAg4/nnnzcMwzDeeusto3jx4sbVq1fN4+vXrzccHByMhIQEwzD+eg996aWXbNro1KmTERYWZj4vX768MXv27CznigcfV4iBW8yYMUPvvvuueXXhVkeOHFHTpk1typo2barjx4/bXOXNLuP/L2m49Z/f6tevn6HP4OBgmzpNmzbV1atXba5kN27c2KZOcHCwOa4jR46oUKFCCgoKMo+XLFlSVatWzXSeAB5MrVq1UnJysvbt26dt27bpoYcekpeXl1q2bGmuI96yZYsqVqyocuXK5bj9OnXqmF+nLwW7cOHCXY3VMIwMSw8aNGhg8zyr99y/v28FBwdneJ5e58iRI6pbt66KFCli04bVar2rq9v45yIQA7do0aKFQkJCNHr06Dzv68iRI/Lw8FDJkiXNslvftO8nBwcHmzXHEje1AA+aypUrq2zZsoqOjlZ0dLRatmwpSfLz85O/v7927typ6OhotWnT5q7ad3JysnlusVjuereII0eOqEKFCjZlvP8hPxGIgb+ZPn26vvjiC+3atcumvHr16tqxY4dN2Y4dO/TQQw/J0dExR31cuHBBq1atUufOneXgkPWv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qVOn3tOYQkNDbZ4vXbpUXl5e+vnnn1WrVi2zfNiwYXrqqaeybMfLy8v8+qWXXlJ8fLz27dtnlo0bN878OiAgQCNGjNCHH36okSNHys3NTe7u7ipUqNBtl0isWrVK169f13vvvaciRYpIkubNm6eOHTtqxowZ8vb2liQVL15c8+bNk6Ojo6pVq6YOHTooKiqKQAzgrhCIASAXtW7dWgsXLlRycrJmz56tQoUKKTQ0VD/99JOuXbumRx55xKZ+amqq6tWrJ0mKiYlRw4YNbY43atTonsd0/PhxTZgwQXv27NGlS5dktVolSXFxcTaBuEGDBtlq76233tKSJUu0c+dOm5C8evVqvfnmm4qNjdXVq1d18+ZNeXh45GisR44cUd26dc0wLElNmzaV1WpVTEyMGYhr1qwpR0dHs46vr69+/PHHHPUFAOkIxACQi4oUKaLKlStL+utKbN26dbVkyRIzeK5fv15lypSxOcfFxSXb7Ts4OMgwDJuyO62d7dixo8qXL6+3335bfn5+slqtqlWrllJTUzOM/U6io6M1dOhQffDBB6pTp45ZvmvXLvXo0UOTJ09WSEiIPD099eGHH+qNN97I9txy4talGtJf65DTgz4A5BSBGADyiIODg8aMGaPw8HAdO3ZMLi4uiouLU8uWLTOtX7VqVX311Vc2ZbcuSZD+WraQkJAgwzDMG9oOHjyY5Rh+++03xcTE6O2331bz5s0lSdu3b7+r+Zw4cUJPP/20xowZk2FpRfpa6bFjx5plp0+ftqnj7OxsrkHOSvXq1bV8+XIlJyebAX3Hjh1ycHBQ1apV72rcAHAn7DIBAHmoS5cucnR01OLFizVixAgNHz5c7777rmJjY3XgwAHNnTtX7777riTp3//+t44ePapXX31Vx44d00cffWSzE4MktWrVShcvXtTMmTMVGxur+fPn6+uvv86y/+LFi6tkyZJ66623dOLECW3evFnh4eE5nseff/6pjh07ql69eho4cKASEhLMhyRVqVJFcXFx+vDDDxUbG6s333xTn376qU0bAQEBOnnypA4ePKhLly4pJSUlQz89evSQq6urwsLCdPjwYfOKdM+ePc3lEgCQ2wjEAJCHChUqpCFDhmjmzJkaPXq0xo8fr4iICFWvXl2PPfaY1q9frwoVKkiSKlSooI8//lhr165VnTp1tHDhQvOKa/qyiurVq2vBggWaP3++6tatq7179952JwoHBwd9+OGH2r9/v2rVqqXhw4ebN+3lxPnz53X06FFFRUXJz89Pvr6+5kOSnnjiCQ0fPlxDhgxRYGCgdu7cqfHjx9u0ERoaqscee0ytW7eWl5eXPvjggwz9FC5cWN98841+//13NWzYUE8//bQefvhhzZs3L8djBoDsshh/X4wGACgwpk6dqkWLFunMmTP5PRQA+MdiDTEAFCALFixQw4YNVbJkSe3YsUP/+c9/NGTIkPweFgD8oxGIAaAAOX78uF5//XX9/vvvKleunF5++WWNHj06v4cFAP9oLJkAAACAXeOmOgAAANg1AjEAAADsGoEYAAAAdo1ADAAAALtGIAYAAIBdIxADAADArhGIAQAAYNcIxAAAALBr/w935WN1FJZZkAAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ], + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\n", + "from tensorflow.keras.optimizers import Adam\n", + "from tensorflow.keras.losses import categorical_crossentropy\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# Reshape data if not already done\n", + "if X_train.shape[-1] != 1:\n", + " X_train = X_train.reshape(-1, 28, 28, 1)\n", + " X_test = X_test.reshape(-1, 28, 28, 1)\n", + "\n", + "# Define regularization options to test\n", + "regularization_options = {\n", + " \"No Dropout\": False,\n", + " \"With Dropout\": True\n", + "}\n", + "results_regularization = {}\n", + "\n", + "print(\"Experimenting with Dropout regularization:\")\n", + "\n", + "for name, use_dropout in regularization_options.items():\n", + " print(f\"\\nTraining model {name}...\")\n", + "\n", + " # Re-initialize the model for each experiment\n", + " model = Sequential()\n", + " model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))\n", + " model.add(MaxPooling2D(pool_size=(2, 2)))\n", + " model.add(Flatten())\n", + " model.add(Dense(128, activation='relu'))\n", + " if use_dropout:\n", + " model.add(Dropout(0.5)) # Add dropout layer with a rate of 0.5\n", + " model.add(Dense(10, activation='softmax'))\n", + "\n", + " # Compile the model\n", + " model.compile(loss=categorical_crossentropy,\n", + " optimizer=Adam(),\n", + " metrics=['accuracy'])\n", + "\n", + " # Train the model (using fewer epochs for quicker experimentation)\n", + " history = model.fit(X_train, y_train_one_hot, epochs=5, validation_split=0.2, verbose=0) # verbose=0 to reduce output\n", + "\n", + " # Evaluate the model\n", + " loss, accuracy = model.evaluate(X_test, y_test_one_hot, verbose=0) # verbose=0 to reduce output\n", + " print(f\"Test Accuracy {name}: {accuracy:.4f}\")\n", + "\n", + " # Store the results\n", + " results_regularization[name] = accuracy\n", + "\n", + "# Print summary of regularization experiments\n", + "print(\"\\nRegularization Experiment Results (Dropout):\")\n", + "for name, accuracy in results_regularization.items():\n", + " print(f\"{name}: Test Accuracy: {accuracy:.4f}\")\n", + "\n", + "# Optional: Visualize the results\n", + "plt.figure(figsize=(8, 5))\n", + "plt.bar(results_regularization.keys(), results_regularization.values())\n", + "plt.xlabel(\"Regularization\")\n", + "plt.ylabel(\"Test Accuracy\")\n", + "plt.title(\"CNN Performance with and without Dropout\")\n", + "plt.ylim(min(results_regularization.values()) * 0.9, max(results_regularization.values()) * 1.1) # Adjust y-axis limits for better visualization\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "cb426f26", + "metadata": { + "id": "cb426f26" + }, + "source": [ + "Reflection: Report on the performance of the models you tested. Did any of the changes you made improve the model's performance? If so, which ones? What do you think contributed to these improvements? Finally, what combination of hyperparameters and regularization techniques yielded the best performance?\n", + "\n", + "**Your answer here**\n", + "The hyperparameter experiment resullted in 128 filters having the best results. Each time more filters were added the accuracy improved. This could be because the model had more diverse features from the original input data to learn from with the addition of more filters. Also experimenting with regularization dropout did not give the best results instead no dropout performed best. Perhaps 5 epochs was to low a number to effective test or dropout rate of 0.5 was too high. The combination of 128 filters and no drpout was the most effective at helping to more acurately identify unseen data, as measured by test accuracy." + ] + }, + { + "cell_type": "markdown", + "id": "46c43a3d", + "metadata": { + "id": "46c43a3d" + }, + "source": [ + "# 5. Training Final Model and Evaluation\n", + "\n", + "In this section, you will train the final model using the best hyperparameters and regularization techniques you found in the previous section. You should:\n", + "- [ ] Compile the final model with the best hyperparameters and regularization techniques.\n", + "- [ ] Train the final model on the training set and evaluate it on the test set.\n", + "- [ ] Report the final model's performance on the test set, including accuracy and any other relevant metrics." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "31f926d1", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "31f926d1", + "outputId": "252bfbc4-b9df-4d74-c979-e56c2f530179" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.12/dist-packages/keras/src/layers/convolutional/base_conv.py:113: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", + " super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Training the final model...\n", + "Epoch 1/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m109s\u001b[0m 72ms/step - accuracy: 0.8173 - loss: 0.5039 - val_accuracy: 0.8949 - val_loss: 0.2963\n", + "Epoch 2/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m141s\u001b[0m 72ms/step - accuracy: 0.9020 - loss: 0.2662 - val_accuracy: 0.9030 - val_loss: 0.2654\n", + "Epoch 3/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m107s\u001b[0m 71ms/step - accuracy: 0.9283 - loss: 0.2000 - val_accuracy: 0.9103 - val_loss: 0.2441\n", + "Epoch 4/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m107s\u001b[0m 71ms/step - accuracy: 0.9392 - loss: 0.1653 - val_accuracy: 0.8976 - val_loss: 0.2909\n", + "Epoch 5/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m112s\u001b[0m 74ms/step - accuracy: 0.9490 - loss: 0.1366 - val_accuracy: 0.9123 - val_loss: 0.2611\n", + "Epoch 6/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m106s\u001b[0m 71ms/step - accuracy: 0.9583 - loss: 0.1110 - val_accuracy: 0.9158 - val_loss: 0.2747\n", + "Epoch 7/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m107s\u001b[0m 71ms/step - accuracy: 0.9675 - loss: 0.0894 - val_accuracy: 0.9147 - val_loss: 0.2813\n", + "Epoch 8/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m106s\u001b[0m 71ms/step - accuracy: 0.9769 - loss: 0.0674 - val_accuracy: 0.9204 - val_loss: 0.2987\n", + "Epoch 9/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m111s\u001b[0m 74ms/step - accuracy: 0.9780 - loss: 0.0600 - val_accuracy: 0.9133 - val_loss: 0.3524\n", + "Epoch 10/10\n", + "\u001b[1m1500/1500\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m142s\u001b[0m 74ms/step - accuracy: 0.9846 - loss: 0.0451 - val_accuracy: 0.9025 - val_loss: 0.3967\n", + "\n", + "Evaluating the final model...\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 13ms/step - accuracy: 0.9007 - loss: 0.4252\n", + "Final Test Loss: 0.4303\n", + "Final Test Accuracy: 0.9005\n" + ] + } + ], + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense\n", + "from tensorflow.keras.optimizers import Adam\n", + "from tensorflow.keras.losses import categorical_crossentropy\n", + "\n", + "# Reshape data if not already done (important if running this cell independently)\n", + "if X_train.shape[-1] != 1:\n", + " X_train = X_train.reshape(-1, 28, 28, 1)\n", + " X_test = X_test.reshape(-1, 28, 28, 1)\n", + "\n", + "# Define the final model with the best hyperparameters and regularization\n", + "# Best: 128 filters, No Dropout\n", + "final_model = Sequential()\n", + "final_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))\n", + "final_model.add(MaxPooling2D(pool_size=(2, 2)))\n", + "final_model.add(Flatten())\n", + "final_model.add(Dense(128, activation='relu'))\n", + "final_model.add(Dense(10, activation='softmax')) # Output layer with softmax activation\n", + "\n", + "# Compile the final model\n", + "final_model.compile(loss=categorical_crossentropy,\n", + " optimizer=Adam(),\n", + " metrics=['accuracy'])\n", + "\n", + "# Train the final model (using more epochs for potentially better performance)\n", + "print(\"Training the final model...\")\n", + "history_final = final_model.fit(X_train, y_train_one_hot, epochs=10, validation_split=0.2)\n", + "\n", + "# Evaluate the final model\n", + "print(\"\\nEvaluating the final model...\")\n", + "loss_final, accuracy_final = final_model.evaluate(X_test, y_test_one_hot)\n", + "print(f\"Final Test Loss: {loss_final:.4f}\")\n", + "print(f\"Final Test Accuracy: {accuracy_final:.4f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "a01f8ebc", + "metadata": { + "id": "a01f8ebc" + }, + "source": [ + "Reflection: How does the final model's performance compare to the baseline and the CNN model? What do you think contributed to the final model's performance? If you had time, what other experiments would you run to further improve the model's performance?\n", + "\n", + "**Your answer here**\n", + "The final model correctly classified approximately 90.05% of the images accurately in the test dataset. This is a good accuracy and a significant improvement over the baseline model. The model demonstrates a strong ability to classify images from the Fashion MNIST dataset, achieving a high accuracy on unseen data. The training loss consistently decreased with each epoch, with the tenth epoch havung a 0.0451 training loss and the final test loss being 0.4303.\n", + "Of the three models the simple CNN has the best performance. I dont quite know why would this be. CNNs are better suited than linear models for image data. This is based on the test loss and accuracy rates.\n", + "Other experimennts could be other hyperparameters, combination regularization tuning techniques, or different model architectures.\n" + ] + }, + { + "cell_type": "markdown", + "id": "01db8512", + "metadata": { + "id": "01db8512" + }, + "source": [ + "🚨 **Please review our [Assignment Submission Guide](https://github.com/UofT-DSI/onboarding/blob/main/onboarding_documents/submissions.md)** 🚨 for detailed instructions on how to format, branch, and submit your work. Following these guidelines is crucial for your submissions to be evaluated correctly.\n", + "### Submission Parameters:\n", + "* Submission Due Date: `23:59 PM - 26/10/2025`\n", + "* The branch name for your repo should be: `assignment-1`\n", + "* What to submit for this assignment:\n", + " * This Jupyter Notebook (assignment_1.ipynb)\n", + " * The Lab 1 notebook (labs/lab_1.ipynb)\n", + " * The Lab 2 notebook (labs/lab_2.ipynb)\n", + " * The Lab 3 notebook (labs/lab_3.ipynb)\n", + "* What the pull request link should look like for this assignment: `https://github.com//deep_learning/pull/`\n", + "* Open a private window in your browser. Copy and paste the link to your pull request into the address bar. Make sure you can see your pull request properly. This helps the technical facilitator and learning support staff review your submission easily.\n", + "Checklist:\n", + "- [ ] Created a branch with the correct naming convention.\n", + "- [ ] Ensured that the repository is public.\n", + "- [ ] Reviewed the PR description guidelines and adhered to them.\n", + "- [ ] Verify that the link is accessible in a private browser window.\n", + "If you encounter any difficulties or have questions, please don't hesitate to reach out to our team via our Slack at `#cohort-7-help-ml`. Our Technical Facilitators and Learning Support staff are here to help you navigate any challenges." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "deep_learning", + "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.12.11" + }, + "colab": { + "provenance": [] + } }, - { - "cell_type": "code", - "execution_count": null, - "id": "420c7178", - "metadata": {}, - "outputs": [], - "source": [ - "from tensorflow.keras.datasets import fashion_mnist\n", - "(X_train, y_train), (X_test, y_test) = fashion_mnist.load_data()\n", - "\n", - "# Normalize the pixel values to be between 0 and 1\n", - "X_train = X_train.astype('float32') / 255.0\n", - "X_test = X_test.astype('float32') / 255.0\n", - "\n", - "# Classes in the Fashion MNIST dataset\n", - "class_names = [\"T-shirt/top\", \"Trouser\", \"Pullover\", \"Dress\", \"Coat\", \"Sandal\", \"Shirt\", \"Sneaker\", \"Bag\", \"Ankle boot\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a6c89fe7", - "metadata": {}, - "outputs": [], - "source": [ - "# Inspect the shapes of the datasets\n", - "\n", - "\n", - "# Convert labels to one-hot encoding\n", - "from tensorflow.keras.utils import to_categorical\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "13e100db", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "# Verify the data looks as expected\n" - ] - }, - { - "cell_type": "markdown", - "id": "989f7dd0", - "metadata": {}, - "source": [ - "Reflection: Does the data look as expected? How is the quality of the images? Are there any issues with the dataset that you notice?\n", - "\n", - "**Your answer here**" - ] - }, - { - "cell_type": "markdown", - "id": "c9e8ad60", - "metadata": {}, - "source": [ - "# 2. Baseline Model\n", - "\n", - "In this section, you will create a linear regression model as a baseline. This model will not use any convolutional layers, but it will help you understand the performance of a simple model on this dataset.\n", - "You should:\n", - "- [ ] Create a simple linear regression model using Keras.\n", - "- [ ] Compile the model with an appropriate loss function and optimizer.\n", - "- [ ] Train the model on the training set and evaluate it on the test set.\n", - "\n", - "A linear regression model can be created using the `Sequential` API in Keras. Using a single `Dense` layer with no activation function is equivalent to a simple linear regression model. Make sure that the number of units in the output layer matches the number of classes in the dataset.\n", - "\n", - "Note that for this step, we will need to use `Flatten` to convert the 2D images into 1D vectors before passing them to the model. Put a `Flatten()` layer as the first layer in your model so that the 2D image data can be flattened into 1D vectors." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8563a7aa", - "metadata": {}, - "outputs": [], - "source": [ - "from keras.models import Sequential\n", - "from keras.layers import Dense, Flatten\n", - "\n", - "# Create a simple linear regression model\n", - "model = Sequential()\n", - "# You can use `model.add()` to add layers to the model\n", - "\n", - "# Compile the model using `model.compile()`\n", - "\n", - "# Train the model with `model.fit()`\n", - "\n", - "# Evaluate the model with `model.evaluate()`" - ] - }, - { - "cell_type": "markdown", - "id": "9a07e9f7", - "metadata": {}, - "source": [ - "Reflection: What is the performance of the baseline model? How does it compare to what you expected? Why do you think the performance is at this level?\n", - "\n", - "**Your answer here**" - ] - }, - { - "cell_type": "markdown", - "id": "fa107b59", - "metadata": {}, - "source": [ - "# 3. Building and Evaluating a Simple CNN Model\n", - "\n", - "In this section, you will build a simple Convolutional Neural Network (CNN) model using Keras. A convolutional neural network is a type of deep learning model that is particularly effective for image classification tasks. Unlike the basic neural networks we have built in the labs, CNNs can accept images as input without needing to flatten them into vectors.\n", - "\n", - "You should:\n", - "- [ ] Build a simple CNN model with at least one convolutional layer (to learn spatial hierarchies in images) and one fully connected layer (to make predictions).\n", - "- [ ] Compile the model with an appropriate loss function and metrics for a multi-class classification problem.\n", - "- [ ] Train the model on the training set and evaluate it on the test set.\n", - "\n", - "Convolutional layers are designed to accept inputs with three dimensions: height, width and channels (e.g., RGB for color images). For grayscale images like those in Fashion MNIST, the input shape will be (28, 28, 1).\n", - "\n", - "When you progress from the convolutional layers to the fully connected layers, you will need to flatten the output of the convolutional layers. This can be done using the `Flatten` layer in Keras, which doesn't require any parameters." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3513cf3d", - "metadata": {}, - "outputs": [], - "source": [ - "from keras.layers import Conv2D\n", - "\n", - "# Reshape the data to include the channel dimension\n", - "X_train = X_train.reshape(-1, 28, 28, 1)\n", - "X_test = X_test.reshape(-1, 28, 28, 1)\n", - "\n", - "# Create a simple CNN model\n", - "model = Sequential()\n", - "\n", - "# Train the model\n", - "\n", - "# Evaluate the model" - ] - }, - { - "cell_type": "markdown", - "id": "fabe379c", - "metadata": {}, - "source": [ - "Reflection: Did the CNN model perform better than the baseline model? If so, by how much? What do you think contributed to this improvement?\n", - "\n", - "**Your answer here**" - ] - }, - { - "cell_type": "markdown", - "id": "1a5e2463", - "metadata": {}, - "source": [ - "# 3. Designing and Running Controlled Experiments\n", - "\n", - "In this section, you will design and run controlled experiments to improve the model's performance. You will focus on one hyperparameter and one regularization technique.\n", - "You should:\n", - "- [ ] Choose one hyperparameter to experiment with (e.g., number of filters, kernel size, number of layers, etc.) and one regularization technique (e.g., dropout, L2 regularization). For your hyperparameter, you should choose at least three different values to test (but there is no upper limit). For your regularization technique, simply test the presence or absence of the technique.\n", - "- [ ] Run experiments by modifying the model architecture or hyperparameters, and evaluate the performance of each model on the test set.\n", - "- [ ] Record the results of your experiments, including the test accuracy and any other relevant metrics.\n", - "- [ ] Visualize the results of your experiments using plots or tables to compare the performance of different models.\n", - "\n", - "The best way to run your experiments is to create a `for` loop that iterates over a range of values for the hyperparameter you are testing. For example, if you are testing different numbers of filters, you can create a loop that runs the model with 32, 64, and 128 filters. Within the loop, you can compile and train the model, then evaluate it on the test set. After each iteration, you can store the results in a list or a dictionary for later analysis.\n", - "\n", - "Note: It's critical that you re-initialize the model (by creating a new instance of the model) before each experiment. If you don't, the model will retain the weights from the previous experiment, which can lead to misleading results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "99d6f46c", - "metadata": {}, - "outputs": [], - "source": [ - "# A. Test Hyperparameters" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dc43ac81", - "metadata": {}, - "outputs": [], - "source": [ - "# B. Test presence or absence of regularization" - ] - }, - { - "cell_type": "markdown", - "id": "cb426f26", - "metadata": {}, - "source": [ - "Reflection: Report on the performance of the models you tested. Did any of the changes you made improve the model's performance? If so, which ones? What do you think contributed to these improvements? Finally, what combination of hyperparameters and regularization techniques yielded the best performance?\n", - "\n", - "**Your answer here**" - ] - }, - { - "cell_type": "markdown", - "id": "46c43a3d", - "metadata": {}, - "source": [ - "# 5. Training Final Model and Evaluation\n", - "\n", - "In this section, you will train the final model using the best hyperparameters and regularization techniques you found in the previous section. You should:\n", - "- [ ] Compile the final model with the best hyperparameters and regularization techniques.\n", - "- [ ] Train the final model on the training set and evaluate it on the test set.\n", - "- [ ] Report the final model's performance on the test set, including accuracy and any other relevant metrics." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "31f926d1", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "id": "a01f8ebc", - "metadata": {}, - "source": [ - "Reflection: How does the final model's performance compare to the baseline and the CNN model? What do you think contributed to the final model's performance? If you had time, what other experiments would you run to further improve the model's performance?\n", - "\n", - "**Your answer here**" - ] - }, - { - "cell_type": "markdown", - "id": "01db8512", - "metadata": {}, - "source": [ - "🚨 **Please review our [Assignment Submission Guide](https://github.com/UofT-DSI/onboarding/blob/main/onboarding_documents/submissions.md)** 🚨 for detailed instructions on how to format, branch, and submit your work. Following these guidelines is crucial for your submissions to be evaluated correctly.\n", - "### Submission Parameters:\n", - "* Submission Due Date: `23:59 PM - 26/10/2025`\n", - "* The branch name for your repo should be: `assignment-1`\n", - "* What to submit for this assignment:\n", - " * This Jupyter Notebook (assignment_1.ipynb)\n", - " * The Lab 1 notebook (labs/lab_1.ipynb)\n", - " * The Lab 2 notebook (labs/lab_2.ipynb)\n", - " * The Lab 3 notebook (labs/lab_3.ipynb)\n", - "* What the pull request link should look like for this assignment: `https://github.com//deep_learning/pull/`\n", - "* Open a private window in your browser. Copy and paste the link to your pull request into the address bar. Make sure you can see your pull request properly. This helps the technical facilitator and learning support staff review your submission easily.\n", - "Checklist:\n", - "- [ ] Created a branch with the correct naming convention.\n", - "- [ ] Ensured that the repository is public.\n", - "- [ ] Reviewed the PR description guidelines and adhered to them.\n", - "- [ ] Verify that the link is accessible in a private browser window.\n", - "If you encounter any difficulties or have questions, please don't hesitate to reach out to our team via our Slack at `#cohort-7-help-ml`. Our Technical Facilitators and Learning Support staff are here to help you navigate any challenges." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "deep_learning", - "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.12.11" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file