{"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 zipfile\n\n\ntrain_path = \"../input/dogs-vs-cats-redux-kernels-edition/train.zip\"\ntest_path = \"../input/dogs-vs-cats-redux-kernels-edition/test.zip\"\n\nwith zipfile.ZipFile(train_path, \"r\") as train_zip_ref:\n    train_zip_ref.extractall(\".\")\n\nwith zipfile.ZipFile(test_path, \"r\") as test_zip_ref:\n    test_zip_ref.extractall(\".\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom os import listdir\n\n\ntrain_df = pd.DataFrame(listdir(\"train\"), columns=[\"file_path\"])\ntrain_df[\"target\"] = np.array(train_df[\"file_path\"].str.split(\".\").tolist())[:, 0]\ntrain_df[\"file_path\"] = \"train/\" + train_df[\"file_path\"]\n\ntest_df = pd.DataFrame(listdir(\"test\"), columns=[\"file_path\"])\ntest_df[\"file_path\"] = \"test/\" + test_df[\"file_path\"]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"TRAIN DATASET\")\ntrain_df.head(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"TEST DATASET\")\ntest_df.head(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"TRAINING DATASET INFO\")\nprint(\"---------------------\")\nprint(train_df.info())\nprint()\n\nprint(\"TARGET DISTRIBUTION\")\nprint(\"-------------------\")\nprint(train_df[\"target\"].value_counts())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Data input pipeline using ImageDataGenerator\nimport tensorflow as tf\nfrom sklearn.model_selection import train_test_split\n\n\ntrain_data, val_data = train_test_split(train_df, test_size=0.2, random_state=42, stratify=train_df[\"target\"])\n\nBATCH_SIZE = 128\nIMG_HEIGHT = 224\nIMG_WIDTH = 224\n\ndatagen = tf.keras.preprocessing.image.ImageDataGenerator()\n\ntrain_datagen = datagen.flow_from_dataframe(\n    dataframe=train_data,\n    directory=\".\",\n    x_col=\"file_path\",\n    y_col=\"target\",\n    target_size=(IMG_HEIGHT, IMG_WIDTH),\n    class_mode=\"binary\",\n    batch_size=BATCH_SIZE\n)\n\nval_datagen = datagen.flow_from_dataframe(\n    dataframe=val_data,\n    directory=\".\",\n    x_col=\"file_path\",\n    y_col=\"target\",\n    target_size=(IMG_HEIGHT, IMG_WIDTH),\n    class_mode=\"binary\",\n    batch_size=BATCH_SIZE\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\n\n\nenc = LabelEncoder()\ntrain_df[\"target\"] = enc.fit_transform(train_df[\"target\"])\n\nlabels = zip(enc.classes_, enc.transform(enc.classes_))\n\nfor ctgry, label in labels:\n    print(f\"Class = {ctgry} Label = {label}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Data input pipeline using tf.data\ndef read_train_images(X, y):\n    X = tf.io.read_file(X)\n    X = tf.io.decode_jpeg(X, channels=3)\n    X = tf.image.resize(X, [IMG_HEIGHT, IMG_WIDTH])\n\n    return (X, y)\n\n\ndef read_test_images(X):\n    X = tf.io.read_file(X)\n    X = tf.io.decode_jpeg(X, channels=3)\n    X = tf.image.resize(X, [IMG_HEIGHT, IMG_WIDTH])\n\n    return X\n\n\ndef build_data_pipeline(X, y=None):\n    if y is None:\n        tf_data = tf.data.Dataset.from_tensor_slices(X).shuffle(1000)\n        tf_data = tf_data.map(read_test_images, num_parallel_calls=tf.data.AUTOTUNE)\n    else:\n        tf_data = tf.data.Dataset.from_tensor_slices((X, y)).shuffle(1000)\n        tf_data = tf_data.map(read_train_images, num_parallel_calls=tf.data.AUTOTUNE)\n\n    tf_data = tf_data.batch(BATCH_SIZE)\n    tf_data = tf_data.prefetch(tf.data.AUTOTUNE)\n\n    return tf_data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data, val_data = train_test_split(train_df, test_size=0.2, random_state=42, stratify=train_df[\"target\"])\n\n\ntrain_tfdata = build_data_pipeline(train_data[\"file_path\"], train_data[\"target\"])\nval_tfdata = build_data_pipeline(val_data[\"file_path\"], val_data[\"target\"])\ntest_tfdata = build_data_pipeline(test_df[\"file_path\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Printing the first 10 images\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\n\nplt.style.use(\"seaborn\")\n\nfig, ax = plt.subplots(nrows=2, ncols=5, figsize=(20, 10))\nax = np.array(ax).ravel()\n\nfor image in train_tfdata.take(1):\n    for i in range(10):\n        img = image[0][i]/255.0\n        ax[i].imshow(img)\n        ax[i].axis(\"off\")\n        ax[i].grid(\"off\")\n\n        if image[1][i] == 0:\n            ax[i].set_title(\"cat\")\n        else:\n            ax[i].set_title(\"dog\")\n\nfig.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Modelling with simple Feed Forward Neural Networks with MobileNetV2 as feature extractor\ndef build_model():\n    pretrained_model = tf.keras.applications.EfficientNetB0(\n        input_shape=(IMG_HEIGHT, IMG_WIDTH, 3),\n        include_top=False,\n        weights=\"imagenet\",\n        pooling=\"avg\"\n    )\n\n    pretrained_model.trainable = False\n\n    model = tf.keras.Sequential([\n        pretrained_model,\n        tf.keras.layers.BatchNormalization(),\n        tf.keras.layers.Dense(units=1, activation=\"sigmoid\")\n    ])\n\n    model.compile(\n        optimizer=\"adam\",\n        loss=\"binary_crossentropy\",\n        metrics=[\"accuracy\"]\n    )\n\n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"build_model().summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(\n    monitor=\"val_loss\",\n    factor=0.5,\n    patience=2,\n    mode=\"min\",\n    verbose=1\n)\n\nearly_stop = tf.keras.callbacks.EarlyStopping(\n    monitor=\"val_loss\",\n    patience=7,\n    restore_best_weights=True,\n    mode=\"min\",\n    verbose=1\n)\n\ncallbacks = [reduce_lr, early_stop]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model training with data generated using tf.data\nfrom time import time\n\n\nstart = time()\nmodel_tfdata = build_model()\n\nhistory_tfdata = model_tfdata.fit(\n    x=train_tfdata,\n    epochs=20,\n    callbacks=callbacks,\n    validation_data=val_tfdata\n)\n\nprint(f\"\\nTime taken for training with tf.data = {time() - start} seconds\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model training with data generated using ImageDataGenerator\nmodel_datagen = build_model()\n\nstart = time()\nhistory_datagen = model_datagen.fit(\n    x=train_datagen,\n    epochs=20,\n    validation_data=val_datagen,\n    callbacks=callbacks\n)\n\nprint(f\"\\nTime taken for training with ImageDataGenerator = {time() - start} seconds\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_model_history(history):\n    fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(20, 5))\n    ax = np.array(ax).ravel()\n\n    ax[0].plot(history.history[\"loss\"], label=\"train loss\", color=\"orange\")\n    ax[0].plot(history.history[\"val_loss\"], label=\"val loss\", color=\"green\")\n    ax[0].set_xlabel(\"Epochs\")\n    ax[0].set_ylabel(\"Loss\")\n    ax[0].set_title(\"Loss vs Epochs\")\n    ax[0].legend()\n\n    ax[1].plot(history.history[\"accuracy\"], label=\"train accuracy\", color=\"orange\")\n    ax[1].plot(history.history[\"val_accuracy\"], label=\"val accuracy\", color=\"green\")\n    ax[1].set_xlabel(\"Epochs\")\n    ax[1].set_ylabel(\"Accuracy\")\n    ax[1].set_title(\"Accuracy vs Epochs\")\n    ax[1].legend()\n\n    fig.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_model_history(history_tfdata)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_model_history(history_datagen)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred_tfdata = model_tfdata.predict(test_tfdata)\n\ntest_datagen = datagen.flow_from_dataframe(\n    dataframe=test_df,\n    directory=\".\",\n    x_col=\"file_path\",\n    target_size=(IMG_HEIGHT, IMG_WIDTH),\n    class_mode=None,\n    batch_size=BATCH_SIZE\n)\n\ny_pred_datagen = model_datagen.predict(test_datagen)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df[\"target\"] = (y_pred_tfdata + y_pred_datagen)/2\ntest_df.to_csv(\"submission_blend.csv\", index=False)\ntest_df.head(10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}