{"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 matplotlib.pyplot as plt\nimport numpy as np\nimport os, shutil\nimport tensorflow as tf\nimport pandas as pd","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-09-17T15:36:59.971866Z","iopub.execute_input":"2023-09-17T15:36:59.972271Z","iopub.status.idle":"2023-09-17T15:36:59.977583Z","shell.execute_reply.started":"2023-09-17T15:36:59.972226Z","shell.execute_reply":"2023-09-17T15:36:59.976164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Follow from this [tutorial](https://www.tensorflow.org/tutorials/images/transfer_learning)","metadata":{}},{"cell_type":"code","source":"BATCH_SIZE = 32\nIMG_SIZE = (160, 160)\n","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:36:59.980014Z","iopub.execute_input":"2023-09-17T15:36:59.981006Z","iopub.status.idle":"2023-09-17T15:36:59.991085Z","shell.execute_reply.started":"2023-09-17T15:36:59.980980Z","shell.execute_reply":"2023-09-17T15:36:59.990133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Change Directory Structure","metadata":{}},{"cell_type":"code","source":"labels_df = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')\nunique_labels = labels_df['breed'].value_counts().index","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:36:59.992127Z","iopub.execute_input":"2023-09-17T15:36:59.992461Z","iopub.status.idle":"2023-09-17T15:37:00.021162Z","shell.execute_reply.started":"2023-09-17T15:36:59.992435Z","shell.execute_reply":"2023-09-17T15:37:00.020275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for label in unique_labels:\n    try :\n        os.makedirs('train/'+label)\n    except FileExistsError:\n        pass\n    \n    for file_name in labels_df[labels_df['breed'] == label]['id']:\n        try:\n            shutil.copyfile('/kaggle/input/dog-breed-identification/train/'+file_name+'.jpg',\n                        'train/'+label+'/'+file_name+'.jpg')\n        except shutil.SameFileError:\n            pass    \n\n\ntry:\n    shutil.copytree('/kaggle/input/dog-breed-identification/test', 'test/test') \nexcept FileExistsError:\n    pass\n\n","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:00.022766Z","iopub.execute_input":"2023-09-17T15:37:00.023461Z","iopub.status.idle":"2023-09-17T15:37:12.820023Z","shell.execute_reply.started":"2023-09-17T15:37:00.023428Z","shell.execute_reply":"2023-09-17T15:37:12.819010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare Data","metadata":{}},{"cell_type":"code","source":"train_dataset = tf.keras.utils.image_dataset_from_directory(\n  'train',\n  validation_split=0.2,\n  subset=\"training\",\n  seed=12345,\n  image_size=IMG_SIZE,\n  batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:12.823028Z","iopub.execute_input":"2023-09-17T15:37:12.823321Z","iopub.status.idle":"2023-09-17T15:37:18.985119Z","shell.execute_reply.started":"2023-09-17T15:37:12.823282Z","shell.execute_reply":"2023-09-17T15:37:18.984135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validation_dataset = tf.keras.utils.image_dataset_from_directory(\n  'train',\n  validation_split=0.2,\n  subset=\"validation\",\n  seed=12345,\n  image_size=IMG_SIZE,\n  batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:18.986387Z","iopub.execute_input":"2023-09-17T15:37:18.988110Z","iopub.status.idle":"2023-09-17T15:37:19.898728Z","shell.execute_reply.started":"2023-09-17T15:37:18.988071Z","shell.execute_reply":"2023-09-17T15:37:19.897148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Show the first nine images","metadata":{}},{"cell_type":"code","source":"class_names = train_dataset.class_names\n\nplt.figure(figsize=(10, 10))\nfor images, labels in train_dataset.take(1):\n  for i in range(9):\n    ax = plt.subplot(3, 3, i + 1)\n    plt.imshow(images[i].numpy().astype(\"uint8\"))\n    plt.title(class_names[labels[i]])\n    plt.axis(\"off\")","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:19.900259Z","iopub.execute_input":"2023-09-17T15:37:19.900632Z","iopub.status.idle":"2023-09-17T15:37:21.628644Z","shell.execute_reply.started":"2023-09-17T15:37:19.900599Z","shell.execute_reply":"2023-09-17T15:37:21.627506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Prepare test dataset","metadata":{}},{"cell_type":"code","source":"test_dataset = tf.keras.utils.image_dataset_from_directory(\n          \"test\",\n           shuffle=False,\n           batch_size=BATCH_SIZE,\n           image_size=IMG_SIZE)\n\ntest_path = test_dataset.file_paths\n","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:21.629620Z","iopub.execute_input":"2023-09-17T15:37:21.629929Z","iopub.status.idle":"2023-09-17T15:37:22.107830Z","shell.execute_reply.started":"2023-09-17T15:37:21.629901Z","shell.execute_reply":"2023-09-17T15:37:22.106830Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Configure the Dataset","metadata":{}},{"cell_type":"code","source":"AUTOTUNE = tf.data.AUTOTUNE\n\ntrain_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)\nvalidation_dataset = validation_dataset.prefetch(buffer_size=AUTOTUNE)\ntest_dataset = test_dataset.prefetch(buffer_size=AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:22.109237Z","iopub.execute_input":"2023-09-17T15:37:22.109595Z","iopub.status.idle":"2023-09-17T15:37:22.117222Z","shell.execute_reply.started":"2023-09-17T15:37:22.109562Z","shell.execute_reply":"2023-09-17T15:37:22.116019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Augmentation","metadata":{}},{"cell_type":"code","source":"data_augmentation = tf.keras.Sequential([\n  tf.keras.layers.RandomFlip('horizontal'),\n  tf.keras.layers.RandomRotation(0.2),\n  tf.keras.layers.RandomZoom(0.2),\n])","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:22.118926Z","iopub.execute_input":"2023-09-17T15:37:22.119356Z","iopub.status.idle":"2023-09-17T15:37:22.140915Z","shell.execute_reply.started":"2023-09-17T15:37:22.119324Z","shell.execute_reply":"2023-09-17T15:37:22.140010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for image, _ in train_dataset.take(1):\n  plt.figure(figsize=(10, 10))\n  first_image = image[0]\n  for i in range(9):\n    ax = plt.subplot(3, 3, i + 1)\n    augmented_image = data_augmentation(tf.expand_dims(first_image, 0))\n    plt.imshow(augmented_image[0] / 255)\n    plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:22.142126Z","iopub.execute_input":"2023-09-17T15:37:22.142626Z","iopub.status.idle":"2023-09-17T15:37:24.158442Z","shell.execute_reply.started":"2023-09-17T15:37:22.142594Z","shell.execute_reply":"2023-09-17T15:37:24.157562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Rescale Pixel Values","metadata":{}},{"cell_type":"markdown","source":"We will use the [MobileNetV2](https://www.tensorflow.org/api_docs/python/tf/keras/applications/mobilenet_v2/MobileNetV2) model. It expects pixel values lie between [-1,1].","metadata":{}},{"cell_type":"code","source":"preprocess_input = tf.keras.applications.mobilenet_v2.preprocess_input","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:24.159916Z","iopub.execute_input":"2023-09-17T15:37:24.160547Z","iopub.status.idle":"2023-09-17T15:37:24.165058Z","shell.execute_reply.started":"2023-09-17T15:37:24.160499Z","shell.execute_reply":"2023-09-17T15:37:24.164014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create the Base Model","metadata":{}},{"cell_type":"code","source":"IMG_SHAPE = IMG_SIZE + (3,)\nbase_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,\n                                               include_top=False,\n                                               weights='imagenet')","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:24.166509Z","iopub.execute_input":"2023-09-17T15:37:24.167186Z","iopub.status.idle":"2023-09-17T15:37:26.077858Z","shell.execute_reply.started":"2023-09-17T15:37:24.167155Z","shell.execute_reply":"2023-09-17T15:37:26.076759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The model is intantiated. Note that the top classification layer is not included, which is ideal for feature extraction.","metadata":{}},{"cell_type":"markdown","source":"# Featrue Extraction","metadata":{}},{"cell_type":"markdown","source":"1. Freeze the convolutional base as a feature extractor\n2. Add a classifier on top and train it.","metadata":{}},{"cell_type":"markdown","source":"## Freeze the Convolutional Base","metadata":{}},{"cell_type":"code","source":"base_model.trainable = False","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:26.083418Z","iopub.execute_input":"2023-09-17T15:37:26.083737Z","iopub.status.idle":"2023-09-17T15:37:26.097869Z","shell.execute_reply.started":"2023-09-17T15:37:26.083710Z","shell.execute_reply":"2023-09-17T15:37:26.096975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Add a Classification Head","metadata":{}},{"cell_type":"markdown","source":"The base model converts `160x160x3` image into a `5x5x1280` blocks of featrues.","metadata":{}},{"cell_type":"code","source":"image_batch, label_batch = next(iter(train_dataset))\nfeature_batch = base_model(image_batch)\nprint(image_batch.shape)\nprint(feature_batch.shape)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:26.101183Z","iopub.execute_input":"2023-09-17T15:37:26.101669Z","iopub.status.idle":"2023-09-17T15:37:33.432376Z","shell.execute_reply.started":"2023-09-17T15:37:26.101645Z","shell.execute_reply":"2023-09-17T15:37:33.431220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The `global_average_layer` convert the `5x5x1280` featrues into a 1280 element vector per image.","metadata":{}},{"cell_type":"code","source":"global_average_layer = tf.keras.layers.GlobalAveragePooling2D()\nfeature_batch_average = global_average_layer(feature_batch)\nprint(feature_batch_average.shape)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:33.434161Z","iopub.execute_input":"2023-09-17T15:37:33.434573Z","iopub.status.idle":"2023-09-17T15:37:33.451730Z","shell.execute_reply.started":"2023-09-17T15:37:33.434536Z","shell.execute_reply":"2023-09-17T15:37:33.450502Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Then convert the 1280 vector into a single prediction for an image.","metadata":{}},{"cell_type":"code","source":"num_classes = len(class_names)\n\nprediction_layer = tf.keras.layers.Dense(num_classes)\nprediction_batch = prediction_layer(feature_batch_average)\nprint(prediction_batch.shape)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:33.453554Z","iopub.execute_input":"2023-09-17T15:37:33.453957Z","iopub.status.idle":"2023-09-17T15:37:33.488034Z","shell.execute_reply.started":"2023-09-17T15:37:33.453919Z","shell.execute_reply":"2023-09-17T15:37:33.486984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Chaining together the data augmentation, rescaling, basemodel, and feature extractor layers.","metadata":{}},{"cell_type":"code","source":"inputs = tf.keras.Input(shape=(160, 160, 3))\nx = data_augmentation(inputs)\nx = preprocess_input(x)\nx = base_model(x, training=False)\nx = global_average_layer(x)\nx = tf.keras.layers.Dropout(0.2)(x)\noutputs = prediction_layer(x)\nmodel = tf.keras.Model(inputs, outputs)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:33.489353Z","iopub.execute_input":"2023-09-17T15:37:33.489903Z","iopub.status.idle":"2023-09-17T15:37:34.195480Z","shell.execute_reply.started":"2023-09-17T15:37:33.489870Z","shell.execute_reply":"2023-09-17T15:37:34.194500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Only parameters in the last dense layer are trainable.","metadata":{}},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:34.196787Z","iopub.execute_input":"2023-09-17T15:37:34.197717Z","iopub.status.idle":"2023-09-17T15:37:34.243544Z","shell.execute_reply.started":"2023-09-17T15:37:34.197681Z","shell.execute_reply":"2023-09-17T15:37:34.242581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Compile the Model","metadata":{}},{"cell_type":"code","source":"base_learning_rate = 0.0001\nmodel.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=base_learning_rate),\n              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:34.244701Z","iopub.execute_input":"2023-09-17T15:37:34.245338Z","iopub.status.idle":"2023-09-17T15:37:34.274500Z","shell.execute_reply.started":"2023-09-17T15:37:34.245292Z","shell.execute_reply":"2023-09-17T15:37:34.273572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train the Model","metadata":{}},{"cell_type":"code","source":"initial_epochs = 10\n\nhistory = model.fit(train_dataset,\n                    epochs=initial_epochs,\n                    validation_data=validation_dataset)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:37:34.279493Z","iopub.execute_input":"2023-09-17T15:37:34.280011Z","iopub.status.idle":"2023-09-17T15:40:26.261763Z","shell.execute_reply.started":"2023-09-17T15:37:34.279984Z","shell.execute_reply":"2023-09-17T15:40:26.260722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Learning Curves","metadata":{}},{"cell_type":"code","source":"acc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs_range = range(initial_epochs)\n\nplt.figure(figsize=(12, 6))\nplt.subplot(1, 2, 1)\nplt.plot(epochs_range, acc, label='Training Accuracy')\nplt.plot(epochs_range, val_acc, label='Validation Accuracy')\nplt.legend()\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(1, 2, 2)\nplt.plot(epochs_range, loss, label='Training Loss')\nplt.plot(epochs_range, val_loss, label='Validation Loss')\nplt.legend()\nplt.title('Training and Validation Loss')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:40:26.265500Z","iopub.execute_input":"2023-09-17T15:40:26.266389Z","iopub.status.idle":"2023-09-17T15:40:26.790309Z","shell.execute_reply.started":"2023-09-17T15:40:26.266346Z","shell.execute_reply":"2023-09-17T15:40:26.789433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Since `BatchNormalization` and `Dropout` in the basemodel are tuned off during validation evaluation, it seems that the validation set has a better performance than the training set.","metadata":{}},{"cell_type":"markdown","source":"# Fine Tuning","metadata":{}},{"cell_type":"markdown","source":"## Unfreeze top layers of the base model","metadata":{}},{"cell_type":"code","source":"base_model.trainable = True","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:40:29.396649Z","iopub.execute_input":"2023-09-17T15:40:29.397692Z","iopub.status.idle":"2023-09-17T15:40:29.409886Z","shell.execute_reply.started":"2023-09-17T15:40:29.397658Z","shell.execute_reply":"2023-09-17T15:40:29.408812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Number of layers in the base model: \", len(base_model.layers))\n","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:40:29.411798Z","iopub.execute_input":"2023-09-17T15:40:29.412198Z","iopub.status.idle":"2023-09-17T15:40:29.424168Z","shell.execute_reply.started":"2023-09-17T15:40:29.412164Z","shell.execute_reply":"2023-09-17T15:40:29.423104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Fine-tune from this layer onwards\nfine_tune_at = 100\n\n# Freeze all the layers before the `fine_tune_at` layer\nfor layer in base_model.layers[:fine_tune_at]:\n  layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:40:29.425967Z","iopub.execute_input":"2023-09-17T15:40:29.426301Z","iopub.status.idle":"2023-09-17T15:40:29.438794Z","shell.execute_reply.started":"2023-09-17T15:40:29.426261Z","shell.execute_reply":"2023-09-17T15:40:29.437680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_learning_rate = 0.0001\nmodel.compile(optimizer = tf.keras.optimizers.RMSprop(learning_rate=base_learning_rate/10),\n              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:40:29.440375Z","iopub.execute_input":"2023-09-17T15:40:29.440712Z","iopub.status.idle":"2023-09-17T15:40:29.463573Z","shell.execute_reply.started":"2023-09-17T15:40:29.440681Z","shell.execute_reply":"2023-09-17T15:40:29.462694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fine_tune_epochs = 10\ntotal_epochs =  initial_epochs + fine_tune_epochs\n\nhistory_fine = model.fit(train_dataset,\n                         epochs=total_epochs,\n                         initial_epoch=history.epoch[-1],\n                         validation_data=validation_dataset)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:40:29.464652Z","iopub.execute_input":"2023-09-17T15:40:29.464969Z","iopub.status.idle":"2023-09-17T15:44:15.126642Z","shell.execute_reply.started":"2023-09-17T15:40:29.464939Z","shell.execute_reply":"2023-09-17T15:44:15.125574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc += history_fine.history['accuracy']\nval_acc += history_fine.history['val_accuracy']\n\nloss += history_fine.history['loss']\nval_loss += history_fine.history['val_loss']","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:45:03.098856Z","iopub.execute_input":"2023-09-17T15:45:03.099302Z","iopub.status.idle":"2023-09-17T15:45:03.105299Z","shell.execute_reply.started":"2023-09-17T15:45:03.099256Z","shell.execute_reply":"2023-09-17T15:45:03.104309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(8, 8))\nplt.subplot(2, 1, 1)\nplt.plot(acc, label='Training Accuracy')\nplt.plot(val_acc, label='Validation Accuracy')\n#plt.ylim([0.8, 1])\nplt.plot([initial_epochs-1,initial_epochs-1],\n          plt.ylim(), label='Start Fine Tuning')\nplt.legend(loc='lower right')\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(2, 1, 2)\nplt.plot(loss, label='Training Loss')\nplt.plot(val_loss, label='Validation Loss')\n#plt.ylim([0, 1.0])\nplt.plot([initial_epochs-1,initial_epochs-1],\n         plt.ylim(), label='Start Fine Tuning')\nplt.legend(loc='upper right')\nplt.title('Training and Validation Loss')\nplt.xlabel('epoch')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:45:14.837289Z","iopub.execute_input":"2023-09-17T15:45:14.837690Z","iopub.status.idle":"2023-09-17T15:45:15.399431Z","shell.execute_reply.started":"2023-09-17T15:45:14.837649Z","shell.execute_reply":"2023-09-17T15:45:15.398444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction of my dog & my neighbor's dog","metadata":{}},{"cell_type":"code","source":"MY_DOG = '/kaggle/input/testing-dogs'\n\nfig, axs = plt.subplots(1,3,figsize=(10,8))\n\nfor i, file in enumerate(os.listdir(MY_DOG)):\n\n\n    img = tf.keras.utils.load_img(\n        MY_DOG+'/'+file,\n        target_size=IMG_SIZE\n    )\n    img_array = tf.keras.utils.img_to_array(img)\n    img_array = tf.expand_dims(img_array, 0) # Create a batch\n\n    predictions = model.predict(img_array, verbose=0)\n    score = tf.nn.softmax(predictions[0])\n\n\n    axs[i].imshow(img)\n    axs[i].axis(\"off\")\n    \n    axs[i].set_title(\"{}, {:.2f}%.\".format(class_names[np.argmax(score)], 100 * np.max(score)))\n    \n                     \n                ","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:47:44.379853Z","iopub.execute_input":"2023-09-17T15:47:44.380222Z","iopub.status.idle":"2023-09-17T15:47:45.956303Z","shell.execute_reply.started":"2023-09-17T15:47:44.380193Z","shell.execute_reply":"2023-09-17T15:47:45.955421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction on the Test Set","metadata":{}},{"cell_type":"code","source":"predictions = model.predict(test_dataset)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:44:15.807946Z","iopub.execute_input":"2023-09-17T15:44:15.811258Z","iopub.status.idle":"2023-09-17T15:44:29.093720Z","shell.execute_reply.started":"2023-09-17T15:44:15.811226Z","shell.execute_reply":"2023-09-17T15:44:29.092697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predict = pd.DataFrame(tf.nn.softmax(predictions), columns = class_names)\n\ntest_predict.insert(0, 'id', test_path)\n\n\ntest_predict['id'] = test_predict['id'].str.split(r'[\\/.]').str[2]","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:44:29.095377Z","iopub.execute_input":"2023-09-17T15:44:29.095739Z","iopub.status.idle":"2023-09-17T15:44:29.134719Z","shell.execute_reply.started":"2023-09-17T15:44:29.095705Z","shell.execute_reply":"2023-09-17T15:44:29.133822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predict.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-09-17T15:44:29.136172Z","iopub.execute_input":"2023-09-17T15:44:29.136547Z","iopub.status.idle":"2023-09-17T15:44:30.568299Z","shell.execute_reply.started":"2023-09-17T15:44:29.136491Z","shell.execute_reply":"2023-09-17T15:44:30.567286Z"},"trusted":true},"execution_count":null,"outputs":[]}]}