{"cells":[{"metadata":{},"cell_type":"markdown","source":"In this kernel I try CNN to distinguish between cats and dogs.\n"},{"metadata":{},"cell_type":"markdown","source":"> ## 1. Import Libraries"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# data load\nimport zipfile\nimport cv2\nfrom keras.preprocessing.image import ImageDataGenerator, load_img\n\nimport random\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# making pictures\nimport matplotlib.pyplot as plt\n\n# CNN\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Flatten, Dropout, Activation, Conv2D, MaxPooling2D\n\nimport os","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"> ## 2. Prepare Train Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(os.listdir(\"../input\"))\nprint(os.listdir(\"../input/dogs-vs-cats\"))\n\npath = \"../input/dogs-vs-cats/\"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's unzip the data first:"},{"metadata":{"trusted":true},"cell_type":"code","source":"with zipfile.ZipFile(path + \"train.zip\",\"r\") as z:\n    z.extractall(\".\")\nwith zipfile.ZipFile(path + \"test1.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \n# saved as output to \"/kaggle/working/train\" and \"/kaggle/working/test1\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path_train = \"/kaggle/working/train/\"\nfilenames = os.listdir(path_train)\nis_dog = []\nfor filename in filenames:\n    category = filename.split('.')[0]\n    if category == 'dog':\n        is_dog.append(1)\n    else:\n        is_dog.append(0)\n\ndf = pd.DataFrame({\n    'filename': filenames,\n    'is_dog': is_dog\n})","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"To verify that we read the labels correctly:"},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### 2.1 Brief Look at the Data"},{"metadata":{},"cell_type":"markdown","source":"We have (about) equal number of cats and dogs in the train sample:"},{"metadata":{"trusted":true},"cell_type":"code","source":"df['is_dog'].value_counts().plot.bar();","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Sample picture:"},{"metadata":{"trusted":true},"cell_type":"code","source":"image = load_img(path_train + random.choice(filenames))\nplt.imshow(image);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### 2.2 Images to Arrays****"},{"metadata":{},"cell_type":"markdown","source":"Let's use cv2 library to read images into arrays:"},{"metadata":{"trusted":true},"cell_type":"code","source":"X = []\ny = []\nconvert = lambda category : int(category == 'dog')\ndef read_train_data(path):\n    for pic in os.listdir(path):\n        category = pic.split(\".\")[0]\n        is_dog = convert(category)\n        img_array = cv2.imread(os.path.join(path,pic), cv2.IMREAD_GRAYSCALE)\n        new_img_array = cv2.resize(img_array, dsize=(80, 80))\n        X.append(new_img_array)\n        y.append(is_dog)\n\nread_train_data(path_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X = np.array(X).reshape(-1, 80,80, 1)\ny = np.array(y)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Check if the shapes are matching:"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(X.shape)\nprint(y.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Gray scale pictures often work better than coloured, so let's normalize them:"},{"metadata":{"trusted":true},"cell_type":"code","source":"X = X/255.0  # from 0-255 to 0-1 scale","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"> ## 3. Train the Model\n\nBasic model from https://www.kaggle.com/ruchibahl18/cats-vs-dogs-basic-cnn-tutorial/notebook\n\n1. First we will add a Conv2D layer with 64 nodes and kernel size of (3,3). You can also experiment with different values here like 32, 128 etc. Also we have to specify input shape which is your X shape. Activation we will take 'relu' for now however there are many others to experiment with.\n2. Now after every Conv layer we always do max pooling so we will add max pooling layer with a size of (2,2)\n3. We will repeat this combination again because come on 2 is better than one. Haha. We you can also add 3 or more convolution layers but keep in mind the more layers you add more time it will take to train.\n4. But we don't have much time so we will add a flatten layer now. As we have to feed our data to Dense layer later.\n5. We will now add a Dense layer of 64 nodes. Note for all these layers we are using activation as 'relu' because I found results better with this. You can skip specifying activation but this might make a model a conveniently linear which might not work for us.\n6. In the end for getting our result we will add final Dense layer . Activation can be sigmoid or softmax (if you need probability use sigmoid else use softmax). Here I have used sigmoid.\n7. Finally we will compile the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\n# Adds a densely-connected layer with 64 units to the model:\nmodel.add(Conv2D(64,(3,3), activation = 'relu', input_shape = X.shape[1:]))\nmodel.add(MaxPooling2D(pool_size = (2,2)))\n# Add another:\nmodel.add(Conv2D(64,(3,3), activation = 'relu'))\nmodel.add(MaxPooling2D(pool_size = (2,2)))\n\nmodel.add(Flatten())\nmodel.add(Dense(64, activation='relu'))\n# Add a softmax layer with 10 output units:\nmodel.add(Dense(1, activation='sigmoid'))\n\nmodel.compile(optimizer=\"adam\",\n              loss='binary_crossentropy',\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit(X, y, epochs=10, batch_size=32, validation_split=0.2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"> ## 4. Make Predictions\n### 4.1 Prepare test data"},{"metadata":{"trusted":true},"cell_type":"code","source":"path_test = \"/kaggle/working/test1/\"\n\nX_test = []\nid_line = []\ndef read_test1_data(path):\n    for pic in os.listdir(path):\n        id_line.append(pic.split(\".\")[0])\n        img_array = cv2.imread(os.path.join(path,pic), cv2.IMREAD_GRAYSCALE)\n        new_img_array = cv2.resize(img_array, dsize=(80, 80))\n        X_test.append(new_img_array)\nread_test1_data(path_test)\nX_test = np.array(X_test).reshape(-1,80,80,1)\nX_test = X_test/255","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### 4.2 Predict, Generate Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions = model.predict(X_test)\npredicted_val = [int(round(p[0])) for p in predictions]\nsubmission_df = pd.DataFrame({'id':id_line, 'label':predicted_val})\nsubmission_df.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for pic in os.listdir(path_test):\n    os.remove(path_test + pic)\nfor pic in os.listdir(path_train):\n    os.remove(path_train + pic)","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}