{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"tpu1vmV38","dataSources":[{"sourceId":21154,"databundleVersionId":1243559,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"\n\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom kaggle_datasets import KaggleDatasets\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, RandomFlip, RandomContrast\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom sklearn.metrics import f1_score\nimport matplotlib.pyplot as plt\n\nprint(\"TensorFlow version:\", tf.__version__)","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:01:09.708020Z","iopub.execute_input":"2024-07-10T07:01:09.708335Z","iopub.status.idle":"2024-07-10T07:01:13.747527Z","shell.execute_reply.started":"2024-07-10T07:01:09.708308Z","shell.execute_reply":"2024-07-10T07:01:13.746697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n# Detect and initialize the TPU","metadata":{}},{"cell_type":"code","source":"# Detect hardware, return appropriate distribution strategy\ntry:\n    # TPU detection. No parameters necessary if TPU_NAME environment variable is set. \n    # On Kaggle this is always the case.\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.TPUStrategy(tpu)\n    print('Running on TPU ', tpu.master())\nexcept (ValueError, TypeError) as e:\n    # If there is an error, it usually means TPU is not available.\n    print(\"Can't connect to a TPU: {}\".format(e))\n    # Fallback to a different strategy or handling\n    strategy = tf.distribute.get_strategy() # Default strategy that works on CPU and GPU\n    ","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:01:13.748910Z","iopub.execute_input":"2024-07-10T07:01:13.749348Z","iopub.status.idle":"2024-07-10T07:01:20.867396Z","shell.execute_reply.started":"2024-07-10T07:01:13.749318Z","shell.execute_reply":"2024-07-10T07:01:20.866214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Access the GCS path for the Kaggle dataset","metadata":{}},{"cell_type":"code","source":"\nGCS_DS_PATH = KaggleDatasets().get_gcs_path('tpu-getting-started')\ndata_dir = GCS_DS_PATH + \"/tfrecords-jpeg-192x192\"","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:01:20.868440Z","iopub.execute_input":"2024-07-10T07:01:20.868724Z","iopub.status.idle":"2024-07-10T07:01:20.872675Z","shell.execute_reply.started":"2024-07-10T07:01:20.868695Z","shell.execute_reply":"2024-07-10T07:01:20.871909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Set image height, width, and batch size","metadata":{}},{"cell_type":"code","source":"\nimg_height, img_width = 192, 192\nbatch_size =128","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:01:20.874275Z","iopub.execute_input":"2024-07-10T07:01:20.874538Z","iopub.status.idle":"2024-07-10T07:01:20.883133Z","shell.execute_reply.started":"2024-07-10T07:01:20.874493Z","shell.execute_reply":"2024-07-10T07:01:20.882326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Set up data input functions","metadata":{}},{"cell_type":"code","source":"\ndef decode_image(image):\n    image = tf.image.decode_jpeg(image, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0\n    image = tf.reshape(image, [img_height, img_width, 3])\n    return image","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:01:20.884009Z","iopub.execute_input":"2024-07-10T07:01:20.884259Z","iopub.status.idle":"2024-07-10T07:01:20.892111Z","shell.execute_reply.started":"2024-07-10T07:01:20.884229Z","shell.execute_reply":"2024-07-10T07:01:20.891361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_tfrecord(example, labeled=True):\n    tfrecord_format = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"class\": tf.io.FixedLenFeature([], tf.int64),\n    } if labeled else {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"id\": tf.io.FixedLenFeature([], tf.string),\n    }\n    example = tf.io.parse_single_example(example, tfrecord_format)\n    image = decode_image(example['image'])\n    if labeled:\n        label = tf.one_hot(example['class'], 104)\n        return image, label\n    return image, example['id']\n\ndef load_dataset(filenames, labeled=True, ordered=False):\n    dataset = tf.data.TFRecordDataset(filenames)\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False  # disable order, increase speed\n    dataset = dataset.with_options(ignore_order)\n    return dataset.map(lambda x: read_tfrecord(x, labeled), num_parallel_calls=tf.data.experimental.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:01:20.892945Z","iopub.execute_input":"2024-07-10T07:01:20.893163Z","iopub.status.idle":"2024-07-10T07:01:20.902233Z","shell.execute_reply.started":"2024-07-10T07:01:20.893140Z","shell.execute_reply":"2024-07-10T07:01:20.901545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load datasets","metadata":{}},{"cell_type":"code","source":"\ntrain_files = tf.io.gfile.glob(data_dir + '/train/*.tfrec')\nval_files = tf.io.gfile.glob(data_dir + '/val/*.tfrec')\ntest_files = tf.io.gfile.glob(data_dir + '/test/*.tfrec')","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:01:20.903138Z","iopub.execute_input":"2024-07-10T07:01:20.903453Z","iopub.status.idle":"2024-07-10T07:01:20.927202Z","shell.execute_reply.started":"2024-07-10T07:01:20.903427Z","shell.execute_reply":"2024-07-10T07:01:20.926438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Assuming the structure and size of the dataset are known:","metadata":{}},{"cell_type":"code","source":"\nnum_train_examples = 11970  # example value\nnum_val_examples = 3480     # example value\nnum_test_files = len(test_files)\nnum_test_examples = num_test_files * 462  # Assuming batch size for test dataset is 2048\nTRAIN_STEPS = num_train_examples // batch_size\nVAL_STEPS = num_val_examples // batch_size\n\ntrain_dataset = load_dataset(train_files).repeat().shuffle(462).batch(batch_size).prefetch(tf.data.experimental.AUTOTUNE)\nval_dataset = load_dataset(val_files).batch(batch_size).cache().prefetch(tf.data.experimental.AUTOTUNE)\ntest_dataset = load_dataset(test_files, labeled=False, ordered=True).batch(batch_size)","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:01:20.928067Z","iopub.execute_input":"2024-07-10T07:01:20.928316Z","iopub.status.idle":"2024-07-10T07:01:21.144208Z","shell.execute_reply.started":"2024-07-10T07:01:20.928290Z","shell.execute_reply":"2024-07-10T07:01:21.143412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define the model architecture","metadata":{}},{"cell_type":"code","source":"\nwith strategy.scope():\n    model= keras.Sequential([\n        layers.RandomFlip('horizontal'),\n        layers.RandomContrast(0.5),\n        layers.BatchNormalization(),\n        layers.Conv2D(filters=128,\n                  kernel_size=3,\n                  strides=1,\n                  padding='same',\n                  activation='relu'),\n        layers.MaxPool2D(pool_size=2,\n                     strides=1,\n                     padding='same'),\n        layers.BatchNormalization(),\n        layers.Conv2D(filters=64,\n                  kernel_size=3,\n                  strides=1,\n                  padding='same',\n                  activation='relu'),\n        layers.MaxPool2D(pool_size=2,\n                     strides=1,\n                     padding='same'),\n        layers.BatchNormalization(),\n        layers.Conv2D(filters=32,\n                  kernel_size=3,\n                  strides=1,\n                  padding='same',\n                  activation='relu'),\n        layers.MaxPool2D(pool_size=2,\n                     strides=1,\n                     padding='same'),\n        layers.BatchNormalization(),\n        layers.Flatten(),\n        layers.Dense(units=6, activation=\"relu\"),\n        layers.Dropout(0.3),\n        layers.Dense(units=104, activation=\"softmax\"),\n    ])\n    model.compile(\n    optimizer= tf.keras.optimizers.Adam(learning_rate=0.001, epsilon=0.01),\n    loss = 'categorical_crossentropy',\n    metrics=['accuracy'],\n    )\n    early_stopping = EarlyStopping(\n  \t  min_delta=0.01, # minimium amount of change to count as an improvement\n   \t  patience=5, # how many epochs to wait before stopping\n   \t  restore_best_weights=True,\n    )\n    \n    history=model.fit(\n    train_dataset,\n    validation_data=(val_dataset),\n    epochs=50,\n    callbacks=[early_stopping],\n    steps_per_epoch=TRAIN_STEPS, \n    validation_steps=VAL_STEPS,\n    )\n","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:04:56.264925Z","iopub.execute_input":"2024-07-10T07:04:56.265878Z","iopub.status.idle":"2024-07-10T07:14:23.036084Z","shell.execute_reply.started":"2024-07-10T07:04:56.265842Z","shell.execute_reply":"2024-07-10T07:14:23.034848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train the model","metadata":{}},{"cell_type":"markdown","source":"# Prediction and submission preparation","metadata":{}},{"cell_type":"code","source":"test_ds = test_dataset\n\nprint('Computing predictions...')\ntest_images_ds = test_ds.map(lambda image, idnum: image)\nprobabilities = model.predict(test_images_ds)\npredictions = np.argmax(probabilities, axis=-1)\nprint(predictions)\n\nprint('Generating submission.csv file...')\n","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:21:18.784907Z","iopub.execute_input":"2024-07-10T07:21:18.785719Z","iopub.status.idle":"2024-07-10T07:21:27.510722Z","shell.execute_reply.started":"2024-07-10T07:21:18.785684Z","shell.execute_reply":"2024-07-10T07:21:27.509148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get image ids from test set and convert to unicode\ntest_ids_ds = test_ds.map(lambda image, idnum: idnum).unbatch()\ntest_ids = next(iter(test_ids_ds.batch(7392))).numpy().astype('U')\n\n# Write the submission file\nnp.savetxt(\n    'submission.csv',\n    np.rec.fromarrays([test_ids, predictions]),\n    fmt=['%s', '%d'],\n    delimiter=',',\n    header='id,label',\n    comments='',\n)\n\n# Look at the first few predictions\n!head submission.csv\n","metadata":{"execution":{"iopub.status.busy":"2024-07-10T07:15:55.843293Z","iopub.execute_input":"2024-07-10T07:15:55.844273Z","iopub.status.idle":"2024-07-10T07:16:06.023126Z","shell.execute_reply.started":"2024-07-10T07:15:55.844235Z","shell.execute_reply":"2024-07-10T07:16:06.021694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predict and prepare submission","metadata":{}},{"cell_type":"markdown","source":"\nplt.figure(figsize=(12, 6))\nplt.subplot(1, 2, 1)\nplt.plot(history.history['accuracy'], label='Training Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.title('Model Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'], label='Training Loss')\nplt.plot(history.history['val_loss'], label='Validation Loss')\nplt.title('Model Loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.tight_layout()\nplt.show()","metadata":{}}]}