{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \nimport cv2  # It is used for all sorts of image and video analysis, like facial recognition and detection, \n            # license plate reading, photo editing, advanced robotic vision, optical character recognition, and a whole lot more..\nimport numpy as np # linear algebra\n                   # It makes working and computing large, multi-dimensional arrays and matrices super easy and fast.\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt #  It can be used for plotting lines, bar-chart, graphs, histograms and even displaying Images.\n# %matplotlib inline # makes our plots appear in the notebook.\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\nimport matplotlib.image as mpimg\nfrom sklearn.model_selection import train_test_split\nimport seaborn as sns\nimport os\nimport random\nimport gc #short for garbage collector is an important tool for manually cleaning and deleting unnecessary variables. \n\n# Necessary keras module\nfrom keras import layers\n# Here we import keras layers module which contains different types of layers used in deep learning such as:\n# ** Convolutional layer (Mostly used in computer vision)\n# ** Pooling layer (also used in computer vision)\n# ** Recurrent layer (Mostly used in sequential and time series modelling)\n# ** Embedding layers (Mostly used in Natural Language processing)\n# ** Normalization layers \n# ** and many more\nfrom keras import models\nfrom keras.layers import Input, Dropout, Flatten, Convolution2D, MaxPooling2D, Dense, Activation\nfrom keras import optimizers\n# Here we import keras optimizer, a module that contains different types of back propagation algorithm for training our model. Some of these optimizers are:\n# **sgd (stochastic gradient descent)\n# **rmsprop (root mean square propagation)\n# **Adams\n# **Adagrad\n# **Adadelta\n\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.preprocessing.image import img_to_array, load_img\n\n\nprint(os.listdir(\"../input\"))\n\ntrain_dir = '../input/train'\ntest_dir = '../input/test'\n\ntrain_dogs = ['../input/train/{}'.format(i) for i in os.listdir(train_dir) if 'dog' in i] # get dog images\ntrain_cats = ['../input/train/{}'.format(i) for i in os.listdir(train_dir) if 'cat' in i] # get cat images\ntest_images = ['../input/test/{}'.format(i) for i in os.listdir(test_dir)] # get test images\n\ntrain_images = train_dogs[:2000] + train_cats[:2000]\nrandom.shuffle(train_images)\ndel(train_dogs)\ndel(train_cats)\ngc.collect()\n\n# for ima in train_images[0:3]:\n#     img = mpimg.imread(ima)\n#     imaplot = plt.imshow(img)\n#     plt.show()\n    \nnrows = 150\nncolumns = 150\nchannels = 3\n\n# A function to read and process the image to an acceptable format for our model\ndef read_and_process_images(list_of_images):\n    \"\"\"\n    returns two arrays\n    x = is an array of resized image\n    y = is an array of labels\n    \"\"\"\n    \n    x = [] # images\n    y = [] # labels\n    \n    for image in list_of_images:\n        x.append(cv2.resize(cv2.imread(image, cv2.IMREAD_COLOR), (nrows, ncolumns), interpolation=cv2.INTER_CUBIC)) # cv2.resize(src, dim, interpolation = {})\n        if 'dog' in image:\n            y.append(1)\n        if 'cat' in image:\n            y.append(0)\n    return x, y\nX, Y = read_and_process_images(train_images)\nplt.figure(figsize=(20,10))\ncolumns = 5\nfor i in range(columns):\n    plt.subplot(5/columns+1, columns, i+1)\n    plt.imshow(X[i])\n    \ndel train_images\ngc.collect()\n#convert a list to numpy array\nX = np.array(X)\nY = np.array(Y)\nsns.countplot(Y)\nplt.title('Cats and Dogs')\nprint(\"Shape of X : \", X.shape)\nprint(\"Shape of Y : \", Y.shape)\n\nX_train, X_val,  Y_train, Y_val = train_test_split(X, Y, test_size=0.2, random_state=2)\nprint(\"Shape of X_Train : \", X_train.shape)\nprint(\"Shape of Y_train : \", Y_train.shape)\nprint(\"Shape of X_Val : \", X_val.shape)\nprint(\"Shape of Y_Val : \", Y_val.shape)\n\ndel X\ndel Y\ngc.collect()\n\n# get the length of the train and val data\nntrain = len(X_train)\nnval = len(X_val)\n\nbatch_size = 32\n\n# Model Creation\noptimizer = optimizers.RMSprop(lr=1e-4)\nobjective = 'binary_crossentropy'\n\ndef cats_and_dogs_model():\n    model = models.Sequential();\n    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))\n    model.add(layers.MaxPooling2D((2, 2)))\n    model.add(layers.Conv2D(64, (3,3), activation='relu'))\n    model.add(layers.MaxPooling2D((2, 2)))\n    model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n    model.add(layers.MaxPooling2D((2, 2)))\n    model.add(layers.Conv2D(256, (3,3), activation='relu'))\n#     model.add(layers.MaxPooling2D((2,2)))\n#     model.add(layers.Conv2D(512, (3,3), activation='relu'))\n    model.add(Flatten())\n    model.add(layers.Dropout(0.5))\n    model.add(layers.Dense(512, activation='relu'))\n    model.add(layers.Dense(1, activation='sigmoid'))\n    model.compile(loss=objective, optimizer=optimizer, metrics=['acc'])\n    model.summary()\n    return model\n\nmodel = cats_and_dogs_model()\n\n# Lets create the augmentation configuration\n# This helps preventing overfitting as we are using small datasets\ntrain_datagen = ImageDataGenerator(rescale=1./255, #Scale the image between 0 and 1\n#                                    We pass the rescale option to the ImageDataGenerator object. \n#                                    The rescale=1./255 option is a very IMPORTANT parameter. \n#                                    It normalizes the image pixel values to have zero mean and\n#                                    standard deviation of 1.\n#                                    It helps your model to generally learn and update its parameters efficiently.\n                                   rotation_range = 40,\n                                   width_shift_range=0.2,\n                                   height_shift_range=0.2,\n                                   shear_range=0.2,\n                                   zoom_range=0.2,\n                                   horizontal_flip=True\n)\n\nval_datagen = ImageDataGenerator(rescale=1./255)\nprint(train_datagen)\n\n#Create the Image Generators\ntrain_generator = train_datagen.flow(X_train, Y_train, batch_size=batch_size)\nval_generator = val_datagen.flow(X_val, Y_val, batch_size=batch_size)\n\nprint(ntrain, \" \", nval)\n# Train the model\nhistory = model.fit_generator(train_generator,\n                              steps_per_epoch=ntrain/batch_size,\n#                               Here we specify the number of steps per epoch. \n#                               This tells our model how many images we want to process before making a \n#                               gradient update to our loss function.\n#                               A total of 3200 images divided by batch size of 32 will give us 100 steps. \n#                               This means we going to make a total of 100 gradient update to our model in one pass through the entire training set.\n                              epochs=100,\n#                               An epoch is a full cycle or pass through the entire training set. \n#                               In our case, an epoch is reached when we make 100 gradient updates as specified by our \n#                               steps_per_epoch parameter.\n#                               Epochs = 64, means we want to go over our training data 64 times and \n#                               each time we will make gradient updates 100 times.\n                              validation_data=val_generator,\n                              validation_steps=nval/batch_size\n                             )\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Lets plot the train and val curve\n# get the details from the history object\n# After training a keras model, it always calculates and saves the metric \n# we specified when we compiled our model in a variable called history. \n# We can extract these values and plot them.\n# Note: The history object contains all the updates that happened during training.\nacc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\n# Here we simply get the size of our epoch from the number of values in the ‘acc’ list.\nepochs = range(1, len(acc)+1)\n\n# Train and validation accuracy\n# Here we plot the accuracy against the epoch size.\nplt.plot(epochs, acc, 'b', label='Training Accuracy')\nplt.plot(epochs, val_acc, 'r', label='Validation Accuracy')\nplt.title(\"Training and Validation Accuracy\")\nplt.legend\nplt.figure\n\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Train and Validation Loss\nplt.plot(epochs, loss, 'b', label='Trainning Loss')\nplt.plot(epochs, val_loss, 'r', label='Validation Loss')\nplt.title(\"Training and Validation Loss\")\nplt.legend\nplt.show","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Now lets predict on the first 10 images of test data\nx_test, y_test = read_and_process_images(test_images[0:10])\nx = np.array(x_test)\ntest_datagen = ImageDataGenerator(rescale=1./255)\nx","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"i=0\ntext_labels = []\nplt.figure(figsize=(30,20))\nfor batch in test_datagen.flow(x, batch_size=1):\n    pred = model.predict(batch)\n    if pred>0.5:\n        text_labels.append('dog')\n    else:\n        text_labels.append('cat')\n    plt.subplot(5/columns+1, columns, i+1)\n    plt.title(\"this is a \" + text_labels[i])\n    imgplot = plt.imshow(batch[0])\n    \n    print(pred)\n    i = i+1;\n    if i&10 == 0:\n        break\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}