{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\n\nAUTO = tf.data.AUTOTUNE\n\nIMG_SIZE = 224\nBATCH_SIZE = 32\nNUM_CLASSES = 104\n\nDATA_PATH = \"/kaggle/input/competitions/tpu-getting-started/tfrecords-jpeg-224x224\"\n\nTRAIN_FILES = tf.io.gfile.glob(DATA_PATH + \"/train/*.tfrec\")\nVAL_FILES   = tf.io.gfile.glob(DATA_PATH + \"/val/*.tfrec\")\nTEST_FILES  = tf.io.gfile.glob(DATA_PATH + \"/test/*.tfrec\")\n\nprint(len(TRAIN_FILES), len(VAL_FILES), len(TEST_FILES))\n\nprint(\"TensorFlow:\", tf.__version__)\nprint(\"GPU:\", tf.config.list_physical_devices(\"GPU\"))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:41:41.411666Z","iopub.execute_input":"2026-07-15T12:41:41.411960Z","iopub.status.idle":"2026-07-15T12:41:41.424195Z","shell.execute_reply.started":"2026-07-15T12:41:41.411936Z","shell.execute_reply":"2026-07-15T12:41:41.422906Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"LABELED = {\n    \"image\": tf.io.FixedLenFeature([], tf.string),\n    \"class\": tf.io.FixedLenFeature([], tf.int64)\n}\n\nUNLABELED = {\n    \"image\": tf.io.FixedLenFeature([], tf.string),\n    \"id\": tf.io.FixedLenFeature([], tf.string)\n}\n\ndef read_train(example):\n\n    example = tf.io.parse_single_example(example, LABELED)\n\n    image = tf.image.decode_jpeg(example[\"image\"], channels=3)\n    image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE))\n    image = tf.cast(image, tf.float32) / 255.0\n\n    label = tf.cast(example[\"class\"], tf.int32)\n\n    return image, label\n\n\ndef read_test(example):\n\n    example = tf.io.parse_single_example(example, UNLABELED)\n\n    image = tf.image.decode_jpeg(example[\"image\"], channels=3)\n    image = tf.image.resize(image, (IMG_SIZE, IMG_SIZE))\n    image = tf.cast(image, tf.float32) / 255.0\n\n    return image, example[\"id\"]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:41:40.923960Z","iopub.execute_input":"2026-07-15T12:41:40.924241Z","iopub.status.idle":"2026-07-15T12:41:40.931580Z","shell.execute_reply.started":"2026-07-15T12:41:40.924218Z","shell.execute_reply":"2026-07-15T12:41:40.930758Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_ds = (\n    tf.data.TFRecordDataset(TRAIN_FILES)\n    .map(read_train, num_parallel_calls=AUTO)\n    .shuffle(2048)\n    .batch(BATCH_SIZE)\n    .prefetch(AUTO)\n)\n\nval_ds = (\n    tf.data.TFRecordDataset(VAL_FILES)\n    .map(read_train, num_parallel_calls=AUTO)\n    .batch(BATCH_SIZE)\n    .prefetch(AUTO)\n)\n\ntest_ds = (\n    tf.data.TFRecordDataset(TEST_FILES)\n    .map(read_test, num_parallel_calls=AUTO)\n    .batch(BATCH_SIZE)\n    .prefetch(AUTO)\n)\n\nprint(\"Ready ✅\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:41:40.933276Z","iopub.execute_input":"2026-07-15T12:41:40.933554Z","iopub.status.idle":"2026-07-15T12:41:41.410792Z","shell.execute_reply.started":"2026-07-15T12:41:40.933525Z","shell.execute_reply":"2026-07-15T12:41:41.409897Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,10))\n\nfor images, labels in train_ds.take(1):\n\n    for i in range(9):\n        plt.subplot(3,3,i+1)\n        plt.imshow(images[i])\n        plt.title(f\"Class: {labels[i].numpy()}\")\n        plt.axis(\"off\")\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:41:47.965974Z","iopub.execute_input":"2026-07-15T12:41:47.966389Z","iopub.status.idle":"2026-07-15T12:41:51.107002Z","shell.execute_reply.started":"2026-07-15T12:41:47.966358Z","shell.execute_reply":"2026-07-15T12:41:51.105962Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_model = tf.keras.applications.ResNet50(\n    weights=\"imagenet\",\n    include_top=False,\n    input_shape=(IMG_SIZE, IMG_SIZE, 3)\n)\n\nbase_model.trainable = False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:42:40.859195Z","iopub.execute_input":"2026-07-15T12:42:40.859628Z","iopub.status.idle":"2026-07-15T12:42:48.927556Z","shell.execute_reply.started":"2026-07-15T12:42:40.859597Z","shell.execute_reply":"2026-07-15T12:42:48.926901Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = tf.keras.Sequential([\n\n    tf.keras.layers.Input(shape=(IMG_SIZE, IMG_SIZE, 3)),\n\n    tf.keras.layers.Rescaling(255.0),\n\n    tf.keras.layers.Lambda(\n        tf.keras.applications.resnet50.preprocess_input\n    ),\n\n    base_model,\n\n    tf.keras.layers.GlobalAveragePooling2D(),\n\n    tf.keras.layers.Dropout(0.3),\n\n    tf.keras.layers.Dense(NUM_CLASSES, activation=\"softmax\")\n\n])\n\nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(1e-3),\n    loss=\"sparse_categorical_crossentropy\",\n    metrics=[\"accuracy\"]\n)\n\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:42:58.743808Z","iopub.execute_input":"2026-07-15T12:42:58.744248Z","iopub.status.idle":"2026-07-15T12:42:58.805764Z","shell.execute_reply.started":"2026-07-15T12:42:58.744219Z","shell.execute_reply":"2026-07-15T12:42:58.805128Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"callbacks = [\n\n    tf.keras.callbacks.ReduceLROnPlateau(\n        monitor=\"val_loss\",\n        factor=0.5,\n        patience=2,\n        verbose=1\n    ),\n\n    tf.keras.callbacks.EarlyStopping(\n        monitor=\"val_loss\",\n        patience=5,\n        restore_best_weights=True\n    )\n\n]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:43:14.489305Z","iopub.execute_input":"2026-07-15T12:43:14.489710Z","iopub.status.idle":"2026-07-15T12:43:14.493945Z","shell.execute_reply.started":"2026-07-15T12:43:14.489681Z","shell.execute_reply":"2026-07-15T12:43:14.493381Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(\n    train_ds,\n    validation_data=val_ds,\n    epochs=10,\n    callbacks=callbacks\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:43:23.452409Z","iopub.execute_input":"2026-07-15T12:43:23.452839Z","iopub.status.idle":"2026-07-15T12:47:56.865324Z","shell.execute_reply.started":"2026-07-15T12:43:23.452809Z","shell.execute_reply":"2026-07-15T12:47:56.864724Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save(\"resnet50_flower_best.keras\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T12:51:16.362836Z","iopub.execute_input":"2026-07-15T12:51:16.363308Z","iopub.status.idle":"2026-07-15T12:51:17.345825Z","shell.execute_reply.started":"2026-07-15T12:51:16.363278Z","shell.execute_reply":"2026-07-15T12:51:17.345205Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_ds = (\n    tf.data.TFRecordDataset(TEST_FILES)\n    .map(read_test, num_parallel_calls=AUTO)\n    .batch(BATCH_SIZE)\n    .prefetch(AUTO)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T13:05:32.773109Z","iopub.execute_input":"2026-07-15T13:05:32.773851Z","iopub.status.idle":"2026-07-15T13:05:32.806017Z","shell.execute_reply.started":"2026-07-15T13:05:32.773820Z","shell.execute_reply":"2026-07-15T13:05:32.805425Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_ds = (\n    tf.data.TFRecordDataset(TEST_FILES)\n    .map(read_test, num_parallel_calls=AUTO)\n    .batch(BATCH_SIZE)\n    .prefetch(AUTO)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T13:06:04.812031Z","iopub.execute_input":"2026-07-15T13:06:04.812382Z","iopub.status.idle":"2026-07-15T13:06:04.841206Z","shell.execute_reply.started":"2026-07-15T13:06:04.812354Z","shell.execute_reply":"2026-07-15T13:06:04.840665Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred_labels = []\nimage_ids = []\n\nfor images, ids in test_ds:\n    \n    predictions = model.predict(images, verbose=0)\n    \n    labels = np.argmax(predictions, axis=1)\n    \n    pred_labels.extend(labels)\n    image_ids.extend(ids.numpy().astype(str))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T13:06:59.798177Z","iopub.execute_input":"2026-07-15T13:06:59.798781Z","iopub.status.idle":"2026-07-15T13:07:36.481389Z","shell.execute_reply.started":"2026-07-15T13:06:59.798752Z","shell.execute_reply":"2026-07-15T13:07:36.480554Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    \"id\": image_ids,\n    \"label\": pred_labels\n})\n\nsubmission.to_csv(\n    \"/kaggle/working/submission.csv\",\n    index=False\n)\n\nsubmission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-15T13:07:47.057925Z","iopub.execute_input":"2026-07-15T13:07:47.058511Z","iopub.status.idle":"2026-07-15T13:07:47.107692Z","shell.execute_reply.started":"2026-07-15T13:07:47.058480Z","shell.execute_reply":"2026-07-15T13:07:47.106991Z"}},"outputs":[],"execution_count":null}]}