{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Dogs vs Cats","metadata":{}},{"cell_type":"markdown","source":"## 1. Importing Necessary Libraries","metadata":{}},{"cell_type":"code","source":"# utilities\nimport numpy as np # linear algebra\nimport pandas as pd # data processing\nimport pickle\nimport random\n\n# visualization\nimport cv2\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# sklearn\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix\n\n# tensorflow\nimport tensorflow as tf\n\nfrom tensorflow.keras import Sequential\nfrom tensorflow.keras.layers import Dense, Flatten, Dropout, Conv2D, MaxPooling2D\n\nfrom tensorflow.keras.regularizers import l2\nfrom keras.preprocessing.image import ImageDataGenerator\n\n# ignoring warnings\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport os\nprint(os.listdir(\"../input\"))","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:53:28.972364Z","iopub.execute_input":"2021-08-26T09:53:28.972878Z","iopub.status.idle":"2021-08-26T09:53:35.965152Z","shell.execute_reply.started":"2021-08-26T09:53:28.972793Z","shell.execute_reply":"2021-08-26T09:53:35.963884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Preprocessing","metadata":{}},{"cell_type":"markdown","source":"### Extracting zip files","metadata":{}},{"cell_type":"code","source":"from zipfile import ZipFile\n\nwith ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \nwith ZipFile(\"../input/dogs-vs-cats/test1.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \n#print(os.listdir(\"/kaggle/working/train\"))","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:53:35.968597Z","iopub.execute_input":"2021-08-26T09:53:35.968940Z","iopub.status.idle":"2021-08-26T09:53:55.533720Z","shell.execute_reply.started":"2021-08-26T09:53:35.968909Z","shell.execute_reply":"2021-08-26T09:53:55.532631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Turning train images to numpy arrays","metadata":{}},{"cell_type":"code","source":"path = \"/kaggle/working/train\"\n\nX = []\ny = []\n\n# if dog, label it as 1\nconvert = lambda category : int(category == 'dog')\n\n# this function read the unzipped images and appends them to X and y array\ndef create_train_data(path):\n    for p in os.listdir(path):\n        category = p.split(\".\")[0]\n        category = convert(category)\n        img = cv2.imread(os.path.join(path, p), cv2.IMREAD_GRAYSCALE)\n        img_np = cv2.resize(img, dsize = (80, 80))\n        X.append(img_np)\n        y.append(category)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:53:55.535956Z","iopub.execute_input":"2021-08-26T09:53:55.536281Z","iopub.status.idle":"2021-08-26T09:53:55.546973Z","shell.execute_reply.started":"2021-08-26T09:53:55.536252Z","shell.execute_reply":"2021-08-26T09:53:55.543572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_train_data(path)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:53:55.550270Z","iopub.execute_input":"2021-08-26T09:53:55.551144Z","iopub.status.idle":"2021-08-26T09:54:22.338924Z","shell.execute_reply.started":"2021-08-26T09:53:55.551099Z","shell.execute_reply":"2021-08-26T09:54:22.337784Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Reshaping the data to be used","metadata":{}},{"cell_type":"markdown","source":"#### We reshape the X array in order to use in Convolutional Neural Network Layers.","metadata":{}},{"cell_type":"code","source":"X = np.array(X).reshape(-1,80,80,1)\ny = np.array(y)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:22.340586Z","iopub.execute_input":"2021-08-26T09:54:22.341043Z","iopub.status.idle":"2021-08-26T09:54:22.439508Z","shell.execute_reply.started":"2021-08-26T09:54:22.340998Z","shell.execute_reply":"2021-08-26T09:54:22.438440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Saving the arrays and downloading it, so we can use later","metadata":{}},{"cell_type":"markdown","source":"#### We can save the X and y array if we don't want to deal with them. And we can download it.","metadata":{}},{"cell_type":"code","source":"pickle.dump(X, open(\"x_train\", \"wb\"))\npickle.dump(y, open(\"y_train\", \"wb\"))\n\nos.chdir(r'../working')\nfrom IPython.display import FileLink\nFileLink(r'y_train')","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:22.441242Z","iopub.execute_input":"2021-08-26T09:54:22.441737Z","iopub.status.idle":"2021-08-26T09:54:22.712973Z","shell.execute_reply.started":"2021-08-26T09:54:22.441693Z","shell.execute_reply":"2021-08-26T09:54:22.711638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Let's look at some images","metadata":{}},{"cell_type":"markdown","source":"#### Here we create a 0 to 24999 number list.","metadata":{}},{"cell_type":"code","source":"num_list = list(range(25000))","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:22.714873Z","iopub.execute_input":"2021-08-26T09:54:22.715344Z","iopub.status.idle":"2021-08-26T09:54:22.720651Z","shell.execute_reply.started":"2021-08-26T09:54:22.715298Z","shell.execute_reply":"2021-08-26T09:54:22.719461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Here we chose random number from the list.","metadata":{}},{"cell_type":"code","source":"i = random.choice(num_list)\nplt.imshow(X[i], cmap = \"gray\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:37.156961Z","iopub.execute_input":"2021-08-26T09:54:37.157338Z","iopub.status.idle":"2021-08-26T09:54:37.397435Z","shell.execute_reply.started":"2021-08-26T09:54:37.157306Z","shell.execute_reply":"2021-08-26T09:54:37.396300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### A dog","metadata":{}},{"cell_type":"code","source":"i = random.choice(num_list)\nplt.imshow(X[i], cmap = \"gray\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:40.180365Z","iopub.execute_input":"2021-08-26T09:54:40.180800Z","iopub.status.idle":"2021-08-26T09:54:40.542649Z","shell.execute_reply.started":"2021-08-26T09:54:40.180770Z","shell.execute_reply":"2021-08-26T09:54:40.541061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### A cat","metadata":{}},{"cell_type":"markdown","source":"### Normalizing","metadata":{}},{"cell_type":"markdown","source":"#### Here we normalize the data so it converges faster to global minima.","metadata":{}},{"cell_type":"code","source":"X = X / 255","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:43.996350Z","iopub.execute_input":"2021-08-26T09:54:43.996777Z","iopub.status.idle":"2021-08-26T09:54:44.613507Z","shell.execute_reply.started":"2021-08-26T09:54:43.996747Z","shell.execute_reply":"2021-08-26T09:54:44.612370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Splitting data to train and validation set","metadata":{}},{"cell_type":"markdown","source":"#### Here we split the data to train and validation data.","metadata":{}},{"cell_type":"code","source":"X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:46.550292Z","iopub.execute_input":"2021-08-26T09:54:46.550682Z","iopub.status.idle":"2021-08-26T09:54:47.039884Z","shell.execute_reply.started":"2021-08-26T09:54:46.550652Z","shell.execute_reply":"2021-08-26T09:54:47.038742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train.shape, X_val.shape, y_train.shape, y_val.shape","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:47.041619Z","iopub.execute_input":"2021-08-26T09:54:47.042072Z","iopub.status.idle":"2021-08-26T09:54:47.049924Z","shell.execute_reply.started":"2021-08-26T09:54:47.042026Z","shell.execute_reply":"2021-08-26T09:54:47.048655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Modeling and Predicting","metadata":{}},{"cell_type":"markdown","source":"#### Here we are constructing our CNN layers. We use Conv2D, MaxPooling2D, Dropout, Flatten and Dense layers.","metadata":{}},{"cell_type":"code","source":"model = Sequential([\n    Conv2D(32, (3,3), activation = \"relu\", input_shape = (80,80,1)),\n    Conv2D(32, (3,3), activation = \"relu\"),\n    MaxPooling2D(2,2),\n    Dropout(0.4),\n    Conv2D(64, (3,3), activation = \"relu\"),\n    Conv2D(64, (3,3), activation = \"relu\"),\n    MaxPooling2D(2,2),\n    Dropout(0.4),\n    Conv2D(128, (3,3), activation = \"relu\"),\n    Conv2D(128, (3,3), activation = \"relu\"),\n    MaxPooling2D(2,2),\n    Dropout(0.4),\n    Flatten(),\n    Dense(128, activation = \"relu\", kernel_regularizer = l2(0.001)),\n    Dropout(0.5),\n    Dense(1, activation = \"sigmoid\")\n])","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:48.446748Z","iopub.execute_input":"2021-08-26T09:54:48.447150Z","iopub.status.idle":"2021-08-26T09:54:51.094233Z","shell.execute_reply.started":"2021-08-26T09:54:48.447119Z","shell.execute_reply":"2021-08-26T09:54:51.093059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Here we set compiler configurations.","metadata":{}},{"cell_type":"code","source":"model.compile(optimizer = \"adam\", loss = \"binary_crossentropy\", metrics = [\"accuracy\"])","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:51.095960Z","iopub.execute_input":"2021-08-26T09:54:51.096371Z","iopub.status.idle":"2021-08-26T09:54:51.116574Z","shell.execute_reply.started":"2021-08-26T09:54:51.096327Z","shell.execute_reply":"2021-08-26T09:54:51.115358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Here we save the history of fitting the data.","metadata":{}},{"cell_type":"code","source":"history = model.fit(X_train, y_train, batch_size = 256, epochs = 50, verbose = 1, validation_data = (X_val, y_val))","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:54:51.819228Z","iopub.execute_input":"2021-08-26T09:54:51.819658Z","iopub.status.idle":"2021-08-26T09:59:10.293282Z","shell.execute_reply.started":"2021-08-26T09:54:51.819628Z","shell.execute_reply":"2021-08-26T09:59:10.291988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Let's see the accuracy.","metadata":{}},{"cell_type":"code","source":"_, accuracy = model.evaluate(X_val, y_val)\nprint(\"Accuracy: %.2f\" % (accuracy*100))","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:10.295988Z","iopub.execute_input":"2021-08-26T09:59:10.296435Z","iopub.status.idle":"2021-08-26T09:59:11.236051Z","shell.execute_reply.started":"2021-08-26T09:59:10.296394Z","shell.execute_reply":"2021-08-26T09:59:11.235041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Let's visualize model accuracy and model loss.","metadata":{}},{"cell_type":"code","source":"plt.plot(history.history[\"accuracy\"])\nplt.plot(history.history[\"val_accuracy\"])\nplt.title(\"Model accuracy\")\nplt.ylabel(\"Accuracy\")\nplt.xlabel(\"Epoch\")\nplt.legend([\"Train\", \"Test\"], loc = \"upper left\")\nplt.show()\n\nplt.plot(history.history[\"loss\"])\nplt.plot(history.history[\"val_loss\"])\nplt.title(\"Model loss\")\nplt.ylabel(\"Loss\")\nplt.xlabel(\"Epoch\")\nplt.legend([\"Train\", \"Test\"], loc = \"upper left\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:11.238726Z","iopub.execute_input":"2021-08-26T09:59:11.239254Z","iopub.status.idle":"2021-08-26T09:59:11.614897Z","shell.execute_reply.started":"2021-08-26T09:59:11.239214Z","shell.execute_reply":"2021-08-26T09:59:11.613590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Let's see the confusion matrix.","metadata":{}},{"cell_type":"code","source":"sns.heatmap(confusion_matrix(model.predict_classes(X_val), y_val), cmap = \"viridis\", annot = True)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:11.616919Z","iopub.execute_input":"2021-08-26T09:59:11.617329Z","iopub.status.idle":"2021-08-26T09:59:12.575255Z","shell.execute_reply.started":"2021-08-26T09:59:11.617287Z","shell.execute_reply":"2021-08-26T09:59:12.574160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### It's time to predict the test data. Almost the same function with train function.","metadata":{}},{"cell_type":"code","source":"test_path = \"/kaggle/working/test1\"\n\nX_test = []\nid_line = []\n\n\ndef create_test_data(path):\n    for p in os.listdir(path):\n        id_line.append(p.split(\".\")[0])\n        img = cv2.imread(os.path.join(path, p), cv2.IMREAD_GRAYSCALE)\n        img_np = cv2.resize(img, dsize = (80, 80))\n        X_test.append(img_np)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:12.577156Z","iopub.execute_input":"2021-08-26T09:59:12.577753Z","iopub.status.idle":"2021-08-26T09:59:12.585616Z","shell.execute_reply.started":"2021-08-26T09:59:12.577695Z","shell.execute_reply":"2021-08-26T09:59:12.583936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"create_test_data(test_path)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:12.587480Z","iopub.execute_input":"2021-08-26T09:59:12.588094Z","iopub.status.idle":"2021-08-26T09:59:24.951915Z","shell.execute_reply.started":"2021-08-26T09:59:12.588052Z","shell.execute_reply":"2021-08-26T09:59:24.950798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Reshaping","metadata":{}},{"cell_type":"code","source":"X_test = np.array(X_test).reshape(-1,80,80,1)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:24.953596Z","iopub.execute_input":"2021-08-26T09:59:24.954029Z","iopub.status.idle":"2021-08-26T09:59:25.008570Z","shell.execute_reply.started":"2021-08-26T09:59:24.953986Z","shell.execute_reply":"2021-08-26T09:59:25.007491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Normalizing","metadata":{}},{"cell_type":"code","source":"X_test = X_test / 255","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:25.011567Z","iopub.execute_input":"2021-08-26T09:59:25.012176Z","iopub.status.idle":"2021-08-26T09:59:25.320855Z","shell.execute_reply.started":"2021-08-26T09:59:25.012136Z","shell.execute_reply":"2021-08-26T09:59:25.319411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Predicting Classes","metadata":{}},{"cell_type":"code","source":"pred = model.predict_classes(X_test)\npred = pred.flatten()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:25.323034Z","iopub.execute_input":"2021-08-26T09:59:25.324081Z","iopub.status.idle":"2021-08-26T09:59:27.171509Z","shell.execute_reply.started":"2021-08-26T09:59:25.324035Z","shell.execute_reply":"2021-08-26T09:59:27.169788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Saving to DataFrame","metadata":{}},{"cell_type":"code","source":"df = pd.DataFrame({\"id\": id_line, \"label\": pred})","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:27.179273Z","iopub.execute_input":"2021-08-26T09:59:27.179714Z","iopub.status.idle":"2021-08-26T09:59:27.193759Z","shell.execute_reply.started":"2021-08-26T09:59:27.179672Z","shell.execute_reply":"2021-08-26T09:59:27.192460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Saving the DataFrame","metadata":{}},{"cell_type":"code","source":"df.to_csv(\"result.csv\", index = False)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:27.197686Z","iopub.execute_input":"2021-08-26T09:59:27.198254Z","iopub.status.idle":"2021-08-26T09:59:27.230170Z","shell.execute_reply.started":"2021-08-26T09:59:27.198187Z","shell.execute_reply":"2021-08-26T09:59:27.229264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Let's look at some images and predict them","metadata":{}},{"cell_type":"code","source":"def predict_class(to_predict):\n    to_predict = to_predict.reshape(1,80,80,1)\n    pred = model.predict_classes(to_predict)\n    plt.imshow(to_predict.reshape(80,80,1), \"gray\")\n    plt.show()\n    if pred[0] == 1:\n        return \"dog\"\n    else:\n        return \"cat\"","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:27.231744Z","iopub.execute_input":"2021-08-26T09:59:27.232279Z","iopub.status.idle":"2021-08-26T09:59:27.239262Z","shell.execute_reply.started":"2021-08-26T09:59:27.232226Z","shell.execute_reply":"2021-08-26T09:59:27.237543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_class(X_test[30])","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:40.430918Z","iopub.execute_input":"2021-08-26T09:59:40.431322Z","iopub.status.idle":"2021-08-26T09:59:40.705326Z","shell.execute_reply.started":"2021-08-26T09:59:40.431291Z","shell.execute_reply":"2021-08-26T09:59:40.704199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_class(X_test[2532])","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:59:43.157072Z","iopub.execute_input":"2021-08-26T09:59:43.157420Z","iopub.status.idle":"2021-08-26T09:59:43.374862Z","shell.execute_reply.started":"2021-08-26T09:59:43.157390Z","shell.execute_reply":"2021-08-26T09:59:43.373844Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}