{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# [Part 1] Data Augmentation Techniques With (tf.data)","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport os\nimport zipfile\nimport shutil","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-12T08:55:08.891597Z","iopub.execute_input":"2022-05-12T08:55:08.891927Z","iopub.status.idle":"2022-05-12T08:55:08.897305Z","shell.execute_reply.started":"2022-05-12T08:55:08.891894Z","shell.execute_reply":"2022-05-12T08:55:08.895966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Extract And Exploring (Training) And (Testing) Data","metadata":{}},{"cell_type":"code","source":"# Extract Training Data\nextracted = './train'\nwith zipfile.ZipFile('../input/dogs-vs-cats/train.zip', 'r') as zip_ref:\n    zip_ref.extractall(extracted)\n    \n# Extract Testing Data\nextracted = './test'\nwith zipfile.ZipFile('../input/dogs-vs-cats/test1.zip', 'r') as zip_ref:\n    zip_ref.extractall(extracted)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T08:36:42.963363Z","iopub.execute_input":"2022-05-12T08:36:42.963613Z","iopub.status.idle":"2022-05-12T08:37:01.948515Z","shell.execute_reply.started":"2022-05-12T08:36:42.96358Z","shell.execute_reply":"2022-05-12T08:37:01.947238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Exploring Training Data\nos.listdir('./train/train')[:6]","metadata":{"execution":{"iopub.status.busy":"2022-05-12T08:53:54.399021Z","iopub.execute_input":"2022-05-12T08:53:54.399331Z","iopub.status.idle":"2022-05-12T08:53:54.42015Z","shell.execute_reply.started":"2022-05-12T08:53:54.399298Z","shell.execute_reply":"2022-05-12T08:53:54.419316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Exploring Testing Data\nos.listdir('./test/test1')[:6]","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:08:38.683353Z","iopub.execute_input":"2022-05-12T09:08:38.683908Z","iopub.status.idle":"2022-05-12T09:08:38.707914Z","shell.execute_reply.started":"2022-05-12T09:08:38.683871Z","shell.execute_reply":"2022-05-12T09:08:38.706966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Organizing The (Training) And (Testing) Data","metadata":{}},{"cell_type":"code","source":"ORGN_TRAIN_PATH = './train/train'\nDIST_TRAIN_PATH = './train'\n\nORGN_TEST_PATH = './test/test1'\nDIST_TEST_PATH = './test'","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:07:33.930847Z","iopub.execute_input":"2022-05-12T09:07:33.931461Z","iopub.status.idle":"2022-05-12T09:07:33.936745Z","shell.execute_reply.started":"2022-05-12T09:07:33.931408Z","shell.execute_reply":"2022-05-12T09:07:33.935754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for image in os.listdir(ORGN_TRAIN_PATH):\n    label = image.split('.')[0]\n    fileName = image[4:]\n    \n    labelPath = os.path.join(DIST_TRAIN_PATH, label)\n    imgPath = os.path.join(labelPath, fileName)\n    \n    if not os.path.exists(labelPath):\n        os.makedirs(labelPath)\n    \n    p = os.path.join(ORGN_TRAIN_PATH, image)\n    shutil.copy2(p,imgPath)\n    os.remove(p)\nos.rmdir(ORGN_TRAIN_PATH)\nos.listdir(DIST_TRAIN_PATH)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:01:47.936826Z","iopub.execute_input":"2022-05-12T09:01:47.937183Z","iopub.status.idle":"2022-05-12T09:01:47.968038Z","shell.execute_reply.started":"2022-05-12T09:01:47.937147Z","shell.execute_reply":"2022-05-12T09:01:47.967123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for image in os.listdir(ORGN_TEST_PATH):\n    imgPath = os.path.sep.join([DIST_TEST_PATH, image])\n    p = os.path.join(ORGN_TEST_PATH, image)\n    \n    shutil.copy2(p,imgPath)\n    os.remove(p)\n    \nos.rmdir(ORGN_TEST_PATH)\nos.listdir(DIST_TEST_PATH)[:3]","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:07:36.334727Z","iopub.execute_input":"2022-05-12T09:07:36.335099Z","iopub.status.idle":"2022-05-12T09:07:38.551527Z","shell.execute_reply.started":"2022-05-12T09:07:36.335058Z","shell.execute_reply":"2022-05-12T09:07:38.550658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Implementing data augmentation with tf.data and TensorFlow","metadata":{}},{"cell_type":"code","source":"!pip install imutils","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:10:37.986873Z","iopub.execute_input":"2022-05-12T09:10:37.987953Z","iopub.status.idle":"2022-05-12T09:10:53.025935Z","shell.execute_reply.started":"2022-05-12T09:10:37.987877Z","shell.execute_reply":"2022-05-12T09:10:53.024751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import the necessary packages\nfrom tensorflow.keras.layers.experimental import preprocessing\nfrom tensorflow.data import AUTOTUNE\nfrom imutils import paths\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport argparse\nimport os","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:27:01.414418Z","iopub.execute_input":"2022-05-12T09:27:01.414873Z","iopub.status.idle":"2022-05-12T09:27:01.421017Z","shell.execute_reply.started":"2022-05-12T09:27:01.414837Z","shell.execute_reply":"2022-05-12T09:27:01.419923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_images(imagePath):\n    # read the image from disk, decode it, convert the data type to\n    # floating point, and resize it\n    image = tf.io.read_file(imagePath)\n    image = tf.image.decode_jpeg(image, channels=3)\n    image = tf.image.convert_image_dtype(image, dtype=tf.float32)\n    image = tf.image.resize(image, (156, 156))\n    # parse the class label from the file path\n    label = tf.strings.split(imagePath, os.path.sep)[-2]\n    \n    # return the image and the label\n    return (image, label)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:27:03.25006Z","iopub.execute_input":"2022-05-12T09:27:03.25038Z","iopub.status.idle":"2022-05-12T09:27:03.256982Z","shell.execute_reply.started":"2022-05-12T09:27:03.250342Z","shell.execute_reply":"2022-05-12T09:27:03.255879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"aug = tf.keras.Sequential([\n    preprocessing.RandomFlip(\"horizontal_and_vertical\"),\n    preprocessing.RandomZoom(\n        height_factor=(-0.05, -0.15),\n        width_factor=(-0.05, -0.15)),\n    preprocessing.RandomRotation(0.3)\n])","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:27:05.605077Z","iopub.execute_input":"2022-05-12T09:27:05.60542Z","iopub.status.idle":"2022-05-12T09:27:05.746121Z","shell.execute_reply.started":"2022-05-12T09:27:05.605386Z","shell.execute_reply":"2022-05-12T09:27:05.745437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def augment_using_layers(images, labels):\n    # pass a batch of images through our data augmentation pipeline\n    # and return the augmented images\n    images = aug(images)\n    # return the image and the label\n    return (images, labels)\n\ndef augment_using_ops(images, labels):\n    # randomly flip the images horizontally, randomly flip the images\n    # vertically, and rotate the images by 90 degrees in the counter\n    # clockwise direction\n    images = tf.image.random_flip_left_right(images)\n    images = tf.image.random_flip_up_down(images)\n    images = tf.image.rot90(images)\n    # return the image and the label\n    return (images, labels)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:27:11.579936Z","iopub.execute_input":"2022-05-12T09:27:11.581145Z","iopub.status.idle":"2022-05-12T09:27:11.588049Z","shell.execute_reply.started":"2022-05-12T09:27:11.581083Z","shell.execute_reply":"2022-05-12T09:27:11.586881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set the batch size\nBATCH_SIZE = 8\n# grabs all image paths\nimagePaths = list(paths.list_images(DIST_TRAIN_PATH))\n# build our dataset and data input pipeline\nprint(\"[INFO] loading the dataset...\")\n\n# Original Dataset\norgDS = tf.data.Dataset.from_tensor_slices(imagePaths)\norgDS = (orgDS\n    .shuffle(len(imagePaths), seed=42)\n    .map(load_images, num_parallel_calls=AUTOTUNE)\n    .cache()\n    .batch(BATCH_SIZE)\n    .prefetch(AUTOTUNE)\n)\n\n# Augmented Dataset Using Layer augmentation\nlayersDS = tf.data.Dataset.from_tensor_slices(imagePaths)\nlayersDS = (layersDS\n    .shuffle(len(imagePaths), seed=42)\n    .map(load_images, num_parallel_calls=AUTOTUNE)\n    .map(lambda x, y: augment_using_layers(x, y),num_parallel_calls=AUTOTUNE)\n    .cache()\n    .batch(BATCH_SIZE)\n    .prefetch(AUTOTUNE)\n)\n\n# Augmented Dataset Using (Manually Created Function) augmentation\nopsDS = tf.data.Dataset.from_tensor_slices(imagePaths)\nopsDS = (opsDS\n    .shuffle(len(imagePaths), seed=42)\n    .map(load_images, num_parallel_calls=AUTOTUNE)\n    .map(augment_using_ops, num_parallel_calls=AUTOTUNE)\n    .cache()\n    .batch(BATCH_SIZE)\n    .prefetch(AUTOTUNE)\n)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:41:57.23538Z","iopub.execute_input":"2022-05-12T09:41:57.235882Z","iopub.status.idle":"2022-05-12T09:41:58.030643Z","shell.execute_reply.started":"2022-05-12T09:41:57.23585Z","shell.execute_reply":"2022-05-12T09:41:58.029692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# grab a batch of data from our dataset\norgBatch = next(iter(orgDS))\nlayersBatch = next(iter(layersDS))\nopsBatch = next(iter(opsDS))","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:42:17.595643Z","iopub.execute_input":"2022-05-12T09:42:17.596385Z","iopub.status.idle":"2022-05-12T09:42:18.3111Z","shell.execute_reply.started":"2022-05-12T09:42:17.596349Z","shell.execute_reply":"2022-05-12T09:42:18.31022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# initialize a figure\nprint(\"[INFO] visualizing the first batch of the dataset...\")\ndef plotting (batch, Type):\n    title = \"With data augmentation {} applied\".format(Type)\n    fig = plt.figure(figsize=(BATCH_SIZE, BATCH_SIZE))\n    fig.suptitle(title)\n    # loop over the batch size\n    for i in range(0, BATCH_SIZE):\n        # grab the image and label from the batch\n        (image, label) = (batch[0][i], batch[1][i])\n        # create a subplot and plot the image and label\n        ax = plt.subplot(2, 4, i + 1)\n        plt.imshow(image.numpy())\n        plt.title(label.numpy().decode(\"UTF-8\"))\n        plt.axis(\"off\")\n    # show the plot\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:34:50.798117Z","iopub.execute_input":"2022-05-12T09:34:50.79855Z","iopub.status.idle":"2022-05-12T09:34:50.810055Z","shell.execute_reply.started":"2022-05-12T09:34:50.798511Z","shell.execute_reply":"2022-05-12T09:34:50.80838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plotting(orgBatch, '(Original)')\nplotting(layersBatch, '(Layers)')","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:43:29.647096Z","iopub.execute_input":"2022-05-12T09:43:29.648435Z","iopub.status.idle":"2022-05-12T09:43:31.033937Z","shell.execute_reply.started":"2022-05-12T09:43:29.648369Z","shell.execute_reply":"2022-05-12T09:43:31.032911Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plotting(orgBatch, '(Original)')\nplotting(opsBatch, '(Ops)')","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:44:58.835612Z","iopub.execute_input":"2022-05-12T09:44:58.835925Z","iopub.status.idle":"2022-05-12T09:44:59.926519Z","shell.execute_reply.started":"2022-05-12T09:44:58.835896Z","shell.execute_reply":"2022-05-12T09:44:59.925686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# [Part 2] Implementing Our Data Augmentation Training Script With tf.data","metadata":{}},{"cell_type":"code","source":"# import the necessary packages\nfrom tensorflow.keras.layers import Conv2D\nfrom tensorflow.keras.layers import Activation\nfrom tensorflow.keras.layers import Flatten\nfrom tensorflow.keras.layers import Dense\nfrom tensorflow.keras.layers import MaxPooling2D\nfrom tensorflow.keras.layers import BatchNormalization\nfrom tensorflow.keras.layers import Dropout\nfrom tensorflow.keras import Sequential\nfrom tensorflow.keras.datasets import cifar10\nfrom tensorflow.keras.layers.experimental import preprocessing\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport argparse","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:57:53.558046Z","iopub.execute_input":"2022-05-12T09:57:53.55836Z","iopub.status.idle":"2022-05-12T09:57:53.566152Z","shell.execute_reply.started":"2022-05-12T09:57:53.558324Z","shell.execute_reply":"2022-05-12T09:57:53.565124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define training hyperparameters\nBATCH_SIZE = 64\nEPOCHS = 10\n# load the CIFAR-10 dataset\nprint(\"[INFO] loading training data...\")\n((trainX, trainLabels), (testX, testLabels)) = cifar10.load_data()","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:57:55.914745Z","iopub.execute_input":"2022-05-12T09:57:55.915026Z","iopub.status.idle":"2022-05-12T09:58:43.234152Z","shell.execute_reply.started":"2022-05-12T09:57:55.914999Z","shell.execute_reply":"2022-05-12T09:58:43.233149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# initialize our sequential data augmentation pipeline for training\ntrainAug = Sequential([\n    preprocessing.Rescaling(scale=1.0 / 255),\n    preprocessing.RandomFlip(\"horizontal_and_vertical\"),\n    preprocessing.RandomZoom(\n        height_factor=(-0.05, -0.15),\n        width_factor=(-0.05, -0.15)),\n    preprocessing.RandomRotation(0.3)\n])\n# initialize a second data augmentation pipeline for testing (this\n# one will only do pixel intensity rescaling\ntestAug = Sequential([\n    preprocessing.Rescaling(scale=1.0 / 255)\n])","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:58:43.236198Z","iopub.execute_input":"2022-05-12T09:58:43.236536Z","iopub.status.idle":"2022-05-12T09:58:43.257727Z","shell.execute_reply.started":"2022-05-12T09:58:43.236493Z","shell.execute_reply":"2022-05-12T09:58:43.256763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prepare the training data pipeline (notice how the augmentation\n# layers have been mapped)\ntrainDS = tf.data.Dataset.from_tensor_slices((trainX, trainLabels))\ntrainDS = (\n    trainDS\n    .shuffle(BATCH_SIZE * 100)\n    .batch(BATCH_SIZE)\n    .map(lambda x, y: (trainAug(x), y),num_parallel_calls=tf.data.AUTOTUNE)\n    .prefetch(tf.data.AUTOTUNE)\n)\n# create our testing data pipeline (notice this time that we are\n# *not* apply data augmentation)\ntestDS = tf.data.Dataset.from_tensor_slices((testX, testLabels))\ntestDS = (\n    testDS\n    .batch(BATCH_SIZE)\n    .map(lambda x, y: (testAug(x), y),num_parallel_calls=tf.data.AUTOTUNE)\n    .prefetch(tf.data.AUTOTUNE)\n)","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:59:11.841514Z","iopub.execute_input":"2022-05-12T09:59:11.842002Z","iopub.status.idle":"2022-05-12T09:59:13.108057Z","shell.execute_reply.started":"2022-05-12T09:59:11.841969Z","shell.execute_reply":"2022-05-12T09:59:13.107118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# initialize the model as a super basic CNN with only a single CONV\n# and RELU layer, followed by a FC and soft-max classifier\nprint(\"[INFO] initializing model...\")\nmodel = Sequential()\n# CONV => RELU => POOL\nmodel.add(Conv2D(32, (3, 3), padding=\"same\",input_shape=(32, 32, 3)))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n# (CONV => RELU => POOL) * 2\nmodel.add(Conv2D(64, (3, 3), padding=\"same\"))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization())\nmodel.add(Conv2D(64, (3, 3), padding=\"same\"))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n# first (and only) set of FC => RELU layers\nmodel.add(Flatten())\nmodel.add(Dense(256))\nmodel.add(Activation(\"relu\"))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.5))\n# softmax classifier        \nmodel.add(Dense(10))\nmodel.add(Activation(\"softmax\"))","metadata":{"execution":{"iopub.status.busy":"2022-05-12T09:59:53.508792Z","iopub.execute_input":"2022-05-12T09:59:53.50912Z","iopub.status.idle":"2022-05-12T09:59:53.659104Z","shell.execute_reply.started":"2022-05-12T09:59:53.509082Z","shell.execute_reply":"2022-05-12T09:59:53.658416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# compile the model\nprint(\"[INFO] compiling model...\")\nmodel.compile(loss=\"sparse_categorical_crossentropy\",optimizer=\"sgd\", metrics=[\"accuracy\"])\n# train the model\nprint(\"[INFO] training model...\")\nH = model.fit(\n    trainDS,\n    validation_data=testDS,\n    epochs=EPOCHS)\n# show the accuracy on the testing set\n(loss, accuracy) = model.evaluate(testDS)\nprint(\"[INFO] accuracy: {:.2f}%\".format(accuracy * 100))","metadata":{"execution":{"iopub.status.busy":"2022-05-12T10:01:40.039627Z","iopub.execute_input":"2022-05-12T10:01:40.039915Z","iopub.status.idle":"2022-05-12T10:03:23.436009Z","shell.execute_reply.started":"2022-05-12T10:01:40.039885Z","shell.execute_reply":"2022-05-12T10:03:23.434909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_training(H, N, plotPath):\n    %matplotlib inline\n    # construct a plot that plots and saves the training history\n    fig, (accuracy, loss) = plt.subplots(1, 2)\n    fig.suptitle('Training Loss and Accuracy')\n    fig.tight_layout()\n    \n    plt.subplots_adjust(wspace = 0.5)\n    plt.style.use(\"ggplot\")\n    plt.figure()\n    \n    loss.plot(np.arange(0, N), H.history[\"loss\"], label=\"train_loss\")\n    loss.plot(np.arange(0, N), H.history[\"val_loss\"], label=\"val_loss\")\n    loss.set_title('Training Loss')\n    loss.set_xlabel('Epoch #')\n    loss.set_ylabel('Loss')\n    loss.legend(loc=\"upper right\")\n    \n    accuracy.plot(np.arange(0, N), H.history[\"accuracy\"], label=\"train_acc\")\n    accuracy.plot(np.arange(0, N), H.history[\"val_accuracy\"], label=\"val_acc\")\n    accuracy.set_title('Training Accuracy')\n    accuracy.set_xlabel('Epoch #')\n    accuracy.set_ylabel('Accuracy')\n    accuracy.legend(loc=\"lower right\")","metadata":{"execution":{"iopub.status.busy":"2022-05-12T10:03:23.438162Z","iopub.execute_input":"2022-05-12T10:03:23.438596Z","iopub.status.idle":"2022-05-12T10:03:23.452827Z","shell.execute_reply.started":"2022-05-12T10:03:23.438551Z","shell.execute_reply":"2022-05-12T10:03:23.452188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_training(H, EPOCHS, \"None\")","metadata":{"execution":{"iopub.status.busy":"2022-05-12T10:03:38.640026Z","iopub.execute_input":"2022-05-12T10:03:38.64031Z","iopub.status.idle":"2022-05-12T10:03:39.092026Z","shell.execute_reply.started":"2022-05-12T10:03:38.640282Z","shell.execute_reply":"2022-05-12T10:03:39.091041Z"},"trusted":true},"execution_count":null,"outputs":[]}]}