diff --git a/Course 2: Convolutional Neural Networks in Tensorflow/README.md b/Course 2: Convolutional Neural Networks in Tensorflow/README.md
index cbe0dd4..e095e60 100644
--- a/Course 2: Convolutional Neural Networks in Tensorflow/README.md
+++ b/Course 2: Convolutional Neural Networks in Tensorflow/README.md
@@ -55,6 +55,10 @@
+
+
+
+
- [Programming assignment]().
### Week 4
diff --git a/Course 2: Convolutional Neural Networks in Tensorflow/Week 2/Exercise_2_Cats_vs_Dogs_using_augmentation_Question-FINAL.ipynb b/Course 2: Convolutional Neural Networks in Tensorflow/Week 2/Exercise_2_Cats_vs_Dogs_using_augmentation_Question-FINAL.ipynb
new file mode 100644
index 0000000..2462b88
--- /dev/null
+++ b/Course 2: Convolutional Neural Networks in Tensorflow/Week 2/Exercise_2_Cats_vs_Dogs_using_augmentation_Question-FINAL.ipynb
@@ -0,0 +1,499 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "dn-6c02VmqiN"
+ },
+ "outputs": [],
+ "source": [
+ "# ATTENTION: Please do not alter any of the provided code in the exercise. Only add your own code where indicated\n",
+ "# ATTENTION: Please do not add or remove any cells in the exercise. The grader will check specific cells based on the cell position.\n",
+ "# ATTENTION: Please use the provided epoch values when training.\n",
+ "\n",
+ "# In this exercise you will train a CNN on the FULL Cats-v-dogs dataset\n",
+ "# This will require you doing a lot of data preprocessing because\n",
+ "# the dataset isn't split into training and validation for you\n",
+ "# This code block has all the required inputs\n",
+ "import os\n",
+ "import zipfile\n",
+ "import random\n",
+ "import shutil\n",
+ "import tensorflow as tf\n",
+ "from tensorflow.keras.optimizers import RMSprop\n",
+ "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
+ "from tensorflow.keras.models import Sequential\n",
+ "from tensorflow.keras.layers import Flatten, Dense, Conv2D, MaxPooling2D\n",
+ "from tensorflow.keras.callbacks import Callback\n",
+ "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
+ "from shutil import copyfile\n",
+ "from os import getcwd"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "3sd9dQWa23aj"
+ },
+ "outputs": [],
+ "source": [
+ "# This code block unzips the full Cats-v-Dogs dataset to /tmp\n",
+ "# which will create a tmp/PetImages directory containing subdirectories\n",
+ "# called 'Cat' and 'Dog' (that's how the original researchers structured it)\n",
+ "path_cats_and_dogs = f\"{getcwd()}/../tmp2/cats-and-dogs.zip\"\n",
+ "shutil.rmtree('/tmp')\n",
+ "\n",
+ "local_zip = path_cats_and_dogs\n",
+ "zip_ref = zipfile.ZipFile(local_zip, 'r')\n",
+ "zip_ref.extractall('/tmp')\n",
+ "zip_ref.close()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "gi3yD62a6X3S"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1500\n",
+ "1500\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(len(os.listdir('/tmp/PetImages/Cat/')))\n",
+ "print(len(os.listdir('/tmp/PetImages/Dog/')))\n",
+ "\n",
+ "# Expected Output:\n",
+ "# 1500\n",
+ "# 1500"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "F-QkLjxpmyK2"
+ },
+ "outputs": [],
+ "source": [
+ "# Use os.mkdir to create your directories\n",
+ "# You will need a directory for cats-v-dogs, and subdirectories for training\n",
+ "# and testing. These in turn will need subdirectories for 'cats' and 'dogs'\n",
+ "try:\n",
+ " #YOUR CODE GOES HERE\n",
+ " main_dir = \"/tmp/cats-v-dogs/\"\n",
+ " \n",
+ " train_dir = os.path.join(main_dir, \"training\")\n",
+ " test_dir = os.path.join(main_dir, \"testing\")\n",
+ " \n",
+ " cats_train = os.path.join(train_dir, \"cats\")\n",
+ " dogs_train = os.path.join(train_dir, \"dogs\")\n",
+ " \n",
+ " cats_test = os.path.join(test_dir, \"cats\")\n",
+ " dogs_test = os.path.join(test_dir, \"dogs\")\n",
+ " \n",
+ " os.mkdir(main_dir)\n",
+ " \n",
+ " os.mkdir(train_dir)\n",
+ " os.mkdir(test_dir)\n",
+ " \n",
+ " os.mkdir(cats_train)\n",
+ " os.mkdir(dogs_train)\n",
+ " \n",
+ " os.mkdir(cats_test)\n",
+ " os.mkdir(dogs_test)\n",
+ "except OSError:\n",
+ " pass"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "zvSODo0f9LaU"
+ },
+ "outputs": [],
+ "source": [
+ "# Write a python function called split_data which takes\n",
+ "# a SOURCE directory containing the files\n",
+ "# a TRAINING directory that a portion of the files will be copied to\n",
+ "# a TESTING directory that a portion of the files will be copie to\n",
+ "# a SPLIT SIZE to determine the portion\n",
+ "# The files should also be randomized, so that the training set is a random\n",
+ "# X% of the files, and the test set is the remaining files\n",
+ "# SO, for example, if SOURCE is PetImages/Cat, and SPLIT SIZE is .9\n",
+ "# Then 90% of the images in PetImages/Cat will be copied to the TRAINING dir\n",
+ "# and 10% of the images will be copied to the TESTING dir\n",
+ "# Also -- All images should be checked, and if they have a zero file length,\n",
+ "# they will not be copied over\n",
+ "#\n",
+ "# os.listdir(DIRECTORY) gives you a listing of the contents of that directory\n",
+ "# os.path.getsize(PATH) gives you the size of the file\n",
+ "# copyfile(source, destination) copies a file from source to destination\n",
+ "# random.sample(list, len(list)) shuffles a list\n",
+ "def split_data(SOURCE, TRAINING, TESTING, SPLIT_SIZE):\n",
+ "# YOUR CODE STARTS HERE\n",
+ " data = os.listdir(SOURCE)\n",
+ " data = random.sample(data, len(data)) # shuffled\n",
+ " for count, file in enumerate(data):\n",
+ " if(count < SPLIT_SIZE * len(data)) and os.path.getsize(f\"{SOURCE}/{file}\")!=0:\n",
+ " copyfile(f\"{SOURCE}/{file}\", f\"{TRAINING}/{file}\")\n",
+ " elif (count >= SPLIT_SIZE * len(data)) and os.path.getsize(f\"{SOURCE}/{file}\")!=0:\n",
+ " copyfile(f\"{SOURCE}/{file}\", f\"{TESTING}/{file}\")\n",
+ "# YOUR CODE ENDS HERE\n",
+ "\n",
+ "\n",
+ "CAT_SOURCE_DIR = \"/tmp/PetImages/Cat/\"\n",
+ "TRAINING_CATS_DIR = \"/tmp/cats-v-dogs/training/cats/\"\n",
+ "TESTING_CATS_DIR = \"/tmp/cats-v-dogs/testing/cats/\"\n",
+ "DOG_SOURCE_DIR = \"/tmp/PetImages/Dog/\"\n",
+ "TRAINING_DOGS_DIR = \"/tmp/cats-v-dogs/training/dogs/\"\n",
+ "TESTING_DOGS_DIR = \"/tmp/cats-v-dogs/testing/dogs/\"\n",
+ "\n",
+ "split_size = .9\n",
+ "split_data(CAT_SOURCE_DIR, TRAINING_CATS_DIR, TESTING_CATS_DIR, split_size)\n",
+ "split_data(DOG_SOURCE_DIR, TRAINING_DOGS_DIR, TESTING_DOGS_DIR, split_size)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "luthalB76ufC"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1350\n",
+ "1350\n",
+ "150\n",
+ "150\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(len(os.listdir('/tmp/cats-v-dogs/training/cats/')))\n",
+ "print(len(os.listdir('/tmp/cats-v-dogs/training/dogs/')))\n",
+ "print(len(os.listdir('/tmp/cats-v-dogs/testing/cats/')))\n",
+ "print(len(os.listdir('/tmp/cats-v-dogs/testing/dogs/')))\n",
+ "\n",
+ "# Expected output:\n",
+ "# 1350\n",
+ "# 1350\n",
+ "# 150\n",
+ "# 150"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "-BQrav4anTmj"
+ },
+ "outputs": [],
+ "source": [
+ "# DEFINE A KERAS MODEL TO CLASSIFY CATS V DOGS\n",
+ "# USE AT LEAST 3 CONVOLUTION LAYERS\n",
+ "model = tf.keras.models.Sequential([\n",
+ "# YOUR CODE HERE\n",
+ " Conv2D(16, (3,3), activation = 'relu', input_shape = (150,150,3)),\n",
+ " MaxPooling2D(2,2),\n",
+ " Conv2D(32, (3,3), activation = 'relu'),\n",
+ " MaxPooling2D(2,2),\n",
+ " Conv2D(64, (3,3), activation = 'relu'),\n",
+ " MaxPooling2D(2,2),\n",
+ " Flatten(),\n",
+ " Dense(512, activation = 'relu'),\n",
+ " Dense(1, activation = 'sigmoid')\n",
+ "])\n",
+ "\n",
+ "model.compile(optimizer=RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['acc'])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# NOTE:\n",
+ "\n",
+ "In the cell below you **MUST** use a batch size of 10 (`batch_size=10`) for the `train_generator` and the `validation_generator`. Using a batch size greater than 10 will exceed memory limits on the Coursera platform."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "mlNjoJ5D61N6"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Found 2700 images belonging to 2 classes.\n",
+ "Found 300 images belonging to 2 classes.\n"
+ ]
+ }
+ ],
+ "source": [
+ "TRAINING_DIR = train_dir#YOUR CODE HERE\n",
+ "train_datagen = ImageDataGenerator(\n",
+ " rescale = 1./255,\n",
+ " rotation_range = 40,\n",
+ " width_shift_range = 0.2,\n",
+ " height_shift_range = 0.2,\n",
+ " shear_range = 0.2,\n",
+ " horizontal_flip = True,\n",
+ " fill_mode = 'nearest'\n",
+ "\n",
+ ") #YOUR CODE HERE\n",
+ "\n",
+ "# NOTE: YOU MUST USE A BATCH SIZE OF 10 (batch_size=10) FOR THE \n",
+ "# TRAIN GENERATOR.\n",
+ "train_generator = train_datagen.flow_from_directory(\n",
+ " TRAINING_DIR,\n",
+ " target_size = (150, 150),\n",
+ " batch_size = 10,\n",
+ " class_mode = 'binary'\n",
+ " )#YOUR CODE HERE\n",
+ "\n",
+ "VALIDATION_DIR = test_dir #YOUR CODE HERE\n",
+ "validation_datagen = ImageDataGenerator(\n",
+ " rescale = 1./255,\n",
+ " rotation_range = 40,\n",
+ " width_shift_range = 0.2,\n",
+ " height_shift_range = 0.2,\n",
+ " shear_range = 0.2,\n",
+ " horizontal_flip = True,\n",
+ " fill_mode = 'nearest'\n",
+ ") #YOUR CODE HERE\n",
+ "\n",
+ "# NOTE: YOU MUST USE A BACTH SIZE OF 10 (batch_size=10) FOR THE \n",
+ "# VALIDATION GENERATOR.\n",
+ "validation_generator = validation_datagen.flow_from_directory(\n",
+ " VALIDATION_DIR,\n",
+ " target_size = (150, 150),\n",
+ " batch_size = 10,\n",
+ " class_mode = 'binary'\n",
+ " )#YOUR CODE HERE\n",
+ "\n",
+ "# Expected Output:\n",
+ "# Found 2700 images belonging to 2 classes.\n",
+ "# Found 300 images belonging to 2 classes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "KyS4n53w7DxC"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Epoch 1/2\n",
+ "270/270 [==============================] - 60s 221ms/step - loss: 7.4806 - acc: 0.4978 - val_loss: 0.7257 - val_acc: 0.5000\n",
+ "Epoch 2/2\n",
+ "270/270 [==============================] - 55s 205ms/step - loss: 0.7067 - acc: 0.5252 - val_loss: 0.6813 - val_acc: 0.5067\n"
+ ]
+ }
+ ],
+ "source": [
+ "history = model.fit_generator(train_generator,\n",
+ " epochs=2,\n",
+ " verbose=1,\n",
+ " validation_data=validation_generator)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {
+ "colab": {},
+ "colab_type": "code",
+ "id": "MWZrJN4-65RC"
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Text(0.5, 1.0, 'Training and validation loss')"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "