{"cells":[{"metadata":{"_uuid":"c0b172f2b866af35fff3490a880a6d605be96e69"},"cell_type":"markdown","source":"#Cats vs. Dogs Kernel"},{"metadata":{"_uuid":"189797fdf3642bb4ef3ef47f84f5c2e50ad5418a"},"cell_type":"markdown","source":"Welcome to my Kernel on the Cats vs Dogs competition. This is my first time working with image data so you will see various links that aided me in learning and completing this Kernel. The goal here is to use a Convolutional Neural Network (CNN) to predict if an image is a picture of a Cat or Dog and then evaluate how well the model did by using a validation set."},{"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 cv2\nimport os\nfrom random import shuffle\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D, MaxPool2D, Flatten\nimport matplotlib.pyplot as plt\n\n#The following code allows us to refer to the directories where the images are located.\n#This will help later when it comes time to load in the images and shape them.\nTrain_dir = '../input/train'\nTest_dir = '../input/test'\nIMG_SIZE = 100\n\n#Code that helped with loading in images and processing images can be found here https://www.youtube.com/watch?v=gT4F3HGYXf4&t=554s","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b181f855d30b7583a31ea2a6060125b11ee59e0e"},"cell_type":"markdown","source":"This was my first time working with true image data so the code for processing the image data in this Kernel is modeled after the code in the video below. Since this is my first time loading in image data in this matter, I will try to describe the code line by line.\n\nLink: https://www.youtube.com/watch?v=gT4F3HGYXf4"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"#The code below aids in labeling each image as \"cat\" or \"dog\"\n#The fuction below also labels the images as one-hot arrays\n#so that they can be passed through the CNN as output labels.\ndef label_img(img):\n    word_label = img.split('.')[0]\n    if word_label == 'cat':\n        return [1,0]\n    elif word_label == 'dog':\n        return [0,1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9e08d5ae5e58bb3422c9e932e4619dedfa437b40"},"cell_type":"code","source":"#The second line of the code above was confusing to me at first so I decided to\n#make a print statement that helped me to understand it better.\n#Running the print statement below shows that it grabs the text \n#that indicates if the picture is a cat or dog. It splits the image by '.'\n#and then takes the 0-ith object in the index which is \"cat\" or \"dog\".\nwords = 'cat.0.jpg'\nwords2 = words.split('.')[0]\nprint(words2)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"da59709ba11f25ecebcabbb0564adf85c595b0c9"},"cell_type":"markdown","source":"The code below is the function that will create our training data. Some notes will be included in the code to help break it down."},{"metadata":{"trusted":true,"_uuid":"5ec49e686320dcdd5c06c293a193eea6b679d103"},"cell_type":"code","source":"def create_train_data():\n    training_data = []\n    #os.listdir returns a list of all of the files and folders in the path\n    #So we pass the path to the training directory that we created earlier\n    #https://www.youtube.com/watch?v=iI2zR1WLPZ8\n    for img in os.listdir(Train_dir):\n        label = label_img(img)\n        #os.path.join seems to create a path to each individual image by\n        #combining the path to the training directory and the image name\n        #https://docs.python.org/3/library/os.path.html#os.path.join\n        path = os.path.join(Train_dir,img)\n        #The code below uses cv2 to read in the image in Grayscale and then resize\n        #the images to 100x100 which we created earlier with the variable IMG_SIZE\n        img = cv2.resize(cv2.imread(path, cv2.IMREAD_GRAYSCALE), (IMG_SIZE, IMG_SIZE))\n        #Appends the result of each image to a numpy array so we can work with it later\n        training_data.append([np.array(img), np.array(label)])\n        shuffle(training_data)\n    return training_data\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"840ccfeb6f6552872691dcd3ccf8e2491df646ce","scrolled":false},"cell_type":"code","source":"#Run function to get our training data\ntraining_data = create_train_data()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"670221986677bc09e4a89d19ad6378f86be08779"},"cell_type":"markdown","source":"The code below creates X and Y arrays to be passed into the model. X is reshaped to 100x100 and divided by 255 as a normalization technique. The model is then created and compiled; for more on the normalization techniques used and creating/ compiling CNNs I wrote an introduction to CNNs here: https://github.com/kasmith11/Intro-to-Convolution-Neural-Networks"},{"metadata":{"trusted":true,"_uuid":"4c19cb5bb64673fc800e43765c848e5dfc678205"},"cell_type":"code","source":"X = np.array([i[0] for i in training_data])\nX = X.reshape(-1,100,100,1)\nX = X/255\nY = np.array([i[1] for i in training_data])\n\nprint(X.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cab22c809624df192731cb5f3752e861b9fcded9"},"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(64, kernel_size = (3,3), input_shape=(100,100,1), activation = 'relu'))\nmodel.add(MaxPool2D(2,2))\nmodel.add(Flatten())\nmodel.add(Dense(64, activation = 'relu'))\nmodel.add(Dense(2, activation = 'softmax'))\nmodel.compile(optimizer='adam',\n              loss= 'binary_crossentropy',\n              metrics=['accuracy', 'mae'])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1fbcfc2bbf338f6eee352bb889c94c519565bede"},"cell_type":"markdown","source":"After creating and compiling the model, it is time to fit the data to the training set. We will use 30% of the training data as the validation set."},{"metadata":{"trusted":true,"_uuid":"7cf197ab48b95a247651bd44e9655686e57d8084"},"cell_type":"code","source":"Fit = model.fit(X, Y, epochs = 5, validation_split = 0.30)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"cc4f66fcd706caf8340999f424260aaae55d4359"},"cell_type":"markdown","source":"The plots below look at the models accuracy and loss overtime. Based on the graphs below, it seems that the model is overfitting the training data. This can be seen by the model preforming significantly worse on \"unseen\" validation samples. To improve this model in the future we can use things such as Dropout and other methods that help with over fitting. The links below helped with plotting and calling the accuracy and loss of the model.\n\nhttps://machinelearningmastery.com/display-deep-learning-model-training-history-in-keras/\n\nhttps://keras.io/callbacks/"},{"metadata":{"trusted":true,"_uuid":"750f0389a39ff20b32e6c004f226ccd9831d103b"},"cell_type":"code","source":"plt.plot(Fit.history['loss'])\nplt.plot(Fit.history['val_loss'])\nplt.ylabel('loss')\nplt.xlabel('epochs')\nplt.legend(['train', 'validation'], loc = 'upper left')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a42b88043a62f36b5114a965d2a6e19cfc48f745"},"cell_type":"code","source":"plt.plot(Fit.history['acc'])\nplt.plot(Fit.history['val_acc'])\nplt.ylabel('Accuracy')\nplt.xlabel('epochs')\nplt.legend(['train', 'validation'], loc = 'upper left')\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}