{"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":"code","source":"import os\nimport cv2\nimport zipfile\n\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\n\nfrom tqdm import tqdm\nfrom matplotlib import pyplot as plt\nfrom sklearn.model_selection import train_test_split","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-20T07:21:37.243105Z","iopub.execute_input":"2022-05-20T07:21:37.243473Z","iopub.status.idle":"2022-05-20T07:21:43.208666Z","shell.execute_reply.started":"2022-05-20T07:21:37.243388Z","shell.execute_reply":"2022-05-20T07:21:43.207797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TEST_SIZE = 0.2\nRANDOM_STATE = 42\nBATCH_SIZE = 64\nEPOCHS = 20\nPATH = '/kaggle/input/dogs-vs-cats-redux-kernels-edition/'\nTRAIN_FOLDER = './train/'\nTEST_FOLDER =  './test/'\nIMG_SIZE = 224","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:21:43.210565Z","iopub.execute_input":"2022-05-20T07:21:43.210845Z","iopub.status.idle":"2022-05-20T07:21:43.219534Z","shell.execute_reply.started":"2022-05-20T07:21:43.210800Z","shell.execute_reply":"2022-05-20T07:21:43.218542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data_path = os.path.join(PATH, \"train.zip\")\ntest_data_path = os.path.join(PATH, \"test.zip\")","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:21:43.223144Z","iopub.execute_input":"2022-05-20T07:21:43.223660Z","iopub.status.idle":"2022-05-20T07:21:43.230638Z","shell.execute_reply.started":"2022-05-20T07:21:43.223629Z","shell.execute_reply":"2022-05-20T07:21:43.229741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# extract train dataset\nwith zipfile.ZipFile(train_data_path,\"r\") as z:\n    z.extractall()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:21:43.233393Z","iopub.execute_input":"2022-05-20T07:21:43.234004Z","iopub.status.idle":"2022-05-20T07:21:56.247784Z","shell.execute_reply.started":"2022-05-20T07:21:43.233962Z","shell.execute_reply":"2022-05-20T07:21:56.246982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# extract test dataset\nwith zipfile.ZipFile(test_data_path,\"r\") as z:\n    z.extractall()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:21:56.249761Z","iopub.execute_input":"2022-05-20T07:21:56.250346Z","iopub.status.idle":"2022-05-20T07:22:03.379873Z","shell.execute_reply.started":"2022-05-20T07:21:56.250304Z","shell.execute_reply":"2022-05-20T07:22:03.376108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def one_hot_encoder(image_path):\n    return 1 if image_path[:3] == 'dog' else 0\n\ndef imageprocess(image):\n    image = cv2.resize(image, (IMG_SIZE, IMG_SIZE), cv2.INTER_CUBIC)\n    return image\n\ndef procces_data(data_folder):\n    data_image_list = os.listdir(data_folder)\n    X, y = [], []\n    for image_path in tqdm(data_image_list):\n        img = cv2.imread(os.path.join(data_folder, image_path))\n        X.append(imageprocess(img))\n        y.append(one_hot_encoder(image_path))\n    return X, y\n\ndef show_images(imgs, isTrain=False, model=None):\n    f, ax = plt.subplots(nrows = 5, ncols = 5, figsize = (15,15))\n    for i, img in enumerate(imgs[:25]):\n        ax[i//5, i%5].imshow(img)\n        ax[i//5, i%5].axis('off')\n        if isTrain:\n            img = imageprocess(img)\n            img = img.reshape(-1,IMG_SIZE,IMG_SIZE,3)\n            pred = model.predict(img)\n            str_label = 'dog' if pred > 0.5 else 'cat'\n            ax[i//5, i%5].set_title(\"Label: {}\".format(str_label))\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:22:03.386306Z","iopub.execute_input":"2022-05-20T07:22:03.386701Z","iopub.status.idle":"2022-05-20T07:22:03.407960Z","shell.execute_reply.started":"2022-05-20T07:22:03.386657Z","shell.execute_reply":"2022-05-20T07:22:03.405964Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X, y = procces_data(TRAIN_FOLDER)\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=TEST_SIZE, random_state=RANDOM_STATE)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:22:03.412972Z","iopub.execute_input":"2022-05-20T07:22:03.413372Z","iopub.status.idle":"2022-05-20T07:23:02.067418Z","shell.execute_reply.started":"2022-05-20T07:22:03.413330Z","shell.execute_reply":"2022-05-20T07:23:02.066585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizing Training Set","metadata":{}},{"cell_type":"code","source":"show_images(X)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:23:02.068729Z","iopub.execute_input":"2022-05-20T07:23:02.069205Z","iopub.status.idle":"2022-05-20T07:23:03.681417Z","shell.execute_reply.started":"2022-05-20T07:23:02.069163Z","shell.execute_reply":"2022-05-20T07:23:03.680563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model","metadata":{}},{"cell_type":"code","source":"resnet50 = tf.keras.applications.ResNet50(\n    include_top=False,\n    weights=\"imagenet\",\n    pooling=\"max\",\n    input_shape=(IMG_SIZE, IMG_SIZE, 3)\n)\n\nmodel_resnet50 = tf. keras.models.Sequential()\nmodel_resnet50.add(resnet50)\nmodel_resnet50.add(tf.keras.layers.Dense(1, activation='sigmoid'))\n\nopt = tf.keras.optimizers.SGD()\nloss = tf.keras.losses.BinaryCrossentropy()\nmetrics = ['accuracy']\n\nmodel_resnet50.compile(optimizer=opt, loss=loss, metrics=metrics)\n\nmodel_resnet50.summary()","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:47:12.922484Z","iopub.execute_input":"2022-05-20T07:47:12.922846Z","iopub.status.idle":"2022-05-20T07:47:14.853925Z","shell.execute_reply.started":"2022-05-20T07:47:12.922803Z","shell.execute_reply":"2022-05-20T07:47:14.853163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data generator","metadata":{}},{"cell_type":"code","source":"class DataGenerator(tf.keras.utils.Sequence):\n    'Generates data for Keras'\n    def __init__(\n            self, \n            images_paths, \n            labels, \n            batch_size=64, \n        ):\n        self.labels = labels\n        self.images_paths = images_paths \n        self.batch_size = batch_size\n        self.on_epoch_end()\n\n\n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        return int(np.floor(len(self.images_paths) / self.batch_size))\n\n    def on_epoch_end(self):\n        'Updates indexes after each epoch'\n        self.indexes = np.arange(len(self.images_paths))\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        indexes = self.indexes[index * self.batch_size: (index + 1) * self.batch_size]\n        labels = np.array([self.labels[k] for k in indexes])\n        images = np.array([self.images_paths[k].astype('float32') for k in indexes])\n        return images, labels\n","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:47:37.460987Z","iopub.execute_input":"2022-05-20T07:47:37.461264Z","iopub.status.idle":"2022-05-20T07:47:37.470443Z","shell.execute_reply.started":"2022-05-20T07:47:37.461234Z","shell.execute_reply":"2022-05-20T07:47:37.469637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = DataGenerator(\n    images_paths=X_train, \n    labels=y_train, \n    batch_size=BATCH_SIZE, \n)\nval_data = DataGenerator(\n    images_paths=X_test, \n    labels=y_test, \n    batch_size=BATCH_SIZE, \n)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T07:47:38.802067Z","iopub.execute_input":"2022-05-20T07:47:38.802639Z","iopub.status.idle":"2022-05-20T07:47:38.807376Z","shell.execute_reply.started":"2022-05-20T07:47:38.802600Z","shell.execute_reply":"2022-05-20T07:47:38.806380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train and visualizing loss and accuracy curves","metadata":{}},{"cell_type":"code","source":"checkpoint = tf.keras.callbacks.ModelCheckpoint(\n    './cat_dogs_resnet50_checkpoint.hdf5',\n    monitor='val_loss',\n    verbose=1,\n    save_best_only=True,\n    mode='min',\n    save_weights_only=True\n)\n\nhistory = model_resnet50.fit_generator(\n    generator=train_data,\n    validation_data=val_data,\n    epochs=EPOCHS,\n    steps_per_epoch=len(train_data),\n    validation_steps=len(val_data),\n    #callbacks=[checkpoint],\n)\nmodel_resnet50.save_weights('./cat_dogs_resnet50.hdf5')","metadata":{"execution":{"iopub.status.busy":"2022-05-20T08:12:53.333780Z","iopub.execute_input":"2022-05-20T08:12:53.334390Z","iopub.status.idle":"2022-05-20T08:32:08.297705Z","shell.execute_reply.started":"2022-05-20T08:12:53.334350Z","shell.execute_reply":"2022-05-20T08:32:08.296974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_accuracy_and_loss(train_model):\n    hist = train_model.history.history\n    acc = hist['accuracy']\n    val_acc = hist['val_accuracy']\n    loss = hist['loss']\n    val_loss = hist['val_loss']\n    epochs = range(len(acc))\n    f, ax = plt.subplots(1,2, figsize=(14,6))\n    ax[0].plot(epochs, acc, 'g', label='Training accuracy')\n    ax[0].plot(epochs, val_acc, 'r', label='Validation accuracy')\n    ax[0].set_title('Training and validation accuracy')\n    ax[0].legend()\n    ax[1].plot(epochs, loss, 'g', label='Training loss')\n    ax[1].plot(epochs, val_loss, 'r', label='Validation loss')\n    ax[1].set_title('Training and validation loss')\n    ax[1].legend()\n    plt.show()\nplot_accuracy_and_loss(model_resnet50)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T08:35:28.086545Z","iopub.execute_input":"2022-05-20T08:35:28.086822Z","iopub.status.idle":"2022-05-20T08:35:28.445654Z","shell.execute_reply.started":"2022-05-20T08:35:28.086790Z","shell.execute_reply":"2022-05-20T08:35:28.444922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"score = model_resnet50.evaluate(val_data, verbose=0)\nprint('Validation accuracy:', score[1])","metadata":{"execution":{"iopub.status.busy":"2022-05-20T08:35:36.653062Z","iopub.execute_input":"2022-05-20T08:35:36.653355Z","iopub.status.idle":"2022-05-20T08:35:47.068919Z","shell.execute_reply.started":"2022-05-20T08:35:36.653323Z","shell.execute_reply":"2022-05-20T08:35:47.068083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizing predictions","metadata":{}},{"cell_type":"code","source":"show_images(\n    [cv2.imread(os.path.join(TEST_FOLDER, image_path)) for image_path in os.listdir(TEST_FOLDER)[:25]],\n    isTrain=True,\n    model=model_resnet50\n)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T08:35:47.070448Z","iopub.execute_input":"2022-05-20T08:35:47.071004Z","iopub.status.idle":"2022-05-20T08:35:49.948276Z","shell.execute_reply.started":"2022-05-20T08:35:47.070963Z","shell.execute_reply":"2022-05-20T08:35:49.945590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_list = []\nimg_list = []\nfor image_path in tqdm(os.listdir(TEST_FOLDER)):\n    image = cv2.imread(os.path.join(TEST_FOLDER, image_path))\n    image = imageprocess(image).astype('float32')\n    image = image.reshape(-1,IMG_SIZE,IMG_SIZE,3)\n    pred = model_resnet50.predict(image)[0]\n    pred_list.append(pred[0])\n    img_list.append(image_path[:-4])","metadata":{"execution":{"iopub.status.busy":"2022-05-20T08:35:49.949462Z","iopub.execute_input":"2022-05-20T08:35:49.950199Z","iopub.status.idle":"2022-05-20T08:46:06.777954Z","shell.execute_reply.started":"2022-05-20T08:35:49.950156Z","shell.execute_reply":"2022-05-20T08:46:06.777155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({'id':img_list , 'label':pred_list})\nsubmission['id'] = submission['id'].astype(int)\nsubmission = submission.sort_values(by=['id'])\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2022-05-20T08:46:06.779941Z","iopub.execute_input":"2022-05-20T08:46:06.780401Z","iopub.status.idle":"2022-05-20T08:46:06.833147Z","shell.execute_reply.started":"2022-05-20T08:46:06.780362Z","shell.execute_reply":"2022-05-20T08:46:06.832415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}