{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":7327,"databundleVersionId":861871,"sourceType":"competition"}],"dockerImageVersionId":30587,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Importing Required Libraries","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom tensorflow.keras import backend as K\nimport keras_tuner as kt\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:26.207302Z","iopub.execute_input":"2023-12-13T14:08:26.207726Z","iopub.status.idle":"2023-12-13T14:08:40.006912Z","shell.execute_reply.started":"2023-12-13T14:08:26.207694Z","shell.execute_reply":"2023-12-13T14:08:40.006000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Multi GPU strategy with TensorFlow","metadata":{}},{"cell_type":"code","source":"strategy = tf.distribute.MirroredStrategy()\nprint(f\"Number of devices: {strategy.num_replicas_in_sync}\")","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:40.008758Z","iopub.execute_input":"2023-12-13T14:08:40.009286Z","iopub.status.idle":"2023-12-13T14:08:44.543545Z","shell.execute_reply.started":"2023-12-13T14:08:40.009256Z","shell.execute_reply":"2023-12-13T14:08:44.542618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PATH = '/kaggle/input/dog-breed-identification'\nNUM_CHANNEL = 3\nINPUT_SHAPE = 256\nBATCH_SIZE = 32 * strategy.num_replicas_in_sync","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:44.544993Z","iopub.execute_input":"2023-12-13T14:08:44.545328Z","iopub.status.idle":"2023-12-13T14:08:44.549931Z","shell.execute_reply.started":"2023-12-13T14:08:44.545303Z","shell.execute_reply":"2023-12-13T14:08:44.548866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Preprocessing","metadata":{}},{"cell_type":"markdown","source":"ImageDatastore to read files and feeds into the model during training","metadata":{}},{"cell_type":"code","source":"class ImageDatastore:\n    \n    def __init__(self, path, csv, output_shape, train_val_test):\n        self.path = path\n        self.csv = csv\n        self.output_shape = output_shape\n        self.train_val_test = train_val_test\n        self.image_paths, self.labels = self.get_files_and_labels()\n        \n    def get_files_and_labels(self):\n        image_paths = [os.path.join(self.path, path) + '.jpg' for path in self.csv.index]\n        if self.train_val_test == 'test':\n            labels = ['' for i in range(len(image_paths))]\n        else:\n            labels = pd.get_dummies(self.csv.breed).astype('uint8').to_numpy()\n        return image_paths, labels\n    \n    def __call__(self):\n        pairs = list(zip(self.image_paths, self.labels))\n        for image_path, label in pairs:\n            image = cv2.imread(image_path)\n            image = cv2.resize(image, self.output_shape)\n            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n            if self.train_val_test == 'test':\n                yield image\n            else:\n                yield image, label","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:44.551248Z","iopub.execute_input":"2023-12-13T14:08:44.551572Z","iopub.status.idle":"2023-12-13T14:08:44.562134Z","shell.execute_reply.started":"2023-12-13T14:08:44.551539Z","shell.execute_reply":"2023-12-13T14:08:44.561090Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"CustomCallback to patiently reduce the learning rate, then stops at the last patience.","metadata":{}},{"cell_type":"code","source":"class CustomCallback(tf.keras.callbacks.Callback):\n    def __init__(self, monitor=\"loss\", factor=0.5, patience=0, min_lr=0.01):\n        super(CustomCallback, self).__init__()\n        self.monitor = monitor\n        self.factor = factor\n        self.patience = patience\n        self.min_lr = min_lr\n        self.job = 0\n\n    def on_train_begin(self, logs=None):\n        self.wait = 0\n        self.stopped_epoch = 0\n        if 'loss' in self.monitor:\n            self.best = np.inf\n        else:\n            self.best = -1\n\n    def on_epoch_end(self, epoch, logs=None):\n        current = logs.get(self.monitor)\n        if 'loss' in self.monitor and current < self.best:\n            self.best = current\n            self.wait = 0\n        elif 'acc' in self.monitor and  current > self.best:\n            self.best = current\n            self.wait = 0\n        else:\n            self.wait += 1\n            if self.wait >= self.patience:\n                if self.job == 0:\n                    lr = float(K.get_value(self.model.optimizer.learning_rate))\n                    new_lr = lr * self.factor\n                    if new_lr < self.min_lr:\n                        new_lr = self.min_lr\n                        self.job = 1\n                    K.set_value(self.model.optimizer.lr, new_lr)\n                    self.wait = 0\n                    print(f\"\\nLearning rate reduced from {'{:.3g}'.format(lr)} to {'{:.3g}'.format(new_lr)}\")\n                elif self.job == 1:\n                    self.stopped_epoch = epoch\n                    self.model.stop_training = True\n\n    def on_train_end(self, logs=None):\n        if self.stopped_epoch > 0:\n            print(f\"Epoch {self.stopped_epoch + 1}: early stopping\")","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:44.564396Z","iopub.execute_input":"2023-12-13T14:08:44.564666Z","iopub.status.idle":"2023-12-13T14:08:44.576325Z","shell.execute_reply.started":"2023-12-13T14:08:44.564637Z","shell.execute_reply":"2023-12-13T14:08:44.575440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(PATH, 'labels.csv'), index_col='id')\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:44.577388Z","iopub.execute_input":"2023-12-13T14:08:44.577672Z","iopub.status.idle":"2023-12-13T14:08:44.644623Z","shell.execute_reply.started":"2023-12-13T14:08:44.577649Z","shell.execute_reply":"2023-12-13T14:08:44.643780Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.value_counts().plot.pie(autopct='%%%.2f', figsize=(25, 50));","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:44.645865Z","iopub.execute_input":"2023-12-13T14:08:44.646181Z","iopub.status.idle":"2023-12-13T14:08:46.649681Z","shell.execute_reply.started":"2023-12-13T14:08:44.646156Z","shell.execute_reply":"2023-12-13T14:08:46.648505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples = train_df.sample(6)\nplt.figure(figsize=(12, 8))\n\nfor i, index in enumerate(samples.index):\n    plt.subplot(230 + i + 1)\n    img = mpimg.imread(os.path.join(PATH, 'train', index + '.jpg'))\n    plt.imshow(img)\n    plt.axis('off')\n    plt.title(f'True Class: {samples.loc[[index], \"breed\"].values[0]}')\n    \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:46.650890Z","iopub.execute_input":"2023-12-13T14:08:46.651241Z","iopub.status.idle":"2023-12-13T14:08:47.731494Z","shell.execute_reply.started":"2023-12-13T14:08:46.651212Z","shell.execute_reply":"2023-12-13T14:08:47.730616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_CLASS = train_df.breed.nunique()\nprint(f'Number of classes: {NUM_CLASS}')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:47.732738Z","iopub.execute_input":"2023-12-13T14:08:47.733091Z","iopub.status.idle":"2023-12-13T14:08:47.742087Z","shell.execute_reply.started":"2023-12-13T14:08:47.733062Z","shell.execute_reply":"2023-12-13T14:08:47.741124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_ratio = 0.2\nnum_sapmle = int(len(train_df) * val_ratio / NUM_CLASS)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:47.743324Z","iopub.execute_input":"2023-12-13T14:08:47.743591Z","iopub.status.idle":"2023-12-13T14:08:47.753395Z","shell.execute_reply.started":"2023-12-13T14:08:47.743567Z","shell.execute_reply":"2023-12-13T14:08:47.752566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_df = pd.concat([train_df[train_df.breed == lbl].sample(num_sapmle) for lbl in train_df.breed.unique()], axis=0)\nval_df = val_df.sample(frac=1)\n\ntrain_df = train_df.drop(val_df.index)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:47.754493Z","iopub.execute_input":"2023-12-13T14:08:47.754762Z","iopub.status.idle":"2023-12-13T14:08:48.009265Z","shell.execute_reply.started":"2023-12-13T14:08:47.754739Z","shell.execute_reply":"2023-12-13T14:08:48.008437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f'''Number of train images: {len(train_df)}\nNumber of val images: {len(val_df)}''')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:48.010233Z","iopub.execute_input":"2023-12-13T14:08:48.010493Z","iopub.status.idle":"2023-12-13T14:08:48.015556Z","shell.execute_reply.started":"2023-12-13T14:08:48.010469Z","shell.execute_reply":"2023-12-13T14:08:48.014554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds = ImageDatastore(os.path.join(PATH, 'train'), train_df, (INPUT_SHAPE, INPUT_SHAPE), 'train')\nval_ds = ImageDatastore(os.path.join(PATH, 'train'), val_df, (INPUT_SHAPE, INPUT_SHAPE), 'val')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:48.016608Z","iopub.execute_input":"2023-12-13T14:08:48.016878Z","iopub.status.idle":"2023-12-13T14:08:48.055485Z","shell.execute_reply.started":"2023-12-13T14:08:48.016855Z","shell.execute_reply":"2023-12-13T14:08:48.054825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Data augmentation with random flip, rotation and zoom. ","metadata":{}},{"cell_type":"code","source":"data_augmentation = tf.keras.Sequential([\n    tf.keras.layers.RandomFlip(),\n    tf.keras.layers.RandomRotation(0.2),\n    tf.keras.layers.RandomZoom(0.2)\n])","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:48.059342Z","iopub.execute_input":"2023-12-13T14:08:48.059630Z","iopub.status.idle":"2023-12-13T14:08:48.090608Z","shell.execute_reply.started":"2023-12-13T14:08:48.059605Z","shell.execute_reply":"2023-12-13T14:08:48.089890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"tf.Data for [better performance](https://www.tensorflow.org/guide/data_performance)  ","metadata":{}},{"cell_type":"code","source":"OUTPUT_SIGNATURE = (tf.TensorSpec(shape=(INPUT_SHAPE, INPUT_SHAPE, NUM_CHANNEL), dtype='uint8'), tf.TensorSpec(shape=(NUM_CLASS), dtype='uint8'))\n\ntrain = tf.data.Dataset.from_generator(generator=train_ds, output_signature=OUTPUT_SIGNATURE)\ntrain = tf.data.Dataset.range(1).interleave(lambda _: train, num_parallel_calls=tf.data.AUTOTUNE).batch(batch_size=BATCH_SIZE, drop_remainder=True).map(lambda X, y: (data_augmentation(X, training=True), y), num_parallel_calls=tf.data.AUTOTUNE).cache().prefetch(buffer_size=tf.data.AUTOTUNE)\n\nval = tf.data.Dataset.from_generator(generator=val_ds, output_signature=OUTPUT_SIGNATURE)\nval = tf.data.Dataset.range(1).interleave(lambda _: val, num_parallel_calls=tf.data.AUTOTUNE).batch(batch_size=BATCH_SIZE, drop_remainder=True).cache().prefetch(buffer_size=tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:48.091529Z","iopub.execute_input":"2023-12-13T14:08:48.091786Z","iopub.status.idle":"2023-12-13T14:08:48.840066Z","shell.execute_reply.started":"2023-12-13T14:08:48.091762Z","shell.execute_reply":"2023-12-13T14:08:48.839198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Building a Model","metadata":{}},{"cell_type":"markdown","source":"Method to build model with hyper-parameters optimization features","metadata":{}},{"cell_type":"code","source":"def build_model(hp):\n\n    input_shape = (INPUT_SHAPE, INPUT_SHAPE, NUM_CHANNEL)\n\n    base = tf.keras.applications.MobileNetV2(input_shape=input_shape, weights='imagenet', include_top=False, pooling='avg')\n    base.trainable=False\n    base.training=False\n\n    inputs = tf.keras.Input(shape=input_shape)\n    \n    x = tf.keras.applications.mobilenet_v2.preprocess_input(inputs)\n    x = base(x)\n    \n    hp_units = hp.Int('units', min_value=32, max_value=512, step=32)\n    x=tf.keras.layers.Dense(hp_units)(x)\n    x=tf.keras.layers.BatchNormalization()(x)\n    \n    hp_act = hp.Choice('activation', values=['relu', 'tanh'])\n    x=tf.keras.layers.Activation(hp_act)(x)\n    \n    hp_drop = hp.Float('rate', min_value=0.0, max_value=0.5, step=0.1)\n    x=tf.keras.layers.Dropout(hp_drop)(x)\n    \n    outputs = tf.keras.layers.Dense(NUM_CLASS, activation=\"softmax\")(x)\n    \n    model = tf.keras.Model(inputs, outputs)\n\n    model.compile(\n        optimizer=tf.keras.optimizers.Adam(1e-3),\n        loss=tf.keras.losses.CategoricalCrossentropy(from_logits=False),\n        metrics=[tf.keras.metrics.CategoricalAccuracy(name=\"accuracy\")],\n    )\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:48.841400Z","iopub.execute_input":"2023-12-13T14:08:48.841683Z","iopub.status.idle":"2023-12-13T14:08:48.850892Z","shell.execute_reply.started":"2023-12-13T14:08:48.841659Z","shell.execute_reply":"2023-12-13T14:08:48.849865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tuner = kt.Hyperband(\n    build_model,\n    objective='val_accuracy',\n    max_epochs=10,\n    factor=3,\n    distribution_strategy=strategy)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:48.852030Z","iopub.execute_input":"2023-12-13T14:08:48.852331Z","iopub.status.idle":"2023-12-13T14:08:50.949163Z","shell.execute_reply.started":"2023-12-13T14:08:48.852308Z","shell.execute_reply":"2023-12-13T14:08:50.948368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tuner.search(train, epochs=10, validation_data=val)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:08:50.950318Z","iopub.execute_input":"2023-12-13T14:08:50.950606Z","iopub.status.idle":"2023-12-13T14:37:26.112705Z","shell.execute_reply.started":"2023-12-13T14:08:50.950581Z","shell.execute_reply":"2023-12-13T14:37:26.111837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"best_hps=tuner.get_best_hyperparameters(num_trials=1)[0]\n\nprint(f\"\"\"\nThe hyperparameter search is complete.\nThe optimal number of units in the first densely-connected layer is {best_hps.get('units')}.\nThe optimal activation for the first densely-connected is {best_hps.get('activation')}.\nThe optimal rate for dropout is {best_hps.get('rate')}.\n\"\"\")","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:37:26.113993Z","iopub.execute_input":"2023-12-13T14:37:26.114679Z","iopub.status.idle":"2023-12-13T14:37:26.120295Z","shell.execute_reply.started":"2023-12-13T14:37:26.114639Z","shell.execute_reply":"2023-12-13T14:37:26.119406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Create the model with best hyper-parameters","metadata":{}},{"cell_type":"code","source":"with strategy.scope():\n    model = tuner.hypermodel.build(best_hps)\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:37:26.121482Z","iopub.execute_input":"2023-12-13T14:37:26.121753Z","iopub.status.idle":"2023-12-13T14:37:29.941612Z","shell.execute_reply.started":"2023-12-13T14:37:26.121730Z","shell.execute_reply":"2023-12-13T14:37:29.940717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(\n    train,\n    epochs=1000,\n    validation_data=val,\n    callbacks=[CustomCallback(monitor='val_accuracy', factor=0.5, patience=10, min_lr=2e-6)]\n)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:37:29.943003Z","iopub.execute_input":"2023-12-13T14:37:29.943254Z","iopub.status.idle":"2023-12-13T14:52:58.164925Z","shell.execute_reply.started":"2023-12-13T14:37:29.943231Z","shell.execute_reply":"2023-12-13T14:52:58.163926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Plotting metrics","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', 'val'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:52:58.167111Z","iopub.execute_input":"2023-12-13T14:52:58.167409Z","iopub.status.idle":"2023-12-13T14:52:58.456126Z","shell.execute_reply.started":"2023-12-13T14:52:58.167383Z","shell.execute_reply":"2023-12-13T14:52:58.455211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend(['train', 'val'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:52:58.457346Z","iopub.execute_input":"2023-12-13T14:52:58.459286Z","iopub.status.idle":"2023-12-13T14:52:58.674997Z","shell.execute_reply.started":"2023-12-13T14:52:58.459257Z","shell.execute_reply":"2023-12-13T14:52:58.674153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction","metadata":{}},{"cell_type":"code","source":"classes = sorted(train_df.breed.unique())\nprint(classes)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:52:58.676201Z","iopub.execute_input":"2023-12-13T14:52:58.676474Z","iopub.status.idle":"2023-12-13T14:52:58.682318Z","shell.execute_reply.started":"2023-12-13T14:52:58.676450Z","shell.execute_reply":"2023-12-13T14:52:58.681412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(12, 8))\n\nfor i, index in enumerate(samples.index):\n    img = mpimg.imread(os.path.join(PATH, 'train', index + '.jpg'))\n    \n    img = cv2.resize(img, (INPUT_SHAPE, INPUT_SHAPE))\n    pred = model.predict(np.expand_dims(img, 0), verbose=False)\n    cls_index = np.argmax(pred)\n    cls_name = classes[cls_index]\n    \n    plt.subplot(230 + i + 1)\n    plt.imshow(img)\n    plt.axis('off')\n    plt.title(f'True Class: {samples.loc[[index], \"breed\"].values[0]} \\n Predicted Class: {cls_name}')\n    \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:52:58.683475Z","iopub.execute_input":"2023-12-13T14:52:58.683736Z","iopub.status.idle":"2023-12-13T14:53:04.078768Z","shell.execute_reply.started":"2023-12-13T14:52:58.683713Z","shell.execute_reply":"2023-12-13T14:53:04.077593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"sub_test_df = pd.read_csv('/kaggle/input/dog-breed-identification/sample_submission.csv', index_col='id')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:53:04.080091Z","iopub.execute_input":"2023-12-13T14:53:04.080421Z","iopub.status.idle":"2023-12-13T14:53:04.620133Z","shell.execute_reply.started":"2023-12-13T14:53:04.080393Z","shell.execute_reply":"2023-12-13T14:53:04.619273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_test_ds = ImageDatastore(os.path.join(PATH, 'test'), sub_test_df, (INPUT_SHAPE, INPUT_SHAPE), 'test')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:53:04.621360Z","iopub.execute_input":"2023-12-13T14:53:04.621734Z","iopub.status.idle":"2023-12-13T14:53:04.648274Z","shell.execute_reply.started":"2023-12-13T14:53:04.621702Z","shell.execute_reply":"2023-12-13T14:53:04.647426Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SUB_OUTPUT_SIGNATURE = (tf.TensorSpec(shape=(INPUT_SHAPE, INPUT_SHAPE, NUM_CHANNEL), dtype='uint8'))\nsub_test = tf.data.Dataset.from_generator(generator=sub_test_ds, output_signature=SUB_OUTPUT_SIGNATURE)\nsub_test = tf.data.Dataset.range(1).interleave(lambda _:sub_test, num_parallel_calls=tf.data.AUTOTUNE).batch(batch_size=BATCH_SIZE, drop_remainder=False).cache().prefetch(buffer_size=tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:53:04.649519Z","iopub.execute_input":"2023-12-13T14:53:04.649876Z","iopub.status.idle":"2023-12-13T14:53:04.710114Z","shell.execute_reply.started":"2023-12-13T14:53:04.649843Z","shell.execute_reply":"2023-12-13T14:53:04.709221Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred = model.predict(sub_test)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:53:04.711316Z","iopub.execute_input":"2023-12-13T14:53:04.713196Z","iopub.status.idle":"2023-12-13T14:55:29.021144Z","shell.execute_reply.started":"2023-12-13T14:53:04.713169Z","shell.execute_reply":"2023-12-13T14:55:29.020288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_test_df.iloc[:] = pred","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:55:29.022777Z","iopub.execute_input":"2023-12-13T14:55:29.023167Z","iopub.status.idle":"2023-12-13T14:55:29.029716Z","shell.execute_reply.started":"2023-12-13T14:55:29.023133Z","shell.execute_reply":"2023-12-13T14:55:29.028933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_test_df.to_csv(os.path.join('/kaggle', 'working', 'submission.csv'))\nsub_test_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T14:55:29.030842Z","iopub.execute_input":"2023-12-13T14:55:29.031154Z","iopub.status.idle":"2023-12-13T14:55:31.744800Z","shell.execute_reply.started":"2023-12-13T14:55:29.031128Z","shell.execute_reply":"2023-12-13T14:55:31.743824Z"},"trusted":true},"execution_count":null,"outputs":[]}]}