{"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 \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\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\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.\n\n#Importing some packages to use\nimport cv2\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport random\nimport gc #Garbage collection\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\n\ntest_imgs = ['../input/test/{}'.format(i) for i in os.listdir(test_dir)] #get test images\n\ntrain_imgs = train_dogs[:2000] + train_cats[:2000] #slice the dataset and use 2000 in each class\nrandom.shuffle(train_imgs) #shuffle the training images randomly\n\n#Clear list that are useless\ndel train_dogs\ndel train_cats\ngc.collect() #Garbage collection to save memory\n\nimport matplotlib.image as mping\nfor ima in train_imgs[0:5]:\n    img=mping.imread(ima)\n    imgplot = plt.imshow(img)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"#Declare image dimensions\nnrows = 150\nncolumns = 150\nchannels = 3 #change to 1 if you're using greyscale\n\n#A function to read and process the images to an acceptable format for our model\ndef read_and_process_image(list_of_images):\n    '''\n    Returns two arrays:\n        X is an array of resized images\n        Y is an array of labels\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))\n        #get the labels\n        if 'dog' in image:\n            y.append(1)\n        elif 'cat' in image:\n            y.append(0)\n            \n    return X, y\n    \nX, y = read_and_process_image(train_imgs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7733b3c39caefc26cf3165c307ac0d5f491e47ff"},"cell_type":"code","source":"plt.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])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"adb97c2b8471fd0708075d73380165f36019f802"},"cell_type":"code","source":"import seaborn as sns\ndel train_imgs\ngc.collect()\n\n#Convert list to numpy array\nX = np.array(X)\ny = np.array(y)\n\n#Plot the label to be sure of the dataset\nsns.countplot(y)\nplt.title('Labels for cats and dogs')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e416c0da79777c6f33abf5d8282ffadc67ede5f5"},"cell_type":"code","source":"print(\"Shape of train images is:\", X.shape)\nprint(\"Shape of labels is:\", y.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3804458593ae1dc1ac4cd669854021daf6263283"},"cell_type":"code","source":"#Split the data set into training and validation set\nfrom sklearn.model_selection import train_test_split\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=2)\n\nprint(\"Shape of train images is:\", X_train.shape)\nprint(\"Shape of validation images is:\", X_val.shape)\nprint(\"Shape of train labels is:\", y_train.shape)\nprint(\"Shape of test labels is:\", y_val.shape)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e7eaa4644770d17a4c3d9b53a88103480b83c2e5"},"cell_type":"code","source":"#clear memory\ndel X\ndel y\ngc.collect()\n\n#get the length of the train and validation data\nntrain = len(X_train)\nnval = len(X_val)\n\n#Use batch size as 32. Note batch size should be a multiple of 2\nbatch_size = 32","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"797504af0536e2ececcef9f94e638d209348ce41"},"cell_type":"code","source":"from keras import layers, models, optimizers\nfrom keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"91a8434f917b927af8c1693aca399ce376d47718"},"cell_type":"code","source":"model = models.Sequential()\nmodel.add(layers.Conv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)))\nmodel.add(layers.MaxPooling2D((2,2)))\nmodel.add(layers.Conv2D(64, (3,3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2,2)))\nmodel.add(layers.Conv2D(128, (3,3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2,2)))\nmodel.add(layers.Conv2D(512, (3,3), activation='relu'))\nmodel.add(layers.MaxPooling2D((2,2)))\nmodel.add(layers.Flatten())\nmodel.add(layers.Dropout(0.5)) #dropout for regularization\nmodel.add(layers.Dense(512, activation='relu'))\nmodel.add(layers.Dense(1, activation='sigmoid'))  #sigmoid function at the end because we have just two classes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cedc09c0a2eaeb69c5f83b1c2f07738d4fc2de2f"},"cell_type":"code","source":"#See our model\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"23de194e278552e10a9a05c012d328d1ec28649d"},"cell_type":"code","source":"#We'll use the RMSprop optimizer with a learning rate of 0.0001\n#We'll use binary_crossentropy loss because its a binary classification\nmodel.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"687915ff4599274a45140fa478971ac2b7cd9a45"},"cell_type":"code","source":"#Create the augmentation configuration\n#This helps to prevent overfitting, since we are using a small dataset\ntrain_datagen = ImageDataGenerator(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                                    zoom_range=0.2,\n                                    horizontal_flip=True,)\nval_datagen = ImageDataGenerator(rescale=1./255) #We do not augment validation data, we only perform rescale","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ce34fe67afa16e64ae4bc6a672d9e93580d6afd5"},"cell_type":"code","source":"#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)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1be746d77b6c118eaae90d373360f43e1cb226d4","scrolled":false},"cell_type":"code","source":"#The Training part\n#We train for 64 epochs with about 100 steps per epoch\nhistory = model.fit_generator(train_generator,\n                               steps_per_epoch=ntrain // batch_size,\n                               epochs=64,\n                               validation_data=val_generator,\n                               validation_steps=nval // batch_size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e5b63328e760b6873f50be23d1c6e41be859b069"},"cell_type":"code","source":"#Save the model\n\nmodel.save_weights('model_weights.h5')\nmodel.save('model_keras.h5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"819bf3bd5115dc82029bdb582f5a50c1e60063a2"},"cell_type":"code","source":"#Plot the train and val curve\nacc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\n#Train and validation accuracy\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()\n\nplt.figure()\n#Train and validation loss\nplt.plot(epochs, loss, 'b', label='Training loss')\nplt.plot(epochs, val_loss, 'r', label='Validation loss')\nplt.title('Training and Validation loss')\nplt.legend()\n\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ae3889fc1c9830859a2d7c69a226869b67aba80b"},"cell_type":"code","source":"#Lets predict on the first 10 Images of the test set\nX_test, y_test = read_and_process_image(test_imgs[0:10]) #Y_test will be empty in this case\nx = np.array(X_test)\ntest_datagen = ImageDataGenerator(rescale=1./255)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3e4a235a6587a1edfba4f4b29220a3fe0a044742"},"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    i += 1\n    if i % 10 == 0:\n        break\nplt.show()","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}