{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":21154,"databundleVersionId":1243559,"sourceType":"competition"},{"sourceId":18422,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":15301}],"dockerImageVersionId":30665,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-03-20T15:22:04.849544Z","iopub.execute_input":"2024-03-20T15:22:04.850338Z","iopub.status.idle":"2024-03-20T15:22:04.986861Z","shell.execute_reply.started":"2024-03-20T15:22:04.850306Z","shell.execute_reply":"2024-03-20T15:22:04.985999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import io\nimport glob\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport seaborn as sns; sns.set()\nfrom sklearn.metrics import f1_score\n\nimport tensorflow as tf\nfrom tensorflow.keras import layers, Model\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.metrics import Mean\nfrom sklearn.metrics import f1_score","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:22:09.508674Z","iopub.execute_input":"2024-03-20T15:22:09.509038Z","iopub.status.idle":"2024-03-20T15:22:29.258909Z","shell.execute_reply.started":"2024-03-20T15:22:09.509005Z","shell.execute_reply":"2024-03-20T15:22:29.257768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_path = '/kaggle/input/tpu-getting-started/tfrecords-jpeg-224x224/train/*.tfrec'\n# valid_path = '/kaggle/input/tpu-getting-started/tfrecords-jpeg-224x224/val/*.tfrec'\n# test_path  = '/kaggle/input/tpu-getting-started/tfrecords-jpeg-224x224/test/*.tfrec'\n\n# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\ndevice = '/GPU:0' if tf.test.is_gpu_available() else '/CPU:0'","metadata":{"execution":{"iopub.status.busy":"2024-03-20T10:17:32.532552Z","iopub.execute_input":"2024-03-20T10:17:32.533280Z","iopub.status.idle":"2024-03-20T10:17:32.910912Z","shell.execute_reply.started":"2024-03-20T10:17:32.533252Z","shell.execute_reply":"2024-03-20T10:17:32.909887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_files = tf.io.gfile.glob('/kaggle/input/tpu-getting-started/tfrecords-jpeg-224x224/train/*.tfrec')\nvalid_files = tf.io.gfile.glob('/kaggle/input/tpu-getting-started/tfrecords-jpeg-224x224/val/*.tfrec')\ntest_files = tf.io.gfile.glob('/kaggle/input/tpu-getting-started/tfrecords-jpeg-224x224/test/*.tfrec')\n\ntrain_dataset = tf.data.TFRecordDataset(train_files)\nvalid_dataset = tf.data.TFRecordDataset(valid_files)\ntest_dataset = tf.data.TFRecordDataset(test_files)","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:22:29.261039Z","iopub.execute_input":"2024-03-20T15:22:29.261848Z","iopub.status.idle":"2024-03-20T15:22:29.958279Z","shell.execute_reply.started":"2024-03-20T15:22:29.261819Z","shell.execute_reply":"2024-03-20T15:22:29.957266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_epochs    = 10                                                            \nbatch_size  = 20                                                           \nnum_prints  = 10                                                  \ntrain_size  = 12753                                                     \nprint_freq  = train_size // (batch_size * num_prints) + 1              \ncheck_freq  = 1                                            ","metadata":{"execution":{"iopub.status.busy":"2024-03-20T10:17:33.274836Z","iopub.execute_input":"2024-03-20T10:17:33.275080Z","iopub.status.idle":"2024-03-20T10:17:33.279768Z","shell.execute_reply.started":"2024-03-20T10:17:33.275058Z","shell.execute_reply":"2024-03-20T10:17:33.278914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class EfficientNetB0(tf.keras.Model):\n    def __init__(self, num_classes):\n        super(EfficientNetB0, self).__init__()\n        self.efficientnet_b0 = tf.keras.applications.EfficientNetB0(weights='imagenet', include_top=False)\n        self.global_average_pooling = tf.keras.layers.GlobalAveragePooling2D()\n        self.output_layer = tf.keras.layers.Dense(num_classes, activation='softmax')\n\n    def call(self, inputs):\n        x = self.efficientnet_b0(inputs)\n        x = self.global_average_pooling(x)\n        return self.output_layer(x)","metadata":{"execution":{"iopub.status.busy":"2024-03-19T23:47:14.308049Z","iopub.execute_input":"2024-03-19T23:47:14.308324Z","iopub.status.idle":"2024-03-19T23:47:14.323556Z","shell.execute_reply.started":"2024-03-19T23:47:14.308294Z","shell.execute_reply":"2024-03-19T23:47:14.322801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def parse_tfrecord_function(example):\n    feature_description = {\n        'image': tf.io.FixedLenFeature([], tf.string),\n        'class': tf.io.FixedLenFeature([], tf.int64),\n        'id': tf.io.FixedLenFeature([], tf.string),\n    }\n    \n    example = tf.io.parse_single_example(example, feature_description)\n    \n    image = tf.image.decode_jpeg(example['image'], channels=3)\n    image = tf.image.resize(image, (300, 300))\n    \n    # Normalize pixel values to [0, 1]\n    # image = tf.cast(image, tf.float32) / 255.0\n    \n    # Normalize using mean and standard deviation\n    mean = [0.485, 0.456, 0.406]\n    std = [0.229, 0.224, 0.225]\n    image = tf.cast(image, tf.float32)\n    image = (image - mean) / std\n    \n    # Expand dimensions\n    image = tf.expand_dims(image, axis=0)\n    \n    # Expand dimensions for label to shape (1,)\n    label = tf.expand_dims(example['class'], axis=0)\n    \n    example['id'] = example['id'].numpy().decode('utf-8')\n    \n    return image, label, example['id']\n","metadata":{"execution":{"iopub.status.busy":"2024-03-20T14:42:42.836638Z","iopub.execute_input":"2024-03-20T14:42:42.837001Z","iopub.status.idle":"2024-03-20T14:42:42.845991Z","shell.execute_reply.started":"2024-03-20T14:42:42.836972Z","shell.execute_reply":"2024-03-20T14:42:42.844874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def EfficientNetB0(input_shape, num_classes):\n    base_model = tf.keras.applications.EfficientNetB0(include_top=False, input_shape=input_shape)\n    x = base_model.output\n    x = layers.GlobalAveragePooling2D()(x)\n    x = layers.Dense(num_classes, activation='softmax')(x)\n    model = Model(inputs=base_model.input, outputs=x)\n    return model\n\ninput_shape = (300, 300, 3)\nnum_classes = 104\n\n# Create the model\nmodel = EfficientNetB0(input_shape, num_classes)\n\n# Define the learning rates for different parts of the model\nlr_backbone = 1e-4\nlr_top = 1e-3\n\n# Define optimizer and its parameters\noptimizer = Adam(lr_backbone) \noptimizer.learning_rate.assign(lr_backbone) \n\n# Set different learning rates for different parts of the model\nfor layer in model.layers:\n    if any([l in layer.name for l in ['block6d', 'block7', 'block8', 'top']]):\n        layer_learning_rate = lr_top\n    else:\n        layer_learning_rate = lr_backbone\n    \n    optimizer.learning_rate.assign(layer_learning_rate)\n\nloss_fn = tf.keras.losses.SparseCategoricalCrossentropy()\n\nlosses = []\nvalid_f1s = []\nn_epochs = 10\n\nfor epoch in range(n_epochs):\n    print(f'Epoch {epoch}:')\n    print('-' * len(f'Epoch {epoch}:'))\n    \n    # Training\n    epoch_loss_avg = Mean()\n    model.trainable = True\n    for i, example in enumerate(train_dataset):\n        x, y = parse_tfrecord_function(example)\n        with tf.GradientTape() as tape:\n            logits = model(x)\n            loss = loss_fn(y, logits)\n        gradients = tape.gradient(loss, model.trainable_variables)\n        optimizer.apply_gradients(zip(gradients, model.trainable_variables))\n        epoch_loss_avg.update_state(loss)\n        if i % print_freq == 0:\n            print(f'Loss {i}: {epoch_loss_avg.result().numpy():.3f}')\n            losses.append(epoch_loss_avg.result().numpy())\n    \n    # Validation\n    if epoch % check_freq == 0:\n        model.trainable = False\n        valid_true_labs = []\n        valid_pred_labs = []\n        for example in valid_dataset:\n            x, y = parse_tfrecord_function(example)\n            logits = model(x)\n            valid_true_labs.extend(y.numpy())\n            valid_pred_labs.extend(tf.argmax(logits, axis=1).numpy())\n        valid_f1 = f1_score(valid_true_labs, valid_pred_labs, average='weighted')\n        valid_f1s.append(valid_f1)\n        print(f'Validation F1: {valid_f1 * 100:.2f}%')\n        model.save_weights(f'./epoch{epoch // check_freq}.weights.h5')\n\n    \n    scheduler.step()\n","metadata":{"execution":{"iopub.status.busy":"2024-03-19T23:47:14.351680Z","iopub.execute_input":"2024-03-19T23:47:14.352026Z","iopub.status.idle":"2024-03-20T04:38:07.985385Z","shell.execute_reply.started":"2024-03-19T23:47:14.351995Z","shell.execute_reply":"2024-03-20T04:38:07.983796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save the final model\nmodel.save('final_model.h5')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T04:58:53.070387Z","iopub.execute_input":"2024-03-20T04:58:53.071126Z","iopub.status.idle":"2024-03-20T04:58:53.402242Z","shell.execute_reply.started":"2024-03-20T04:58:53.071090Z","shell.execute_reply":"2024-03-20T04:58:53.401429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def parse_tfrecord_test(example):\n    feature_description = {\n        'image': tf.io.FixedLenFeature([], tf.string),\n        'id': tf.io.FixedLenFeature([], tf.string),\n    }\n    \n    example = tf.io.parse_single_example(example, feature_description)\n    \n    image = tf.image.decode_jpeg(example['image'], channels=3)\n    image = tf.image.resize(image, (300, 300))\n    \n    # Normalize pixel values to [0, 1]\n    # image = tf.cast(image, tf.float32) / 255.0\n    \n    # Normalize using mean and standard deviation\n    mean = [0.485, 0.456, 0.406]\n    std = [0.229, 0.224, 0.225]\n    image = tf.cast(image, tf.float32)\n    image = (image - mean) / std\n    \n    # Expand dimensions\n    image = tf.expand_dims(image, axis=0)\n    \n    example['id'] = example['id'].numpy().decode('utf-8')\n    \n    return image, example['id']","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:21:44.388169Z","iopub.execute_input":"2024-03-20T15:21:44.388503Z","iopub.status.idle":"2024-03-20T15:21:44.404397Z","shell.execute_reply.started":"2024-03-20T15:21:44.388475Z","shell.execute_reply":"2024-03-20T15:21:44.403262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from tensorflow.keras.models import load_model\n# model = load_model('/kaggle/input/final_model.h5/other/h5/1/final_model.h5')","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:22:45.392910Z","iopub.execute_input":"2024-03-20T15:22:45.393376Z","iopub.status.idle":"2024-03-20T15:22:47.796936Z","shell.execute_reply.started":"2024-03-20T15:22:45.393339Z","shell.execute_reply":"2024-03-20T15:22:47.795934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ids = []\npreds = []\n\nmodel.trainable = False\n\nfor example in test_dataset:\n    x, example_id = parse_tfrecord_test(example)\n    ids.append(example_id) \n    logits = model(x)\n    prediction = tf.argmax(logits, axis=1).numpy().item()\n    preds.append(prediction)\n\nsubmission = pd.DataFrame({'id': ids, 'label': preds})\nsubmission.to_csv('submission.csv', index=False)\n\nsubmission.head()\n","metadata":{"execution":{"iopub.status.busy":"2024-03-20T15:22:47.799092Z","iopub.execute_input":"2024-03-20T15:22:47.799450Z","iopub.status.idle":"2024-03-20T15:49:42.506443Z","shell.execute_reply.started":"2024-03-20T15:22:47.799418Z","shell.execute_reply":"2024-03-20T15:49:42.505484Z"},"trusted":true},"execution_count":null,"outputs":[]}]}