{"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":"1. Import libraries\n2. Manually create training data (No ImageDataGenerator or tf.data used here, for practice)\n3. Initialize Keras model \n4. Initialize callbacks\n5. Compile, fit and validate model\n6. Visualize model training parameters\n7. Manually create test data\n8. Predict labels\n9. Create submission file","metadata":{}},{"cell_type":"markdown","source":"## 1. Import libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Input, Flatten, Dense, Dropout, Conv2D, MaxPooling2D\nimport zipfile\nimport cv2\n# from tensorflow.python.keras\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-12-15T10:26:55.240421Z","iopub.execute_input":"2021-12-15T10:26:55.240769Z","iopub.status.idle":"2021-12-15T10:26:55.250980Z","shell.execute_reply.started":"2021-12-15T10:26:55.240732Z","shell.execute_reply":"2021-12-15T10:26:55.249894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filenames = os.listdir('../input/dogs-vs-cats')\nprint(filenames)","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:26:55.252924Z","iopub.execute_input":"2021-12-15T10:26:55.253541Z","iopub.status.idle":"2021-12-15T10:26:55.259714Z","shell.execute_reply.started":"2021-12-15T10:26:55.253493Z","shell.execute_reply":"2021-12-15T10:26:55.258817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with zipfile.ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\".\")\nwith zipfile.ZipFile(\"../input/dogs-vs-cats/test1.zip\",\"r\") as z:\n    z.extractall(\".\")\nprint('Images extracted!')","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:26:55.260848Z","iopub.execute_input":"2021-12-15T10:26:55.261286Z","iopub.status.idle":"2021-12-15T10:27:10.133249Z","shell.execute_reply.started":"2021-12-15T10:26:55.261245Z","shell.execute_reply":"2021-12-15T10:27:10.132362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The train and test directories are extracted in the current working directory\nprint(os.listdir(\"/kaggle/working/train\")[:10])","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:10.135063Z","iopub.execute_input":"2021-12-15T10:27:10.135589Z","iopub.status.idle":"2021-12-15T10:27:10.159578Z","shell.execute_reply.started":"2021-12-15T10:27:10.135537Z","shell.execute_reply":"2021-12-15T10:27:10.158500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = \"/kaggle/working/\"\ntrain_dir = \"train\"\npath = os.path.join(base_dir,train_dir)\n\nfor p in os.listdir(path):\n    category = p.split(\".\")[0]\n    img_array = cv2.imread(os.path.join(path,p),cv2.IMREAD_GRAYSCALE)\n    new_img_array = cv2.resize(img_array, dsize=(80, 80))\n    plt.imshow(new_img_array,cmap=\"gray\")\n    break","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:10.160864Z","iopub.execute_input":"2021-12-15T10:27:10.161192Z","iopub.status.idle":"2021-12-15T10:27:10.425250Z","shell.execute_reply.started":"2021-12-15T10:27:10.161162Z","shell.execute_reply":"2021-12-15T10:27:10.424338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Manually create training data","metadata":{}},{"cell_type":"code","source":"X = []\ny = []\nconvert = lambda category : int(category == 'dog')\ndef create_test_data(path):\n    for p in os.listdir(path):\n        category = p.split(\".\")[0]\n        category = convert(category)\n        img_array = cv2.imread(os.path.join(path,p),cv2.IMREAD_GRAYSCALE)\n        new_img_array = cv2.resize(img_array, dsize=(80, 80))\n        X.append(new_img_array)\n        y.append(category)","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:10.427737Z","iopub.execute_input":"2021-12-15T10:27:10.428070Z","iopub.status.idle":"2021-12-15T10:27:10.451063Z","shell.execute_reply.started":"2021-12-15T10:27:10.428025Z","shell.execute_reply":"2021-12-15T10:27:10.449654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Reshaping Image array to (batch_size, img height, img width, no. of channels) \n# as required by conv2d (no batches used here, so we write -1 for python to figure out the correct size dimension)\ncreate_test_data(path)\nX = np.array(X).reshape(-1, 80,80,1)\ny = np.array(y)","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:10.456783Z","iopub.execute_input":"2021-12-15T10:27:10.457261Z","iopub.status.idle":"2021-12-15T10:27:35.675003Z","shell.execute_reply.started":"2021-12-15T10:27:10.457219Z","shell.execute_reply":"2021-12-15T10:27:35.673968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Find number of instances of both classes in training data\nprint(X.shape)\nprint(y.shape)\ndf = pd.DataFrame({'class':y})\ndf.value_counts().plot.bar()","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:35.677875Z","iopub.execute_input":"2021-12-15T10:27:35.678411Z","iopub.status.idle":"2021-12-15T10:27:35.887140Z","shell.execute_reply.started":"2021-12-15T10:27:35.678355Z","shell.execute_reply":"2021-12-15T10:27:35.886514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Normalize data\nX = X/255.0","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:35.888681Z","iopub.execute_input":"2021-12-15T10:27:35.889173Z","iopub.status.idle":"2021-12-15T10:27:37.096877Z","shell.execute_reply.started":"2021-12-15T10:27:35.889129Z","shell.execute_reply":"2021-12-15T10:27:37.096004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print(X)\n# print(y)","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:37.101801Z","iopub.execute_input":"2021-12-15T10:27:37.102062Z","iopub.status.idle":"2021-12-15T10:27:37.106232Z","shell.execute_reply.started":"2021-12-15T10:27:37.102029Z","shell.execute_reply":"2021-12-15T10:27:37.105423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Initialize model","metadata":{}},{"cell_type":"code","source":"def initialize_model():\n    input = Input(shape=(80,80,1))\n    x = Conv2D(64,(3,3),activation='relu')(input)\n    x = MaxPooling2D(pool_size = (2,2))(x)\n    x = Conv2D(64,(3,3),activation='relu')(input)\n    x = MaxPooling2D(pool_size = (2,2))(x)\n    x = Flatten()(x)\n    x = Dense(64, activation='relu')(x)\n    x = Dense(1, activation='sigmoid')(x)\n    \n    return Model(inputs=input, outputs=x)","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:37.107413Z","iopub.execute_input":"2021-12-15T10:27:37.107650Z","iopub.status.idle":"2021-12-15T10:27:37.117943Z","shell.execute_reply.started":"2021-12-15T10:27:37.107623Z","shell.execute_reply":"2021-12-15T10:27:37.117055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = initialize_model()\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:37.119502Z","iopub.execute_input":"2021-12-15T10:27:37.120021Z","iopub.status.idle":"2021-12-15T10:27:37.324941Z","shell.execute_reply.started":"2021-12-15T10:27:37.119973Z","shell.execute_reply":"2021-12-15T10:27:37.324054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. Initialize callbacks","metadata":{}},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ReduceLROnPlateau\n\nearlystop = EarlyStopping(monitor='val_loss', patience=5)\nlearning_rate_reduction = ReduceLROnPlateau(monitor='val_loss', \n                                            patience=2, \n                                            verbose=1, \n                                            factor=0.5, \n                                            min_lr=0.00001)\ncallbacks = [earlystop, learning_rate_reduction]","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:37.326129Z","iopub.execute_input":"2021-12-15T10:27:37.326345Z","iopub.status.idle":"2021-12-15T10:27:37.332286Z","shell.execute_reply.started":"2021-12-15T10:27:37.326319Z","shell.execute_reply":"2021-12-15T10:27:37.331460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5. Compile, fit and validate model","metadata":{}},{"cell_type":"code","source":"model.compile(optimizer=\"adam\",\n              loss='binary_crossentropy',\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:37.333826Z","iopub.execute_input":"2021-12-15T10:27:37.334514Z","iopub.status.idle":"2021-12-15T10:27:37.354267Z","shell.execute_reply.started":"2021-12-15T10:27:37.334470Z","shell.execute_reply":"2021-12-15T10:27:37.353620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(X, y, epochs=10, batch_size=32, validation_split=0.2, callbacks=callbacks)","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:27:37.355371Z","iopub.execute_input":"2021-12-15T10:27:37.355627Z","iopub.status.idle":"2021-12-15T10:34:36.511214Z","shell.execute_reply.started":"2021-12-15T10:27:37.355596Z","shell.execute_reply":"2021-12-15T10:34:36.510525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 6. Visualize model training parameters","metadata":{}},{"cell_type":"code","source":"print(history.history.keys())","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:34:36.512477Z","iopub.execute_input":"2021-12-15T10:34:36.513172Z","iopub.status.idle":"2021-12-15T10:34:36.518512Z","shell.execute_reply.started":"2021-12-15T10:34:36.513134Z","shell.execute_reply":"2021-12-15T10:34:36.517624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Summarize history for accuracy\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('Model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['acc','val_acc'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:34:36.520033Z","iopub.execute_input":"2021-12-15T10:34:36.520506Z","iopub.status.idle":"2021-12-15T10:35:01.529247Z","shell.execute_reply.started":"2021-12-15T10:34:36.520463Z","shell.execute_reply":"2021-12-15T10:35:01.528143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Summarize history for loss\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['loss','val_loss'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:35:01.530636Z","iopub.execute_input":"2021-12-15T10:35:01.530896Z","iopub.status.idle":"2021-12-15T10:35:01.745810Z","shell.execute_reply.started":"2021-12-15T10:35:01.530864Z","shell.execute_reply":"2021-12-15T10:35:01.744799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 7. Manually create test data","metadata":{}},{"cell_type":"code","source":"test_dir = \"test1\"\npath = os.path.join(base_dir,test_dir)\n\nX_test = []\nid_line = []\n\ndef create_test1_data(path):\n    for p in os.listdir(path):\n        id_line.append(p.split(\".\")[0])\n        img_array = cv2.imread(os.path.join(path,p),cv2.IMREAD_GRAYSCALE)\n        new_img_array = cv2.resize(img_array, dsize=(80, 80))\n        X_test.append(new_img_array)\n        \ncreate_test1_data(path)\nX_test = np.array(X_test).reshape(-1,80,80,1)\nX_test = X_test/255","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:35:01.747592Z","iopub.execute_input":"2021-12-15T10:35:01.748137Z","iopub.status.idle":"2021-12-15T10:35:14.637965Z","shell.execute_reply.started":"2021-12-15T10:35:01.748087Z","shell.execute_reply":"2021-12-15T10:35:14.637016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8. Predict labels","metadata":{}},{"cell_type":"code","source":"predictions = model.predict(X_test)\npredictions","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:35:14.639190Z","iopub.execute_input":"2021-12-15T10:35:14.639440Z","iopub.status.idle":"2021-12-15T10:35:21.602328Z","shell.execute_reply.started":"2021-12-15T10:35:14.639409Z","shell.execute_reply":"2021-12-15T10:35:21.601688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Rounding predictions to 0 or 1\npredicted_val = [int(round(p[0])) for p in predictions]\nprint(predicted_val[:10])","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:35:21.603293Z","iopub.execute_input":"2021-12-15T10:35:21.603980Z","iopub.status.idle":"2021-12-15T10:35:21.643452Z","shell.execute_reply.started":"2021-12-15T10:35:21.603935Z","shell.execute_reply":"2021-12-15T10:35:21.642572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 9. Create submission file","metadata":{}},{"cell_type":"code","source":"# Create submission file\nsubmission_df = pd.DataFrame({'id':id_line, 'label':predicted_val})\nsubmission_df.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-15T10:35:21.644945Z","iopub.execute_input":"2021-12-15T10:35:21.645440Z","iopub.status.idle":"2021-12-15T10:35:21.685164Z","shell.execute_reply.started":"2021-12-15T10:35:21.645406Z","shell.execute_reply":"2021-12-15T10:35:21.684167Z"},"trusted":true},"execution_count":null,"outputs":[]}]}