{"cells":[{"metadata":{},"cell_type":"markdown","source":"A comparison of accuracy with and without data augmentation using CNN on the dogs vs cats dataset","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport tensorflow as tf\nimport sklearn\nimport os\nimport sys\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nimport cv2\nfrom keras.preprocessing.image import img_to_array\nfrom PIL import Image\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D\nfrom keras.layers import MaxPooling2D\nfrom keras.layers import Flatten\nfrom keras.layers import Dense\nfrom keras.layers import Dropout\nfrom keras import backend as K\nfrom keras.layers import BatchNormalization\nimport zipfile\n\nwith zipfile.ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \nwith zipfile.ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\".\")\n\n\ncategories = [\"cat\", \"dog\"]\ndata_dir = \"/kaggle/working/train\"\nIMG_SIZE = 64\n\ndef create_img_array(data_dir):  # function that creates a 3D array holding the images\n    img_array_list = []\n    label_list = []\n    path = data_dir\n        \n    for img in tqdm(os.listdir(path)):\n            \n        try:  # some of the images have error \n            if img.startswith('cat'):\n                img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE) \n                img_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))\n                img_array = img_to_array(img_array)\n                img_array_list.append(img_array)\n                label_list.append(0) # cats labelled 0\n                \n            elif img.startswith('dog'):\n                img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)\n                img_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))\n                img_array = img_to_array(img_array)\n                img_array_list.append(img_array)\n                label_list.append(1) # dogs labelled 1\n                \n                \n        except Exception as e:\n            print(str(e))\n            \n    return img_array_list, label_list\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"img, labels = create_img_array(data_dir) \nimg = np.asarray(img) # convert the list with img arrays to array\nlabels = np.array(labels) # convert list with labels to array","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.utils import to_categorical  # encode the labels using one hot encoding\nlabels = to_categorical(labels, num_classes = 2)\nlabels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split # random split into train test data\n\ntrain_x, test_x, train_y, test_y = train_test_split(img, labels, random_state = 42, test_size = 0.2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train_x.shape)\nprint(train_y.shape)\nprint(test_x.shape)\nprint(test_y.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_x = train_x.astype('float32')/255.0 # normalise the pixel values to between [0, 1] works better on CNN\ntest_x = test_x.astype('float32') / 255.0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nK.common.image_dim_ordering() == 'th'\nmodel.add(Conv2D(128, (3, 3), input_shape = (IMG_SIZE, IMG_SIZE, 1), activation = 'relu')) \nmodel.add(MaxPooling2D(pool_size = (2, 2))) # pooling is to reduce the size of the images as much as possible, downsampling\nmodel.add(Dropout(0.2))# dropout is a regularization technique to reduce overfitting, by giving each node a probability of being dropped\nmodel.add(Conv2D(128, (3, 3), activation = 'relu'))\nmodel.add(MaxPooling2D(pool_size = (2, 2))) \nmodel.add(Dropout(0.2))\nmodel.add(Conv2D(128, (3, 3), activation = 'relu'))\nmodel.add(MaxPooling2D(pool_size = (2, 2)))\nmodel.add(Dropout(0.2))\nmodel.add(Flatten())# get 1D array to feed into the Dense layer\nmodel.add(Dense(units = 512, activation = 'tanh'))\nmodel.add(Dropout(0.2))\nmodel.add(Dense(units = 256, activation = 'tanh'))\nmodel.add(Dropout(0.2))\nmodel.add(Dense(units = 2, activation = 'softmax'))\nmodel.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"### chose to run just 10 epochs due to time, could have ran up to 50 epochs to get better results \nmodel_results = model.fit(train_x, train_y, epochs = 10, batch_size = 64, validation_data = (test_x, test_y), verbose = 1)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"score, acc = model.evaluate(test_x, test_y, batch_size = 64)\nprint(acc)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred = model.predict(test_x) # can see model's prediction perccentages on whether image is cat or dog\npred","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(model_results.history['accuracy'])\nplt.plot(model_results.history['val_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epochs')\nplt.legend(['train', 'val'], loc = 'upper left')\nplt.show()\n\n# the larger the training accuracy compared to val_accuracy, the greater the overfitting problem","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(model_results.history['loss'])\nplt.plot(model_results.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epochs')\nplt.legend(['train', 'val'], loc = 'upper left')\nplt.show()\n\n# If you have loss noticeably lower than val_loss it is the sign of overfitting.\n# A model that is underfit will have high training and high testing error while an overfit model\n# will have extremely low training error but a high testing error.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* Data Augmentation ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\ntrain_x, test_x, train_y, test_y = train_test_split(img, labels, test_size = 0.2)\ntrain_x = train_x.astype('float32')/255.0 # normalise the pixel values to between [0, 1] works better on CNN\ntest_x = test_x.astype('float32') / 255.0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = ImageDataGenerator(rotation_range = 40, height_shift_range = 0.2, width_shift_range = 0.2,horizontal_flip = True) \n\n# need to know which augmentations are relevant to the data\ntrain_generator.fit(train_x)\n\ntrain_generator = train_generator.flow(train_x, train_y, batch_size = 64, shuffle = False)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit_generator(train_generator, steps_per_epoch = len(train_x) / 64,epochs = 15, validation_data = \n                   (test_x, test_y))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pred = model.predict(test_x)\npred","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"score, acc = model.evaluate(test_x, test_y, batch_size = 64)\nprint(acc) # accuracy with data augmentation","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(model_results.history['accuracy'])\nplt.plot(model_results.history['val_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epochs')\nplt.legend(['train', 'val'], loc = 'upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(model_results.history['loss'])\nplt.plot(model_results.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epochs')\nplt.legend(['train', 'val'], loc = 'upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}