{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":21154,"databundleVersionId":1243559,"sourceType":"competition"}],"dockerImageVersionId":31192,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"\nimport os\nos.environ[\"CUDA_VISIBLE_DEVICES\"] = \"-1\"\nos.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'\n\n!pip install --quiet protobuf==3.20.3\n\n\nimport tensorflow as tf\nimport numpy as np\nfrom kaggle_datasets import KaggleDatasets\n\nprint(\"TF:\", tf.__version__)\n\n\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print(\"TPU found:\", tpu.master())\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    STRAT = tf.distribute.TPUStrategy(tpu)\nexcept:\n    print(\"TPU tidak tersedia — pakai strategy default.\")\n    STRAT = tf.distribute.get_strategy()\n\nprint(\"Replicas:\", STRAT.num_replicas_in_sync)\n\n\ntry:\n    ROOT = KaggleDatasets().get_gcs_path(\"tpu-getting-started\")\nexcept:\n    ROOT = \"/kaggle/input/tpu-getting-started\"\n\nprint(\"DATA ROOT:\", ROOT)\n\nIMG_SIZE = 192\nRESIZE_TO = 64\nNUM_LABEL = 104\nEPOCH_TRAIN = 20\nBATCH_SIZE = 16 * STRAT.num_replicas_in_sync\n\nTFREC_DIR = f\"{ROOT}/tfrecords-jpeg-{IMG_SIZE}x{IMG_SIZE}\"\ntrain_files = tf.io.gfile.glob(TFREC_DIR + \"/train/*.tfrec\")\nval_files   = tf.io.gfile.glob(TFREC_DIR + \"/val/*.tfrec\")\ntest_files  = tf.io.gfile.glob(TFREC_DIR + \"/test/*.tfrec\")\n\nAUTO = tf.data.AUTOTUNE\n\n\ndef decode_image(raw):\n    img = tf.image.decode_jpeg(raw, channels=3)\n    img = tf.image.convert_image_dtype(img, tf.float32)\n    img = tf.image.resize(img, (RESIZE_TO, RESIZE_TO))\n    return img\n\ndef read_train(example):\n    features = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"class\": tf.io.FixedLenFeature([], tf.int64)\n    }\n    data = tf.io.parse_single_example(example, features)\n    return decode_image(data[\"image\"]), tf.cast(data[\"class\"], tf.int32)\n\ndef read_test(example):\n    features = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"id\": tf.io.FixedLenFeature([], tf.string)\n    }\n    data = tf.io.parse_single_example(example, features)\n    return decode_image(data[\"image\"]), data[\"id\"]\n\ndef load_ds(files, train=True):\n    ds = tf.data.TFRecordDataset(files, num_parallel_reads=AUTO)\n    ds = ds.map(read_train if train else read_test, num_parallel_calls=AUTO)\n    return ds\n\n\ndef get_train_ds():\n    ds = load_ds(train_files, train=True)\n    ds = ds.shuffle(20000)\n    ds = ds.repeat()\n    ds = ds.batch(BATCH_SIZE)\n    ds = ds.prefetch(AUTO)\n    return ds\n\ndef get_val_ds():\n    ds = load_ds(val_files, train=True)\n    ds = ds.batch(BATCH_SIZE)\n    ds = ds.cache()\n    ds = ds.prefetch(AUTO)\n    return ds\n\ndef get_test_ds():\n    ds = load_ds(test_files, train=False)\n    ds = ds.batch(BATCH_SIZE)\n    ds = ds.prefetch(AUTO)\n    return ds\n\n\ndef count(files):\n    return sum([int(f.split(\"-\")[-1].split(\".\")[0]) for f in files])\n\nN_TRAIN = count(train_files)\nN_VAL   = count(val_files)\nN_TEST  = count(test_files)\n\nSTEP_TRAIN = N_TRAIN // BATCH_SIZE\n\nprint(\"TRAIN:\", N_TRAIN, \"VAL:\", N_VAL, \"TEST:\", N_TEST)\nprint(\"STEP TRAIN:\", STEP_TRAIN)\n\n\nwith STRAT.scope():\n    model = tf.keras.Sequential([\n        tf.keras.layers.Input((RESIZE_TO, RESIZE_TO, 3)),\n        tf.keras.layers.Flatten(),\n\n        tf.keras.layers.Dense(2048, activation=\"relu\"),\n        tf.keras.layers.BatchNormalization(),\n        tf.keras.layers.Dropout(0.35),\n\n        tf.keras.layers.Dense(1024, activation=\"relu\"),\n        tf.keras.layers.BatchNormalization(),\n        tf.keras.layers.Dropout(0.30),\n\n        tf.keras.layers.Dense(512, activation=\"relu\"),\n        tf.keras.layers.BatchNormalization(),\n        tf.keras.layers.Dropout(0.25),\n\n        tf.keras.layers.Dense(NUM_LABEL, activation=\"softmax\")\n    ])\n\n    model.compile(\n        optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),\n        loss=\"sparse_categorical_crossentropy\",\n        metrics=[\"sparse_categorical_accuracy\"]\n    )\n\nmodel.summary()\n\n\nhistory = model.fit(\n    get_train_ds(),\n    epochs=EPOCH_TRAIN,\n    steps_per_epoch=STEP_TRAIN,\n    validation_data=get_val_ds(),\n    verbose=1\n)\n\n\ntest_ds = get_test_ds()\n\nprobs = model.predict(test_ds.map(lambda x, y: x))\npreds = np.argmax(probs, axis=1)\n\nids = next(iter(test_ds.map(lambda x, y: y).unbatch().batch(N_TEST))).numpy().astype(\"U\")\n\nnp.savetxt(\n    \"submission.csv\",\n    np.rec.fromarrays([ids, preds]),\n    fmt=[\"%s\", \"%d\"],\n    delimiter=\",\",\n    header=\"id,label\",\n    comments=\"\"\n)\n\nprint(\"DONE — submission.csv created!\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-12-03T11:34:53.456067Z","iopub.execute_input":"2025-12-03T11:34:53.456460Z","execution_failed":"2025-12-03T12:36:07.455Z"}},"outputs":[],"execution_count":null}]}