{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"tpuV5e8","dataSources":[{"sourceId":21154,"databundleVersionId":1243559,"sourceType":"competition"}],"dockerImageVersionId":31194,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import Library","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport 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","trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:33:03.331164Z","iopub.execute_input":"2025-12-03T13:33:03.331416Z","iopub.status.idle":"2025-12-03T13:33:03.972889Z","shell.execute_reply.started":"2025-12-03T13:33:03.331394Z","shell.execute_reply":"2025-12-03T13:33:03.971987Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Deteksi TPU","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\ntry:\n    resolver = tf.distribute.cluster_resolver.TPUClusterResolver()\n    tf.config.experimental_connect_to_cluster(resolver)\n    tf.tpu.experimental.initialize_tpu_system(resolver)\n    strategy = tf.distribute.TPUStrategy(resolver)\n    print(\"TPU initialized.\")\n    print(\"REPLICAS:\", strategy.num_replicas_in_sync)\nexcept Exception as e:\n    print(\"TPU failed:\", e)\n    strategy = tf.distribute.get_strategy()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:33:08.516650Z","iopub.execute_input":"2025-12-03T13:33:08.516987Z","iopub.status.idle":"2025-12-03T13:33:39.317283Z","shell.execute_reply.started":"2025-12-03T13:33:08.516967Z","shell.execute_reply":"2025-12-03T13:33:39.316261Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Fungsi Decode ","metadata":{}},{"cell_type":"code","source":"IMAGE_SIZE = [224, 224]\nAUTO = tf.data.experimental.AUTOTUNE\nBATCH_SIZE = 32\nNUM_CLASSES = 104\n\ndef decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.image.resize(image, IMAGE_SIZE)\n    image = tf.cast(image, tf.float32) / 255.0\n    return image\n\ndef read_train_tfrecord(example):\n    features = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"class\": tf.io.FixedLenFeature([], tf.int64)\n    }\n    example = tf.io.parse_single_example(example, features)\n    image = decode_image(example[\"image\"])\n    label = example[\"class\"]\n    return image, label\n\ndef read_test_tfrecord(example):\n    features = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"id\": tf.io.FixedLenFeature([], tf.string)\n    }\n    example = tf.io.parse_single_example(example, features)\n    image = decode_image(example[\"image\"])\n    img_id = example[\"id\"]\n    return image, img_id\n\ndef load_dataset(files, train=True):\n    dataset = tf.data.TFRecordDataset(files)\n    if train:\n        dataset = dataset.map(read_train_tfrecord, num_parallel_calls=AUTO)\n    else:\n        dataset = dataset.map(read_test_tfrecord, num_parallel_calls=AUTO)\n    return dataset\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:33:42.297844Z","iopub.execute_input":"2025-12-03T13:33:42.298372Z","iopub.status.idle":"2025-12-03T13:33:42.303755Z","shell.execute_reply.started":"2025-12-03T13:33:42.298355Z","shell.execute_reply":"2025-12-03T13:33:42.302982Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Load Data","metadata":{}},{"cell_type":"code","source":"train_files = tf.io.gfile.glob('/kaggle/input/tpu-getting-started/tfrecords-jpeg-224x224/train/*.tfrec')\nval_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_ds = load_dataset(train_files, train=True).shuffle(2048).batch(BATCH_SIZE).prefetch(AUTO)\nval_ds   = load_dataset(val_files,   train=True).batch(BATCH_SIZE).prefetch(AUTO)\ntest_ds  = load_dataset(test_files,  train=False).batch(BATCH_SIZE)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:33:46.221686Z","iopub.execute_input":"2025-12-03T13:33:46.221970Z","iopub.status.idle":"2025-12-03T13:33:46.399450Z","shell.execute_reply.started":"2025-12-03T13:33:46.221946Z","shell.execute_reply":"2025-12-03T13:33:46.398410Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Buat Model","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras import layers, models\n\nmodel = models.Sequential([\n    layers.Flatten(input_shape=(224, 224, 3)),\n    layers.Dense(512, activation='relu'),\n    layers.Dense(256, activation='relu'),\n    layers.Dense(NUM_CLASSES, activation='softmax')\n])\n\nmodel.compile(\n    optimizer='adam',\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy']\n)\n\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:33:49.221919Z","iopub.execute_input":"2025-12-03T13:33:49.222183Z","iopub.status.idle":"2025-12-03T13:33:49.329910Z","shell.execute_reply.started":"2025-12-03T13:33:49.222165Z","shell.execute_reply":"2025-12-03T13:33:49.329004Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Train Model","metadata":{}},{"cell_type":"code","source":"history = model.fit(\n    train_ds,\n    validation_data=val_ds,\n    epochs=7\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:33:54.018020Z","iopub.execute_input":"2025-12-03T13:33:54.018298Z","iopub.status.idle":"2025-12-03T13:43:21.146995Z","shell.execute_reply.started":"2025-12-03T13:33:54.018282Z","shell.execute_reply":"2025-12-03T13:43:21.145724Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Grafik Model","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.plot(history.history['accuracy'], label='Train Acc')\nplt.plot(history.history['val_accuracy'], label='Val Acc')\nplt.legend()\nplt.show()\n\nplt.plot(history.history['loss'], label='Train Loss')\nplt.plot(history.history['val_loss'], label='Val Loss')\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:43:24.583480Z","iopub.execute_input":"2025-12-03T13:43:24.583796Z","iopub.status.idle":"2025-12-03T13:43:24.935478Z","shell.execute_reply.started":"2025-12-03T13:43:24.583778Z","shell.execute_reply":"2025-12-03T13:43:24.934394Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Test Model","metadata":{}},{"cell_type":"code","source":"test_images = []\ntest_ids = []\n\ntest_images_ds = test_ds.map(lambda image, idnum: image)\nprobabilities = model.predict(test_images_ds)\npredictions = np.argmax(probabilities, axis=-1)\n# Mengambil hanya ID dari dataset\ntest_ids_ds = test_ds.map(lambda image, idnum: idnum).unbatch()\nraw_ids = next(iter(test_ids_ds.batch(len(predictions)))).numpy()\ntest_ids = [id_byte.decode('utf-8') for id_byte in raw_ids]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:43:29.081317Z","iopub.execute_input":"2025-12-03T13:43:29.081661Z","iopub.status.idle":"2025-12-03T13:43:33.020441Z","shell.execute_reply.started":"2025-12-03T13:43:29.081642Z","shell.execute_reply":"2025-12-03T13:43:33.019537Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred = model.predict(test_images_ds)\npred_labels = np.argmax(pred, axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:43:34.659139Z","iopub.execute_input":"2025-12-03T13:43:34.659535Z","iopub.status.idle":"2025-12-03T13:43:37.393088Z","shell.execute_reply.started":"2025-12-03T13:43:34.659505Z","shell.execute_reply":"2025-12-03T13:43:37.392064Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"submission = pd.DataFrame({\n    \"id\": test_ids,\n    \"label\": pred_labels\n})\n\nsubmission.to_csv('/kaggle/working/submission.csv', index=False)\nsubmission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-03T13:43:40.794951Z","iopub.execute_input":"2025-12-03T13:43:40.795213Z","iopub.status.idle":"2025-12-03T13:43:40.822792Z","shell.execute_reply.started":"2025-12-03T13:43:40.795188Z","shell.execute_reply":"2025-12-03T13:43:40.821839Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}