{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Imports #\n\nWe begin by importing several Python packages.","metadata":{"_cell_guid":"1d9ee5a1-e4ea-4bc3-a6f6-56159d3fead9","_uuid":"51c2912f-1532-45ba-8028-83fedb4a223f","trusted":true}},{"cell_type":"code","source":"!pip install pydot","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install graphviz","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import math, re, os\nimport numpy as np\nimport tensorflow as tf\n\nprint(\"Tensorflow version \" + tf.__version__)","metadata":{"_cell_guid":"e0243cfb-901d-47be-971e-770ef7fa7a95","_uuid":"9b51b936-d2fd-4acb-b728-a7f5f90f0fef","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-11-13T04:30:39.702105Z","iopub.execute_input":"2023-11-13T04:30:39.702387Z","iopub.status.idle":"2023-11-13T04:30:49.505989Z","shell.execute_reply.started":"2023-11-13T04:30:39.702360Z","shell.execute_reply":"2023-11-13T04:30:49.505231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Step 2: Distribution Strategy #\n\nA TPU has eight different *cores* and each of these cores acts as its own accelerator. (A TPU is sort of like having eight GPUs in one machine.) We tell TensorFlow how to make use of all these cores at once through a **distribution strategy**. Run the following cell to create the distribution strategy that we'll later apply to our model.","metadata":{"_cell_guid":"55824e4b-1677-4d87-b922-6b6428234efc","_uuid":"f6315394-5d14-4f24-a8ed-45a662e99529","trusted":true}},{"cell_type":"code","source":"# Detect TPU, return appropriate distribution strategy\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver() \n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy() \n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)","metadata":{"_cell_guid":"364569fd-145d-4209-bade-e32bd2689801","_uuid":"85950d42-ddea-4f64-970e-88d33614a2fd","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-11-13T04:30:49.509501Z","iopub.execute_input":"2023-11-13T04:30:49.509729Z","iopub.status.idle":"2023-11-13T04:30:56.838240Z","shell.execute_reply.started":"2023-11-13T04:30:49.509704Z","shell.execute_reply":"2023-11-13T04:30:56.837461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We'll use the distribution strategy when we create our neural network model. Then, TensorFlow will distribute the training among the eight TPU cores by creating eight different *replicas* of the model, one for each core.\n\n# Step 3: Loading the Competition Data #\n\n## Get GCS Path ##\n\nWhen used with TPUs, datasets need to be stored in a [Google Cloud Storage bucket](https://cloud.google.com/storage/). You can use data from any public GCS bucket by giving its path just like you would data from `'/kaggle/input'`. The following will retrieve the GCS path for this competition's dataset.","metadata":{"_cell_guid":"05347650-c05d-4ff7-b80d-fd904288266b","_uuid":"4ec19ade-0dbd-47bf-8173-c4047c8df60b","trusted":true}},{"cell_type":"code","source":"from kaggle_datasets import KaggleDatasets\n\nGCS_DS_PATH = KaggleDatasets().get_gcs_path('tpu-getting-started')\nprint(GCS_DS_PATH) # what do gcs paths look like?","metadata":{"_cell_guid":"a15470dd-f1df-4a58-a040-a40c34661455","_uuid":"820898a8-b8ce-46d8-9d19-9ea178785b3c","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-11-13T04:30:56.839159Z","iopub.execute_input":"2023-11-13T04:30:56.839390Z","iopub.status.idle":"2023-11-13T04:30:56.845275Z","shell.execute_reply.started":"2023-11-13T04:30:56.839365Z","shell.execute_reply":"2023-11-13T04:30:56.844073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You can use data from any public dataset here on Kaggle in just the same way. If you'd like to use data from one of your private datasets, see [here](https://www.kaggle.com/docs/tpu#tpu3pt5).\n\n## Load Data ##\n\nWhen used with TPUs, datasets are often serialized into [TFRecords](https://www.kaggle.com/ryanholbrook/tfrecords-basics). This is a format convenient for distributing data to each of the TPUs cores. We've hidden the cell that reads the TFRecords for our dataset since the process is a bit long. You could come back to it later for some guidance on using your own datasets with TPUs.","metadata":{"_cell_guid":"3282478a-20b0-4ac7-bac7-a9e3008f84b2","_uuid":"dde6c2b3-4b70-4090-a62b-14475771aff3","trusted":true}},{"cell_type":"code","source":"CLASSES = ['pink primrose',    'hard-leaved pocket orchid', 'canterbury bells', 'sweet pea',     'wild geranium',     'tiger lily',           'moon orchid',              'bird of paradise', 'monkshood',        'globe thistle',         # 00 - 09\n           'snapdragon',       \"colt's foot\",               'king protea',      'spear thistle', 'yellow iris',       'globe-flower',         'purple coneflower',        'peruvian lily',    'balloon flower',   'giant white arum lily', # 10 - 19\n           'fire lily',        'pincushion flower',         'fritillary',       'red ginger',    'grape hyacinth',    'corn poppy',           'prince of wales feathers', 'stemless gentian', 'artichoke',        'sweet william',         # 20 - 29\n           'carnation',        'garden phlox',              'love in the mist', 'cosmos',        'alpine sea holly',  'ruby-lipped cattleya', 'cape flower',              'great masterwort', 'siam tulip',       'lenten rose',           # 30 - 39\n           'barberton daisy',  'daffodil',                  'sword lily',       'poinsettia',    'bolero deep blue',  'wallflower',           'marigold',                 'buttercup',        'daisy',            'common dandelion',      # 40 - 49\n           'petunia',          'wild pansy',                'primula',          'sunflower',     'lilac hibiscus',    'bishop of llandaff',   'gaura',                    'geranium',         'orange dahlia',    'pink-yellow dahlia',    # 50 - 59\n           'cautleya spicata', 'japanese anemone',          'black-eyed susan', 'silverbush',    'californian poppy', 'osteospermum',         'spring crocus',            'iris',             'windflower',       'tree poppy',            # 60 - 69\n           'gazania',          'azalea',                    'water lily',       'rose',          'thorn apple',       'morning glory',        'passion flower',           'lotus',            'toad lily',        'anthurium',             # 70 - 79\n           'frangipani',       'clematis',                  'hibiscus',         'columbine',     'desert-rose',       'tree mallow',          'magnolia',                 'cyclamen ',        'watercress',       'canna lily',            # 80 - 89\n           'hippeastrum ',     'bee balm',                  'pink quill',       'foxglove',      'bougainvillea',     'camellia',             'mallow',                   'mexican petunia',  'bromelia',         'blanket flower',        # 90 - 99\n           'trumpet creeper',  'blackberry lily',           'common tulip',     'wild rose'] \nAUTO = tf.data.experimental.AUTOTUNE\n# Define the batch size. This will be 16 with TPU off and 128 (=16*8) with TPU on\nBATCH_SIZE = 16 * strategy.num_replicas_in_sync\n","metadata":{"_cell_guid":"01f15e6f-302c-4078-82cf-906e2ac24952","_uuid":"bd04f3fa-9d2c-4a47-b9b4-d6b6f964894a","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-11-13T04:30:56.847261Z","iopub.execute_input":"2023-11-13T04:30:56.847536Z","iopub.status.idle":"2023-11-13T04:30:56.858688Z","shell.execute_reply.started":"2023-11-13T04:30:56.847510Z","shell.execute_reply":"2023-11-13T04:30:56.858030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Explore Data #\n\nLet's take a moment to look at some of the images in the dataset.","metadata":{"_cell_guid":"71c735f9-88d4-458f-b488-f0c719e477cd","_uuid":"fd393e0b-0f1f-4999-af84-8657f819fe50","trusted":true}},{"cell_type":"code","source":"from matplotlib import pyplot as plt\n\ndef batch_to_numpy_images_and_labels(data):\n    images, labels = data\n    numpy_images = images.numpy()\n    numpy_labels = labels.numpy()\n    if numpy_labels.dtype == object: # binary string in this case,\n                                     # these are image ID strings\n        numpy_labels = [None for _ in enumerate(numpy_images)]\n    # If no labels, only image IDs, return None for labels (this is\n    # the case for test data)\n    return numpy_images, numpy_labels\n\ndef title_from_label_and_target(label, correct_label):\n    if correct_label is None:\n        return CLASSES[label], True\n    correct = (label == correct_label)\n    return \"{} [{}{}{}]\".format(CLASSES[label], 'OK' if correct else 'NO', u\"\\u2192\" if not correct else '',\n                                CLASSES[correct_label] if not correct else ''), correct\n\ndef display_one_flower(image, title, subplot, red=False, titlesize=16):\n    plt.subplot(*subplot)\n    plt.axis('off')\n    plt.imshow(image)\n    if len(title) > 0:\n        plt.title(title, fontsize=int(titlesize) if not red else int(titlesize/1.2), color='red' if red else 'black', fontdict={'verticalalignment':'center'}, pad=int(titlesize/1.5))\n    return (subplot[0], subplot[1], subplot[2]+1)\n    \ndef display_batch_of_images(databatch, predictions=None):\n    \"\"\"This will work with:\n    display_batch_of_images(images)\n    display_batch_of_images(images, predictions)\n    display_batch_of_images((images, labels))\n    display_batch_of_images((images, labels), predictions)\n    \"\"\"\n    # data\n    images, labels = batch_to_numpy_images_and_labels(databatch)\n    if labels is None:\n        labels = [None for _ in enumerate(images)]\n        \n    # auto-squaring: this will drop data that does not fit into square\n    # or square-ish rectangle\n    rows = int(math.sqrt(len(images)))\n    cols = len(images)//rows\n        \n    # size and spacing\n    FIGSIZE = 13.0\n    SPACING = 0.1\n    subplot=(rows,cols,1)\n    if rows < cols:\n        plt.figure(figsize=(FIGSIZE,FIGSIZE/cols*rows))\n    else:\n        plt.figure(figsize=(FIGSIZE/rows*cols,FIGSIZE))\n    \n    # display\n    for i, (image, label) in enumerate(zip(images[:rows*cols], labels[:rows*cols])):\n        title = '' if label is None else CLASSES[label]\n        correct = True\n        if predictions is not None:\n            title, correct = title_from_label_and_target(predictions[i], label)\n        dynamic_titlesize = FIGSIZE*SPACING/max(rows,cols)*40+3 # magic formula tested to work from 1x1 to 10x10 images\n        subplot = display_one_flower(image, title, subplot, not correct, titlesize=dynamic_titlesize)\n    \n    #layout\n    plt.tight_layout()\n    if label is None and predictions is None:\n        plt.subplots_adjust(wspace=0, hspace=0)\n    else:\n        plt.subplots_adjust(wspace=SPACING, hspace=SPACING)\n    plt.show()\n\n\ndef display_training_curves(training, validation, title, subplot):\n    if subplot%10==1: # set up the subplots on the first call\n        plt.subplots(figsize=(10,10), facecolor='#F0F0F0')\n        plt.tight_layout()\n    ax = plt.subplot(subplot)\n    ax.set_facecolor('#F8F8F8')\n    ax.plot(training)\n    ax.plot(validation)\n    ax.set_title('model '+ title)\n    ax.set_ylabel(title)\n    #ax.set_ylim(0.28,1.05)\n    ax.set_xlabel('epoch')\n    ax.legend(['train', 'valid.'])","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:56.859566Z","iopub.execute_input":"2023-11-13T04:30:56.859797Z","iopub.status.idle":"2023-11-13T04:30:57.244971Z","shell.execute_reply.started":"2023-11-13T04:30:56.859772Z","shell.execute_reply":"2023-11-13T04:30:57.244059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Transform the Data","metadata":{}},{"cell_type":"code","source":"def decode_image(image_data,image_size):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0  # convert image to floats in [0, 1] range\n    image = tf.reshape(image, [*image_size, 3]) # explicit size needed for TPU\n    return image\n\ndef read_labeled_tfrecord(example, image_size):\n    LABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string), # tf.string means bytestring\n        \"class\": tf.io.FixedLenFeature([], tf.int64),  # shape [] means single element\n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image = decode_image(example['image'], image_size)\n    label = tf.cast(example['class'], tf.int32)\n    return image, label # returns a dataset of (image, label) pairs\n\ndef read_unlabeled_tfrecord(example, image_size):\n    UNLABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string), # tf.string means bytestring\n        \"id\": tf.io.FixedLenFeature([], tf.string),  # shape [] means single element\n        # class is missing, this competitions's challenge is to predict flower classes for the test dataset\n    }\n    example = tf.io.parse_single_example(example, UNLABELED_TFREC_FORMAT)\n    image = decode_image(example['image'], image_size)\n    idnum = example['id']\n    return image, idnum # returns a dataset of image(s)\n\ndef load_dataset(filenames, image_size, labeled=True, ordered=False):\n    # Read from TFRecords. For optimal performance, reading from multiple files at once and\n    # disregarding data order. Order does not matter since we will be shuffling the data anyway.\n\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False # disable order, increase speed\n\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTO) # automatically interleaves reads from multiple files\n    dataset = dataset.with_options(ignore_order) # uses data as soon as it streams in, rather than in its original order\n    dataset = dataset.map(lambda x: read_labeled_tfrecord(x, image_size) if labeled else read_unlabeled_tfrecord(x, image_size), num_parallel_calls=AUTO)\n    # returns a dataset of (image, label) pairs if labeled=True or (image, id) pairs if labeled=False\n    return dataset","metadata":{"_cell_guid":"d148f582-26ef-4292-bb5e-5a6000e1c806","_uuid":"1deabb92-5000-4ffc-b5eb-214bdd9e3ef7","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-11-13T04:30:57.246193Z","iopub.execute_input":"2023-11-13T04:30:57.246473Z","iopub.status.idle":"2023-11-13T04:30:57.255519Z","shell.execute_reply.started":"2023-11-13T04:30:57.246444Z","shell.execute_reply":"2023-11-13T04:30:57.254716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Augmentation of Data","metadata":{}},{"cell_type":"code","source":"def data_augment(image, label):\n    # Thanks to the dataset.prefetch(AUTO)\n    # statement in the next function (below), this happens essentially\n    # for free on TPU. Data pipeline code is executed on the \"CPU\"\n    # part of the TPU while the TPU itself is computing gradients.\n    image = tf.image.random_flip_left_right(image)\n    #image = tf.image.random_saturation(image, 0, 2)\n    return image, label   \n\ndef get_training_dataset(train_file_name, image_size):\n    dataset = load_dataset(train_file_name, image_size, labeled=True)\n    dataset = dataset.map(data_augment, num_parallel_calls=AUTO)\n    dataset = dataset.repeat() # the training dataset must repeat for several epochs\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO) # prefetch next batch while training (autotune prefetch buffer size)\n    return dataset\n\ndef get_validation_dataset(validation_file_name, image_size,ordered=False):\n    dataset = load_dataset(validation_file_name, image_size, labeled=True, ordered=ordered)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.cache()\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\ndef get_test_dataset(test_file_name,image_size,ordered=False):\n    dataset = load_dataset(test_file_name,image_size, labeled=False, ordered=ordered)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\ndef count_data_items(filenames):\n    # the number of data items is written in the name of the .tfrec\n    # files, i.e. flowers00-230.tfrec = 230 data items\n    n = [int(re.compile(r\"-([0-9]*)\\.\").search(filename).group(1)) for filename in filenames]\n    return np.sum(n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.256567Z","iopub.execute_input":"2023-11-13T04:30:57.256847Z","iopub.status.idle":"2023-11-13T04:30:57.272786Z","shell.execute_reply.started":"2023-11-13T04:30:57.256820Z","shell.execute_reply":"2023-11-13T04:30:57.272012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Learning Rate","metadata":{}},{"cell_type":"code","source":"EPOCHS = 10\n# Learning Rate Schedule for Fine Tuning #\ndef exponential_lr(epoch,\n                   start_lr = 0.00001, min_lr = 0.00001, max_lr = 0.00005,\n                   rampup_epochs = 5, sustain_epochs = 0,\n                   exp_decay = 0.8):\n\n    def lr(epoch, start_lr, min_lr, max_lr, rampup_epochs, sustain_epochs, exp_decay):\n        # linear increase from start to rampup_epochs\n        if epoch < rampup_epochs:\n            lr = ((max_lr - start_lr) /\n                  rampup_epochs * epoch + start_lr)\n        # constant max_lr during sustain_epochs\n        elif epoch < rampup_epochs + sustain_epochs:\n            lr = max_lr\n        # exponential decay towards min_lr\n        else:\n            lr = ((max_lr - min_lr) *\n                  exp_decay**(epoch - rampup_epochs - sustain_epochs) +\n                  min_lr)\n        return lr\n    return lr(epoch,\n              start_lr,\n              min_lr,\n              max_lr,\n              rampup_epochs,\n              sustain_epochs,\n              exp_decay)\n\nlr_callback = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)\n\nrng = [i for i in range(EPOCHS)]\ny = [exponential_lr(x) for x in rng]\nplt.plot(rng, y)\nprint(\"Learning rate schedule: {:.3g} to {:.3g} to {:.3g}\".format(y[0], max(y), y[-1]))","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.273711Z","iopub.execute_input":"2023-11-13T04:30:57.273957Z","iopub.status.idle":"2023-11-13T04:30:57.479279Z","shell.execute_reply.started":"2023-11-13T04:30:57.273933Z","shell.execute_reply":"2023-11-13T04:30:57.478501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model - VGG 16 PRETRAINED MODEL","metadata":{}},{"cell_type":"code","source":"with strategy.scope():\n    def create_vgg16_model(input_shape, N_CLASSES):\n        pretrained_model = tf.keras.applications.VGG16(\n            weights='imagenet',\n            include_top=False,\n            input_shape=input_shape\n        )\n        pretrained_model.trainable = True\n\n        model = tf.keras.Sequential([\n            pretrained_model,\n            tf.keras.layers.GlobalAveragePooling2D(),\n            tf.keras.layers.Dense(N_CLASSES, activation='softmax')\n        ])\n\n        return model\ndef compile_model(model, optimizer):\n    model.compile(\n        optimizer=optimizer,\n        loss='sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy']\n    )\n\ndef fine_tuning_lr(epoch, base_lr=0.00001, multiplier=0.2):\n    return base_lr * (multiplier ** epoch)\n\n# Example usage:\ninitial_fine_tuning_lr = fine_tuning_lr(0)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.480278Z","iopub.execute_input":"2023-11-13T04:30:57.480566Z","iopub.status.idle":"2023-11-13T04:30:57.487986Z","shell.execute_reply.started":"2023-11-13T04:30:57.480536Z","shell.execute_reply":"2023-11-13T04:30:57.487223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# MODEL VGG - 19 PRETRAINED MODEL","metadata":{}},{"cell_type":"code","source":"with strategy.scope():\n    def create_vgg19_model(input_shape, N_CLASSES):\n        pretrained_model = tf.keras.applications.VGG19(\n            weights='imagenet',\n            include_top=False,\n            input_shape=input_shape\n        )\n        pretrained_model.trainable = True\n\n        model = tf.keras.Sequential([\n            pretrained_model,\n            tf.keras.layers.GlobalAveragePooling2D(),\n            tf.keras.layers.Dense(N_CLASSES, activation='softmax')\n        ])\n\n        return model\ndef compile_model(model, optimizer):\n    model.compile(\n        optimizer=optimizer,\n        loss='sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy']\n    )\n\ndef fine_tuning_lr(epoch, base_lr=0.00001, multiplier=0.2):\n    return base_lr * (multiplier ** epoch)\n\n# Example usage:\ninitial_fine_tuning_lr = fine_tuning_lr(0)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.488900Z","iopub.execute_input":"2023-11-13T04:30:57.489154Z","iopub.status.idle":"2023-11-13T04:30:57.505608Z","shell.execute_reply.started":"2023-11-13T04:30:57.489127Z","shell.execute_reply":"2023-11-13T04:30:57.504874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CUSTOM ARCHITECTURE","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\n\ndef create_custom_model(input_shape, num_classes):\n    model = models.Sequential()\n\n    # Convolutional and pooling layers\n    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))\n    model.add(layers.MaxPooling2D((2, 2)))\n    model.add(layers.Conv2D(64, (3, 3), activation='relu'))\n    model.add(layers.MaxPooling2D((2, 2)))\n    model.add(layers.Conv2D(128, (3, 3), activation='relu'))\n    model.add(layers.MaxPooling2D((2, 2)))\n\n    # Flatten and dense layers\n    model.add(layers.Flatten())\n    model.add(layers.Dense(256, activation='relu'))\n    model.add(layers.Dropout(0.5))  # Optional dropout layer for regularization\n    model.add(layers.Dense(num_classes, activation='softmax'))\n\n    return model\n\ndef compile_model(model, optimizer):\n    model.compile(\n        optimizer=optimizer,\n        loss='sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy']\n    )\n\n\ndef fine_tuning_lr(epoch, base_lr=0.00001, multiplier=0.2):\n    return base_lr * (multiplier ** epoch)\ninitial_fine_tuning_lr = fine_tuning_lr(0)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.506563Z","iopub.execute_input":"2023-11-13T04:30:57.506811Z","iopub.status.idle":"2023-11-13T04:30:57.524676Z","shell.execute_reply.started":"2023-11-13T04:30:57.506777Z","shell.execute_reply":"2023-11-13T04:30:57.523927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.optimizers import Adam\nimport time\nimport matplotlib.pyplot as plt\n\ndef create_custom_model(input_shape, num_classes, num_neurons_list, num_layers, conv_shape):\n    model = models.Sequential()\n    \n    # Convolutional Layer\n    model.add(layers.Conv2D(32, conv_shape, activation='relu', input_shape=input_shape))\n    model.add(layers.MaxPooling2D((2, 2)))\n\n    # Flatten and dense layers\n    model.add(layers.Flatten())\n\n    for _ in range(num_layers):\n        for neurons in num_neurons_list:\n            model.add(layers.Dense(neurons, activation='relu'))\n    \n    model.add(layers.Dense(num_classes, activation='softmax'))\n\n    return model\n\ndef compile_model(model, optimizer):\n    model.compile(\n        optimizer=optimizer,\n        loss='sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy']\n    )\n\ndef fine_tuning_lr(epoch, base_lr=0.00001, multiplier=0.2):\n    return base_lr * (multiplier ** epoch)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.525597Z","iopub.execute_input":"2023-11-13T04:30:57.525861Z","iopub.status.idle":"2023-11-13T04:30:57.539719Z","shell.execute_reply.started":"2023-11-13T04:30:57.525835Z","shell.execute_reply":"2023-11-13T04:30:57.539027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CUSTOM ARCHITECTURE FOR VGG 19\n\n### Fine Tuning the Dense Layers with Batch Normalization to Accelerate the training process","metadata":{}},{"cell_type":"code","source":"def customize_vgg19_model(input_shape, N_CLASSES):\n    pretrained_model = tf.keras.applications.VGG19(\n        weights='imagenet',\n        include_top=False,\n        input_shape=input_shape\n    )\n    pretrained_model.trainable = True\n\n    model = tf.keras.Sequential([\n        pretrained_model,\n        tf.keras.layers.BatchNormalization(),\n        tf.keras.layers.GlobalAveragePooling2D(),\n        tf.keras.layers.Dense(512, activation='relu'),\n        tf.keras.layers.Dropout(0.5),\n        tf.keras.layers.BatchNormalization(),\n        tf.keras.layers.Dense(256, activation='relu'),\n        tf.keras.layers.Dropout(0.5),\n        tf.keras.layers.BatchNormalization(),\n        tf.keras.layers.Dense(N_CLASSES, activation='softmax')\n    ])\n\n    return model\n\ndef compile_model(model, optimizer):\n    model.compile(\n        optimizer=optimizer,\n        loss='sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy']\n    )\n\ndef fine_tuning_lr(epoch, base_lr=0.00001, multiplier=0.2):\n    return base_lr * (multiplier ** epoch)\ninitial_fine_tuning_lr = fine_tuning_lr(0)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.542654Z","iopub.execute_input":"2023-11-13T04:30:57.542940Z","iopub.status.idle":"2023-11-13T04:30:57.555307Z","shell.execute_reply.started":"2023-11-13T04:30:57.542913Z","shell.execute_reply":"2023-11-13T04:30:57.554365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_training_curves(training, validation, title, subplot):\n    if subplot%10==1: # set up the subplots on the first call\n        plt.subplots(figsize=(10,10), facecolor='#F0F0F0')\n        plt.tight_layout()\n    ax = plt.subplot(subplot)\n    ax.set_facecolor('#F8F8F8')\n    ax.plot(training)\n    ax.plot(validation)\n    ax.set_title('model '+ title)\n    ax.set_ylabel(title)\n    #ax.set_ylim(0.28,1.05)\n    ax.set_xlabel('epoch')\n    ax.legend(['train', 'valid.'])","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.556285Z","iopub.execute_input":"2023-11-13T04:30:57.556606Z","iopub.status.idle":"2023-11-13T04:30:57.569843Z","shell.execute_reply.started":"2023-11-13T04:30:57.556576Z","shell.execute_reply":"2023-11-13T04:30:57.569139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Confusion Matrix","metadata":{}},{"cell_type":"code","source":"\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import f1_score, precision_score, recall_score, confusion_matrix\n\ndef display_confusion_matrix(cmat, score, precision, recall):\n    plt.figure(figsize=(15,15))\n    ax = plt.gca()\n    ax.matshow(cmat, cmap='Reds')\n    ax.set_xticks(range(len(CLASSES)))\n    ax.set_xticklabels(CLASSES, fontdict={'fontsize': 7})\n    plt.setp(ax.get_xticklabels(), rotation=45, ha=\"left\", rotation_mode=\"anchor\")\n    ax.set_yticks(range(len(CLASSES)))\n    ax.set_yticklabels(CLASSES, fontdict={'fontsize': 7})\n    plt.setp(ax.get_yticklabels(), rotation=45, ha=\"right\", rotation_mode=\"anchor\")\n    titlestring = \"\"\n    if score is not None:\n        titlestring += 'f1 = {:.3f} '.format(score)\n    if precision is not None:\n        titlestring += '\\nprecision = {:.3f} '.format(precision)\n    if recall is not None:\n        titlestring += '\\nrecall = {:.3f} '.format(recall)\n    if len(titlestring) > 0:\n        ax.text(101, 1, titlestring, fontdict={'fontsize': 18, 'horizontalalignment':'right', 'verticalalignment':'top', 'color':'#804040'})\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:57.570699Z","iopub.execute_input":"2023-11-13T04:30:57.570985Z","iopub.status.idle":"2023-11-13T04:30:58.084943Z","shell.execute_reply.started":"2023-11-13T04:30:57.570957Z","shell.execute_reply":"2023-11-13T04:30:58.084004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_confusion_matrix(model, validation_dataset, number_validation_images):\n    images_ds = validation_dataset.map(lambda image, label: image)\n    labels_ds = validation_dataset.map(lambda image, label: label).unbatch()\n\n    correct_labels = next(iter(labels_ds.batch(number_validation_images))).numpy()\n    probabilities = model.predict(images_ds)\n    predictions = np.argmax(probabilities, axis=-1)\n\n    labels = range(len(CLASSES))\n    cmat = confusion_matrix(correct_labels, predictions, labels=labels)\n    cmat = (cmat.T / cmat.sum(axis=1)).T  # normalize\n    \n    f1 = f1_score(correct_labels, predictions, labels=labels, average='macro')\n    precision = precision_score(correct_labels, predictions, labels=labels, average='macro')\n    recall = recall_score(correct_labels, predictions, labels=labels, average='macro')\n\n    display_confusion_matrix(cmat, f1, precision, recall)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:58.086012Z","iopub.execute_input":"2023-11-13T04:30:58.086550Z","iopub.status.idle":"2023-11-13T04:30:58.092465Z","shell.execute_reply.started":"2023-11-13T04:30:58.086517Z","shell.execute_reply":"2023-11-13T04:30:58.091796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def compute_predictions(model, dataset):\n    images_ds = dataset.map(lambda image, idnum: image)\n    probabilities = model.predict(images_ds)\n    predictions = np.argmax(probabilities, axis=-1)\n    return predictions\n\ndef generate_submission(model, test_dataset, output_filename, number_test_images):\n    predictions = compute_predictions(model, test_dataset)\n    test_ids_ds = test_dataset.map(lambda image, idnum: idnum).unbatch()\n    test_ids = next(iter(test_ids_ds.batch(number_test_images))).numpy().astype('U')\n    np.savetxt(\n        output_filename,\n        np.rec.fromarrays([test_ids, predictions]),\n        fmt=['%s', '%d'],\n        delimiter=',',\n        header='id,label',\n        comments='',\n    )\n\n    print(f'Generated {output_filename} file successfully!')","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:58.093238Z","iopub.execute_input":"2023-11-13T04:30:58.093456Z","iopub.status.idle":"2023-11-13T04:30:58.104609Z","shell.execute_reply.started":"2023-11-13T04:30:58.093432Z","shell.execute_reply":"2023-11-13T04:30:58.103921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **RESOLUTION = 512 x 512**","metadata":{"_cell_guid":"b30a71f4-0367-4b6f-a310-5ed00e8d0c26","_uuid":"b17b1b34-2cf7-4890-8799-5bd5238432e3","trusted":true}},{"cell_type":"code","source":"IMAGE_SIZE_512 = [512, 512]\nGCS_PATH_512 = GCS_DS_PATH + '/tfrecords-jpeg-512x512'\n\nTRAINING_FILENAMES_512 = tf.io.gfile.glob(GCS_PATH_512 + '/train/*.tfrec')\nVALIDATION_FILENAMES_512 = tf.io.gfile.glob(GCS_PATH_512 + '/val/*.tfrec')\nTEST_FILENAMES_512 = tf.io.gfile.glob(GCS_PATH_512 + '/test/*.tfrec')                                                                                          # 100 - 10","metadata":{"_cell_guid":"93be87f1-11a8-4e87-a7e1-a1f591870980","_kg_hide-input":true,"_uuid":"a628034c-e00c-40d7-a7cd-82d9058ba85a","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_TRAINING_IMAGES_512 = count_data_items(TRAINING_FILENAMES_512)\nNUM_VALIDATION_IMAGES_512 = count_data_items(VALIDATION_FILENAMES_512)\nNUM_TEST_IMAGES_512 = count_data_items(TEST_FILENAMES_512)\n\nprint('Dataset - 512 x 512: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAINING_IMAGES_512, NUM_VALIDATION_IMAGES_512, NUM_TEST_IMAGES_512))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_train_512 = get_training_dataset(TRAINING_FILENAMES_512, IMAGE_SIZE_512)\nds_valid_512 = get_validation_dataset(VALIDATION_FILENAMES_512, IMAGE_SIZE_512)\nds_test_512 = get_test_dataset(TEST_FILENAMES_512, IMAGE_SIZE_512)\n\nprint(\"Training - 512:\", ds_train_512)\nprint (\"Validation - 512:\", ds_valid_512)\nprint(\"Test - 512:\", ds_test_512)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.set_printoptions(threshold=15, linewidth=80)\n\nprint(\"Training - 512 data shapes:\")\nfor image, label in ds_train_512.take(3):\n    print(image.numpy().shape, label.numpy().shape)\nprint(\"Training - 512 data label examples:\", label.numpy())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Test - 512 data shapes:\")\nfor image, idnum in ds_test_512.take(3):\n    print(image.numpy().shape, idnum.numpy().shape)\nprint(\"Test - 512 data IDs:\", idnum.numpy().astype('U')) # U=unicode string","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_iter_512 = iter(ds_train_512.unbatch().batch(20))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"PRINTING ONE BATCH OF 512 x 512 SIZE IMAGES\")\none_batch_512 = next(ds_iter_512)\ndisplay_batch_of_images(one_batch_512)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lr_callback_512 = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with strategy.scope():\n    model_512 = create_vgg16_model(IMAGE_SIZE_512 + [3], len(CLASSES))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer_512 = tf.keras.optimizers.Adam(learning_rate=initial_fine_tuning_lr)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with strategy.scope():\n    compile_model(model_512,optimizer_512)\n    model_512.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH_512 = NUM_TRAINING_IMAGES_512 // BATCH_SIZE","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_512 = model_512.fit(\n    ds_train_512,\n    validation_data=ds_valid_512,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH_512,\n    callbacks=[lr_callback_512],\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_training_curves(\n    history_512.history['loss'],\n    history_512.history['val_loss'],\n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history_512.history['sparse_categorical_accuracy'],\n    history_512.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212,\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix_512 = generate_confusion_matrix(model_512, get_validation_dataset(VALIDATION_FILENAMES_512, IMAGE_SIZE_512, ordered = True), NUM_VALIDATION_IMAGES_512)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_512 = get_validation_dataset(VALIDATION_FILENAMES_512, IMAGE_SIZE_512)\ndataset_512 = dataset_512.unbatch().batch(20)\nbatch_512 = iter(dataset_512)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(batch_512)\nprobabilities = model_512.predict(images)\npredictions = np.argmax(probabilities, axis=-1)\ndisplay_batch_of_images((images, labels), predictions)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds_512 = get_test_dataset(TEST_FILENAMES_512, IMAGE_SIZE_512, ordered=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# generate_submission(model_512, test_ds_512, 'submission.csv', NUM_TEST_IMAGES_512)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **RESOLUTION = 331 x 331**","metadata":{"_cell_guid":"9d20240c-5178-46a6-a33a-6e680a6a3b82","_uuid":"9fec60fa-92ed-43cc-ab06-05a684420fde","trusted":true}},{"cell_type":"code","source":"IMAGE_SIZE_331 = [331, 331]\nGCS_PATH_331 = GCS_DS_PATH + '/tfrecords-jpeg-331x331'\n\nTRAINING_FILENAMES_331 = tf.io.gfile.glob(GCS_PATH_331 + '/train/*.tfrec')\nVALIDATION_FILENAMES_331 = tf.io.gfile.glob(GCS_PATH_331 + '/val/*.tfrec')\nTEST_FILENAMES_331 = tf.io.gfile.glob(GCS_PATH_331 + '/test/*.tfrec')","metadata":{"_cell_guid":"488b6b94-5cf4-48d8-83f2-f9f9f49bcfcc","_uuid":"962891fe-91a3-48fe-9f89-517e4aee0fa1","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-11-13T04:30:58.105434Z","iopub.execute_input":"2023-11-13T04:30:58.105692Z","iopub.status.idle":"2023-11-13T04:30:58.135975Z","shell.execute_reply.started":"2023-11-13T04:30:58.105666Z","shell.execute_reply":"2023-11-13T04:30:58.134907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_TRAINING_IMAGES_331 = count_data_items(TRAINING_FILENAMES_331)\nNUM_VALIDATION_IMAGES_331 = count_data_items(VALIDATION_FILENAMES_331)\nNUM_TEST_IMAGES_331 = count_data_items(TEST_FILENAMES_331)\n\nprint('Dataset - 331 x 331: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAINING_IMAGES_331, NUM_VALIDATION_IMAGES_331, NUM_TEST_IMAGES_331))","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:58.137039Z","iopub.execute_input":"2023-11-13T04:30:58.137292Z","iopub.status.idle":"2023-11-13T04:30:58.142271Z","shell.execute_reply.started":"2023-11-13T04:30:58.137266Z","shell.execute_reply":"2023-11-13T04:30:58.141539Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_train_331 = get_training_dataset(TRAINING_FILENAMES_331, IMAGE_SIZE_331)\nds_valid_331 = get_validation_dataset(VALIDATION_FILENAMES_331, IMAGE_SIZE_331)\nds_test_331 = get_test_dataset(TEST_FILENAMES_331, IMAGE_SIZE_331)\n\nprint(\"Training - 331:\", ds_train_331)\nprint (\"Validation - 331:\", ds_valid_331)\nprint(\"Test - 331:\", ds_test_331)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:58.143171Z","iopub.execute_input":"2023-11-13T04:30:58.143423Z","iopub.status.idle":"2023-11-13T04:30:58.434328Z","shell.execute_reply.started":"2023-11-13T04:30:58.143396Z","shell.execute_reply":"2023-11-13T04:30:58.433437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.set_printoptions(threshold=15, linewidth=80)\n\nprint(\"Training - 331 data shapes:\")\nfor image, label in ds_train_331.take(3):\n    print(image.numpy().shape, label.numpy().shape)\nprint(\"Training - 331 data label examples:\", label.numpy())","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:30:58.435398Z","iopub.execute_input":"2023-11-13T04:30:58.435718Z","iopub.status.idle":"2023-11-13T04:31:00.095388Z","shell.execute_reply.started":"2023-11-13T04:30:58.435686Z","shell.execute_reply":"2023-11-13T04:31:00.094449Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Test - 331 data shapes:\")\nfor image, idnum in ds_test_331.take(3):\n    print(image.numpy().shape, idnum.numpy().shape)\nprint(\"Test - 331 data IDs:\", idnum.numpy().astype('U')) # U=unicode string","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:00.096508Z","iopub.execute_input":"2023-11-13T04:31:00.096830Z","iopub.status.idle":"2023-11-13T04:31:00.570669Z","shell.execute_reply.started":"2023-11-13T04:31:00.096799Z","shell.execute_reply":"2023-11-13T04:31:00.569395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_iter_331 = iter(ds_train_331.unbatch().batch(20))","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:00.571829Z","iopub.execute_input":"2023-11-13T04:31:00.572132Z","iopub.status.idle":"2023-11-13T04:31:00.607493Z","shell.execute_reply.started":"2023-11-13T04:31:00.572102Z","shell.execute_reply":"2023-11-13T04:31:00.606623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"PRINTING ONE BATCH OF 331 x 331 SIZE IMAGES\")\none_batch_331 = next(ds_iter_331)\ndisplay_batch_of_images(one_batch_331)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:00.608367Z","iopub.execute_input":"2023-11-13T04:31:00.608616Z","iopub.status.idle":"2023-11-13T04:31:03.527099Z","shell.execute_reply.started":"2023-11-13T04:31:00.608590Z","shell.execute_reply":"2023-11-13T04:31:03.525963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lr_callback_331_vgg16 = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)\nlr_callback_331_vgg19 = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)\nlr_callback_331_custom_model = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)\nlr_callback_331_customize_vgg19 = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:03.528360Z","iopub.execute_input":"2023-11-13T04:31:03.528649Z","iopub.status.idle":"2023-11-13T04:31:03.533263Z","shell.execute_reply.started":"2023-11-13T04:31:03.528621Z","shell.execute_reply":"2023-11-13T04:31:03.532492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_neurons_list = [100, 200, 300]\nnum_layers = 3\nconv_shape = (3, 3)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:03.535725Z","iopub.execute_input":"2023-11-13T04:31:03.536000Z","iopub.status.idle":"2023-11-13T04:31:03.546872Z","shell.execute_reply.started":"2023-11-13T04:31:03.535973Z","shell.execute_reply":"2023-11-13T04:31:03.546059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with strategy.scope():\n    model_331_vgg16 = create_vgg16_model(IMAGE_SIZE_331 + [3], len(CLASSES))\n    model_331_vgg19 = create_vgg19_model(IMAGE_SIZE_331 + [3], len(CLASSES))\n    model_331_custom_model = create_custom_model(IMAGE_SIZE_331 + [3], len(CLASSES), num_neurons_list,num_layers,conv_shape)\n    model_331_customize_vgg19 = customize_vgg19_model(IMAGE_SIZE_331 + [3], len(CLASSES))","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:03.547735Z","iopub.execute_input":"2023-11-13T04:31:03.547969Z","iopub.status.idle":"2023-11-13T04:31:17.696604Z","shell.execute_reply.started":"2023-11-13T04:31:03.547947Z","shell.execute_reply":"2023-11-13T04:31:17.695615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer_331_vgg16 = tf.keras.optimizers.Adam(learning_rate=initial_fine_tuning_lr)\noptimizer_331_vgg19 = tf.keras.optimizers.Adam(learning_rate=initial_fine_tuning_lr)\noptimizer_331_custom_model = tf.keras.optimizers.Adam(learning_rate=initial_fine_tuning_lr)\noptimizer_331_customize_vgg19 = tf.keras.optimizers.Adam(learning_rate=initial_fine_tuning_lr)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:17.697752Z","iopub.execute_input":"2023-11-13T04:31:17.698043Z","iopub.status.idle":"2023-11-13T04:31:17.711535Z","shell.execute_reply.started":"2023-11-13T04:31:17.698013Z","shell.execute_reply":"2023-11-13T04:31:17.710528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import plot_model\nwith strategy.scope():\n    compile_model(model_331_vgg16,optimizer_331_vgg16)\n    plot_model(model_331_vgg16, to_file='model_331_vgg16.png', show_shapes=True, show_layer_names=True)\n    model_331_vgg16.summary()\n    compile_model(model_331_vgg19,optimizer_331_vgg19)\n    plot_model(model_331_vgg19, to_file='model_331_vgg19.png', show_shapes=True, show_layer_names=True)\n    model_331_vgg19.summary()\n    compile_model(model_331_custom_model,optimizer_331_custom_model)\n    plot_model(model_331_custom_model, to_file='model_331_custom_model.png', show_shapes=True, show_layer_names=True)\n    model_331_custom_model.summary()\n    compile_model(model_331_customize_vgg19,optimizer_331_customize_vgg19)\n    plot_model(model_331_customize_vgg19, to_file='model_331_customize_vgg19.png', show_shapes=True, show_layer_names=True)\n    model_331_customize_vgg19.summary()","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:17.713552Z","iopub.execute_input":"2023-11-13T04:31:17.713863Z","iopub.status.idle":"2023-11-13T04:31:17.932134Z","shell.execute_reply.started":"2023-11-13T04:31:17.713836Z","shell.execute_reply":"2023-11-13T04:31:17.931352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH_331 = NUM_TRAINING_IMAGES_331 // BATCH_SIZE","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:17.932978Z","iopub.execute_input":"2023-11-13T04:31:17.933228Z","iopub.status.idle":"2023-11-13T04:31:17.936647Z","shell.execute_reply.started":"2023-11-13T04:31:17.933203Z","shell.execute_reply":"2023-11-13T04:31:17.935861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_331_vgg16 = model_331_vgg16.fit(\n    ds_train_331,\n    validation_data=ds_valid_331,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH_331,\n    callbacks=[lr_callback_331_vgg16],\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:31:17.937541Z","iopub.execute_input":"2023-11-13T04:31:17.937846Z","iopub.status.idle":"2023-11-13T04:35:52.661106Z","shell.execute_reply.started":"2023-11-13T04:31:17.937818Z","shell.execute_reply":"2023-11-13T04:35:52.659935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_331_vgg19 = model_331_vgg19.fit(\n    ds_train_331,\n    validation_data=ds_valid_331,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH_331,\n    callbacks=[lr_callback_331_vgg19],\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:35:52.662954Z","iopub.execute_input":"2023-11-13T04:35:52.663270Z","iopub.status.idle":"2023-11-13T04:40:46.351425Z","shell.execute_reply.started":"2023-11-13T04:35:52.663239Z","shell.execute_reply":"2023-11-13T04:40:46.350213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_331_custom_model = model_331_custom_model.fit(\n    ds_train_331,\n    validation_data=ds_valid_331,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH_331,\n    callbacks=[lr_callback_331_custom_model],\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:40:46.354820Z","iopub.execute_input":"2023-11-13T04:40:46.355123Z","iopub.status.idle":"2023-11-13T04:45:43.798101Z","shell.execute_reply.started":"2023-11-13T04:40:46.355092Z","shell.execute_reply":"2023-11-13T04:45:43.796975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_331_customize_vgg19 = model_331_customize_vgg19.fit(\n    ds_train_331,\n    validation_data=ds_valid_331,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH_331,\n    callbacks=[lr_callback_331_customize_vgg19],\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:45:43.800589Z","iopub.execute_input":"2023-11-13T04:45:43.800889Z","iopub.status.idle":"2023-11-13T04:50:44.093944Z","shell.execute_reply.started":"2023-11-13T04:45:43.800858Z","shell.execute_reply":"2023-11-13T04:50:44.092663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_training_curves(\n    history_331_vgg16.history['loss'],\n    history_331_vgg16.history['val_loss'],\n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history_331_vgg16.history['sparse_categorical_accuracy'],\n    history_331_vgg16.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212,\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:50:44.096774Z","iopub.execute_input":"2023-11-13T04:50:44.097083Z","iopub.status.idle":"2023-11-13T04:50:45.113775Z","shell.execute_reply.started":"2023-11-13T04:50:44.097052Z","shell.execute_reply":"2023-11-13T04:50:45.112874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_training_curves(\n    history_331_vgg19.history['loss'],\n    history_331_vgg19.history['val_loss'],\n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history_331_vgg19.history['sparse_categorical_accuracy'],\n    history_331_vgg19.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212,\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:50:45.114777Z","iopub.execute_input":"2023-11-13T04:50:45.115057Z","iopub.status.idle":"2023-11-13T04:50:45.722585Z","shell.execute_reply.started":"2023-11-13T04:50:45.115029Z","shell.execute_reply":"2023-11-13T04:50:45.721669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_training_curves(\n    history_331_custom_model.history['loss'],\n    history_331_custom_model.history['val_loss'],\n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history_331_custom_model.history['sparse_categorical_accuracy'],\n    history_331_custom_model.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212,\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:50:45.723624Z","iopub.execute_input":"2023-11-13T04:50:45.723898Z","iopub.status.idle":"2023-11-13T04:50:46.269180Z","shell.execute_reply.started":"2023-11-13T04:50:45.723870Z","shell.execute_reply":"2023-11-13T04:50:46.268295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_training_curves(\n    history_331_customize_vgg19.history['loss'],\n    history_331_customize_vgg19.history['val_loss'],\n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history_331_customize_vgg19.history['sparse_categorical_accuracy'],\n    history_331_customize_vgg19.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212,\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:50:46.270313Z","iopub.execute_input":"2023-11-13T04:50:46.270641Z","iopub.status.idle":"2023-11-13T04:50:46.769791Z","shell.execute_reply.started":"2023-11-13T04:50:46.270609Z","shell.execute_reply":"2023-11-13T04:50:46.768853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix_331_vgg16 = generate_confusion_matrix(model_331_vgg16, get_validation_dataset(VALIDATION_FILENAMES_331, IMAGE_SIZE_331, ordered = True), NUM_VALIDATION_IMAGES_331)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:50:46.770789Z","iopub.execute_input":"2023-11-13T04:50:46.771079Z","iopub.status.idle":"2023-11-13T04:51:01.660089Z","shell.execute_reply.started":"2023-11-13T04:50:46.771050Z","shell.execute_reply":"2023-11-13T04:51:01.658762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix_331_vgg19 = generate_confusion_matrix(model_331_vgg19, get_validation_dataset(VALIDATION_FILENAMES_331, IMAGE_SIZE_331, ordered = True), NUM_VALIDATION_IMAGES_331)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:51:01.662038Z","iopub.execute_input":"2023-11-13T04:51:01.662358Z","iopub.status.idle":"2023-11-13T04:51:15.914709Z","shell.execute_reply.started":"2023-11-13T04:51:01.662327Z","shell.execute_reply":"2023-11-13T04:51:15.913642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix_331_custom_model = generate_confusion_matrix(model_331_custom_model, get_validation_dataset(VALIDATION_FILENAMES_331, IMAGE_SIZE_331, ordered = True), NUM_VALIDATION_IMAGES_331)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:51:15.916274Z","iopub.execute_input":"2023-11-13T04:51:15.916595Z","iopub.status.idle":"2023-11-13T04:52:20.951121Z","shell.execute_reply.started":"2023-11-13T04:51:15.916566Z","shell.execute_reply":"2023-11-13T04:52:20.949751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix_331_customize_vgg19 = generate_confusion_matrix(model_331_customize_vgg19, get_validation_dataset(VALIDATION_FILENAMES_331, IMAGE_SIZE_331, ordered = True), NUM_VALIDATION_IMAGES_331)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:52:20.954542Z","iopub.execute_input":"2023-11-13T04:52:20.954997Z","iopub.status.idle":"2023-11-13T04:52:35.988442Z","shell.execute_reply.started":"2023-11-13T04:52:20.954967Z","shell.execute_reply":"2023-11-13T04:52:35.987240Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_331 = get_validation_dataset(VALIDATION_FILENAMES_331, IMAGE_SIZE_331)\ndataset_331 = dataset_331.unbatch().batch(20)\nbatch_331 = iter(dataset_331)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:52:35.990262Z","iopub.execute_input":"2023-11-13T04:52:35.990601Z","iopub.status.idle":"2023-11-13T04:52:36.058355Z","shell.execute_reply.started":"2023-11-13T04:52:35.990570Z","shell.execute_reply":"2023-11-13T04:52:36.057229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(batch_331)\nprobabilities_vgg16 = model_331_vgg16.predict(images)\npredictions = np.argmax(probabilities_vgg16, axis=-1)\ndisplay_batch_of_images((images, labels), predictions)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:52:36.059420Z","iopub.execute_input":"2023-11-13T04:52:36.059729Z","iopub.status.idle":"2023-11-13T04:52:47.092665Z","shell.execute_reply.started":"2023-11-13T04:52:36.059700Z","shell.execute_reply":"2023-11-13T04:52:47.091247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(batch_331)\nprobabilities_vgg19 = model_331_vgg19.predict(images)\npredictions = np.argmax(probabilities_vgg19, axis=-1)\ndisplay_batch_of_images((images, labels), predictions)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:52:47.093859Z","iopub.execute_input":"2023-11-13T04:52:47.094161Z","iopub.status.idle":"2023-11-13T04:52:57.674219Z","shell.execute_reply.started":"2023-11-13T04:52:47.094130Z","shell.execute_reply":"2023-11-13T04:52:57.672711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(batch_331)\nprobabilities_custom_model = model_331_custom_model.predict(images)\npredictions = np.argmax(probabilities_custom_model, axis=-1)\ndisplay_batch_of_images((images, labels), predictions)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:52:57.675381Z","iopub.execute_input":"2023-11-13T04:52:57.675662Z","iopub.status.idle":"2023-11-13T04:53:05.486832Z","shell.execute_reply.started":"2023-11-13T04:52:57.675633Z","shell.execute_reply":"2023-11-13T04:53:05.485766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(batch_331)\nprobabilities_customize_vgg19 = model_331_customize_vgg19.predict(images)\npredictions = np.argmax(probabilities_customize_vgg19, axis=-1)\ndisplay_batch_of_images((images, labels), predictions)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:53:05.488029Z","iopub.execute_input":"2023-11-13T04:53:05.488291Z","iopub.status.idle":"2023-11-13T04:53:15.952549Z","shell.execute_reply.started":"2023-11-13T04:53:05.488265Z","shell.execute_reply":"2023-11-13T04:53:15.951107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds_331 = get_test_dataset(TEST_FILENAMES_331, IMAGE_SIZE_331, ordered=True)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:53:15.953737Z","iopub.execute_input":"2023-11-13T04:53:15.954032Z","iopub.status.idle":"2023-11-13T04:53:15.985721Z","shell.execute_reply.started":"2023-11-13T04:53:15.954002Z","shell.execute_reply":"2023-11-13T04:53:15.984573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# generate_submission(model_331_vgg16, test_ds_331, 'submission.csv', NUM_TEST_IMAGES_331)\ngenerate_submission(model_331_vgg19, test_ds_331, 'submission.csv', NUM_TEST_IMAGES_331)\n# generate_submission(model_331_custom_model, test_ds_331, 'submission.csv', NUM_TEST_IMAGES_331)\n# generate_submission(model_331_customize_vgg19, test_ds_331, 'submission.csv', NUM_TEST_IMAGES_331)","metadata":{"execution":{"iopub.status.busy":"2023-11-13T04:53:15.986803Z","iopub.execute_input":"2023-11-13T04:53:15.987040Z","iopub.status.idle":"2023-11-13T04:53:33.347274Z","shell.execute_reply.started":"2023-11-13T04:53:15.987015Z","shell.execute_reply":"2023-11-13T04:53:33.346143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **RESOLUTION = 224 x 224**","metadata":{"_cell_guid":"1091252a-1ea0-405f-a319-7b63ec7e00d4","_uuid":"e6a13fb3-f353-445b-8819-792e40c209ee","trusted":true}},{"cell_type":"code","source":"IMAGE_SIZE_224 = [224, 224]\nGCS_PATH_224 = GCS_DS_PATH + '/tfrecords-jpeg-224x224'\n\nTRAINING_FILENAMES_224 = tf.io.gfile.glob(GCS_PATH_224 + '/train/*.tfrec')\nVALIDATION_FILENAMES_224 = tf.io.gfile.glob(GCS_PATH_224 + '/val/*.tfrec')\nTEST_FILENAMES_224 = tf.io.gfile.glob(GCS_PATH_224 + '/test/*.tfrec')","metadata":{"_cell_guid":"af775a9c-2c60-4614-a86b-aa9d4f8dae72","_uuid":"645e2887-8fd1-4399-8564-07026fd351cd","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_TRAINING_IMAGES_224 = count_data_items(TRAINING_FILENAMES_224)\nNUM_VALIDATION_IMAGES_224 = count_data_items(VALIDATION_FILENAMES_224)\nNUM_TEST_IMAGES_224 = count_data_items(TEST_FILENAMES_224)\n\nprint('Dataset - 224 x 224: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAINING_IMAGES_224, NUM_VALIDATION_IMAGES_224, NUM_TEST_IMAGES_224))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_train_224 = get_training_dataset(TRAINING_FILENAMES_224, IMAGE_SIZE_224)\nds_valid_224 = get_validation_dataset(VALIDATION_FILENAMES_224, IMAGE_SIZE_224)\nds_test_224 = get_test_dataset(TEST_FILENAMES_224, IMAGE_SIZE_224)\n\nprint(\"Training - 224:\", ds_train_224)\nprint (\"Validation - 224:\", ds_valid_224)\nprint(\"Test - 224:\", ds_test_224)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.set_printoptions(threshold=15, linewidth=80)\n\nprint(\"Training - 224 data shapes:\")\nfor image, label in ds_train_224.take(3):\n    print(image.numpy().shape, label.numpy().shape)\nprint(\"Training - 224 data label examples:\", label.numpy())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Test - 224 data shapes:\")\nfor image, idnum in ds_test_224.take(3):\n    print(image.numpy().shape, idnum.numpy().shape)\nprint(\"Test - 224 data IDs:\", idnum.numpy().astype('U')) # U=unicode string","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_iter_224 = iter(ds_train_224.unbatch().batch(20))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"PRINTING ONE BATCH OF 224 x 224 SIZE IMAGES\")\none_batch_224 = next(ds_iter_224)\ndisplay_batch_of_images(one_batch_224)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lr_callback_224 = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with strategy.scope():\n    model_224 = create_vgg16_model(IMAGE_SIZE_224 + [3], len(CLASSES))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer_224 = tf.keras.optimizers.Adam(learning_rate=initial_fine_tuning_lr)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with strategy.scope():\n    compile_model(model_224,optimizer_224)\n    model_224.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH_224 = NUM_TRAINING_IMAGES_224 // BATCH_SIZE","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_224 = model_224.fit(\n    ds_train_224,\n    validation_data=ds_valid_224,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH_224,\n    callbacks=[lr_callback_224],\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_training_curves(\n    history_224.history['loss'],\n    history_224.history['val_loss'],\n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history_224.history['sparse_categorical_accuracy'],\n    history_224.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212,\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix_224 = generate_confusion_matrix(model_224, get_validation_dataset(VALIDATION_FILENAMES_224, IMAGE_SIZE_224, ordered = True), NUM_VALIDATION_IMAGES_224)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_224 = get_validation_dataset(VALIDATION_FILENAMES_224, IMAGE_SIZE_224)\ndataset_224 = dataset_224.unbatch().batch(20)\nbatch_224 = iter(dataset_224)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(batch_224)\nprobabilities = model_224.predict(images)\npredictions = np.argmax(probabilities, axis=-1)\ndisplay_batch_of_images((images, labels), predictions)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds_224 = get_test_dataset(TEST_FILENAMES_224, IMAGE_SIZE_224, ordered=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# generate_submission(model_224, test_ds_224, 'submission.csv', NUM_TEST_IMAGES_224)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **RESOLUTION = 192 x 192**","metadata":{"_cell_guid":"6230f53b-2869-4c0a-a907-23a0039bd326","_uuid":"a81dae11-8d7e-4891-8028-bff587a6921a","trusted":true}},{"cell_type":"code","source":"IMAGE_SIZE_192 = [192, 192]\nGCS_PATH_192 = GCS_DS_PATH + '/tfrecords-jpeg-192x192'\n\nTRAINING_FILENAMES_192 = tf.io.gfile.glob(GCS_PATH_192 + '/train/*.tfrec')\nVALIDATION_FILENAMES_192 = tf.io.gfile.glob(GCS_PATH_192 + '/val/*.tfrec')\nTEST_FILENAMES_192 = tf.io.gfile.glob(GCS_PATH_192 + '/test/*.tfrec')","metadata":{"_cell_guid":"75c0801e-a9ac-40f8-a02e-c5d567aeba88","_uuid":"cd762259-0331-4214-b82a-484f3cb689ba","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_TRAINING_IMAGES_192 = count_data_items(TRAINING_FILENAMES_192)\nNUM_VALIDATION_IMAGES_192 = count_data_items(VALIDATION_FILENAMES_192)\nNUM_TEST_IMAGES_192 = count_data_items(TEST_FILENAMES_192)\n\nprint('Dataset - 224 x 224: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAINING_IMAGES_192, NUM_VALIDATION_IMAGES_192, NUM_TEST_IMAGES_192))","metadata":{"_cell_guid":"a145f79f-fd9d-4cab-8d12-2a9c23b28912","_uuid":"17cb82bb-1fa0-4c16-b4a0-799f615e3e4c","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_train_192 = get_training_dataset(TRAINING_FILENAMES_192, IMAGE_SIZE_192)\nds_valid_192 = get_validation_dataset(VALIDATION_FILENAMES_192, IMAGE_SIZE_192)\nds_test_192 = get_test_dataset(TEST_FILENAMES_192, IMAGE_SIZE_192)\n\nprint(\"Training - 192:\", ds_train_192)\nprint (\"Validation - 192:\", ds_valid_192)\nprint(\"Test - 192:\", ds_test_192)","metadata":{"_cell_guid":"63eae70e-cdcb-4d18-afa4-4639cf32c32b","_uuid":"e7d1a00a-3abf-446e-93f1-6568c1251d35","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.set_printoptions(threshold=15, linewidth=80)\n\nprint(\"Training - 192 data shapes:\")\nfor image, label in ds_train_192.take(3):\n    print(image.numpy().shape, label.numpy().shape)\nprint(\"Training - 192 data label examples:\", label.numpy())","metadata":{"_cell_guid":"c72ee93f-5dd0-45bc-8e0e-b42200abeafb","_uuid":"27d6d0d0-50be-4efa-a73b-f5d9a0a02afc","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Test - 192 data shapes:\")\nfor image, idnum in ds_test_192.take(3):\n    print(image.numpy().shape, idnum.numpy().shape)\nprint(\"Test - 192 data IDs:\", idnum.numpy().astype('U')) # U=unicode string","metadata":{"_cell_guid":"3cd3996d-5cd8-4298-8075-d24378019958","_uuid":"3faaea94-c29a-46e8-9c18-696c39b5735a","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_iter_192 = iter(ds_train_192.unbatch().batch(20))","metadata":{"_cell_guid":"72732423-cd59-43aa-a376-41110d3cf60b","_uuid":"9aeb53e3-a48c-461e-9fa7-880f5b110d6b","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"PRINTING ONE BATCH OF 192 x 192 SIZE IMAGES\")\none_batch_192 = next(ds_iter_192)\ndisplay_batch_of_images(one_batch_192)","metadata":{"_cell_guid":"2e168b0f-d1ec-4eef-a612-fb2dc09aa921","_uuid":"9eae0c94-e6d4-45cc-b9cd-2e372b69bc62","collapsed":false,"jupyter":{"outputs_hidden":false},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lr_callback_192 = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with strategy.scope():\n    model_192 = create_vgg16_model(IMAGE_SIZE_192 + [3], len(CLASSES))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer_192 = tf.keras.optimizers.Adam(learning_rate=initial_fine_tuning_lr)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with strategy.scope():\n    compile_model(model_192,optimizer_192)\n    model_192.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"STEPS_PER_EPOCH_192 = NUM_TRAINING_IMAGES_192 // BATCH_SIZE","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_192 = model_192.fit(\n    ds_train_192,\n    validation_data=ds_valid_192,\n    epochs=EPOCHS,\n    steps_per_epoch=STEPS_PER_EPOCH_192,\n    callbacks=[lr_callback_192],\n)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"display_training_curves(\n    history_192.history['loss'],\n    history_192.history['val_loss'],\n    'loss',\n    211,\n)\ndisplay_training_curves(\n    history_192.history['sparse_categorical_accuracy'],\n    history_192.history['val_sparse_categorical_accuracy'],\n    'accuracy',\n    212,\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"confusion_matrix_192 = generate_confusion_matrix(model_192, get_validation_dataset(VALIDATION_FILENAMES_192, IMAGE_SIZE_192, ordered = True), NUM_VALIDATION_IMAGES_192)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_192 = get_validation_dataset(VALIDATION_FILENAMES_192, IMAGE_SIZE_192)\ndataset_192 = dataset_192.unbatch().batch(20)\nbatch_192 = iter(dataset_192)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(batch_192)\nprobabilities = model_192.predict(images)\npredictions = np.argmax(probabilities, axis=-1)\ndisplay_batch_of_images((images, labels), predictions)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds_192 = get_test_dataset(TEST_FILENAMES_192, IMAGE_SIZE_192, ordered=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# generate_submission(model_192, test_ds_192, 'submission.csv', NUM_TEST_IMAGES_192)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# COMPARING THE MODELS BASED ON ACCURACY","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n# Submission data\nversions = ['VGG - 16 (331)', 'VGG - 16 (224)', 'VGG - 16 (192)', 'VGG - 16 (512)', 'AVERAGE ACCURACY']\n# Corresponding Kaggle scores\nscores = [0.82255, 0.81265, 0.8116, 0.80122, 0.04212]\ncolors = ['skyblue', 'salmon', 'lightgreen', 'lightcoral', 'yellow']\n# Create a horizontal bar chart with different colors and additional styling\nfig, ax = plt.subplots()\nbars = ax.barh(versions, scores, color=colors)\nfor bar, score in zip(bars, scores):\n    width = bar.get_width()\n    ax.text(width, bar.get_y() + bar.get_height() / 2, f'{score:.4f}', ha='left', va='center')\nax.set_xlabel('Kaggle Score for VGG - 16 Model', fontsize=12)\nax.set_ylabel('Kaggle Submission VGG - 16 Model Versions', fontsize=12)\nax.set_title('Kaggle Submission Scores for Different Resolutions', fontsize=14)\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-13T05:31:58.690944Z","iopub.execute_input":"2023-11-13T05:31:58.691661Z","iopub.status.idle":"2023-11-13T05:31:58.847515Z","shell.execute_reply.started":"2023-11-13T05:31:58.691621Z","shell.execute_reply":"2023-11-13T05:31:58.846795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# VGG - 16 Model for Resolution 331 x 331 gave better accuracy comparitvely to other resolutions","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\n\nversions = [\"VGG 19 331 E - 12\", \"VGG 16 331 E - 20\", \"VGG 19 331 E - 12\", \"VGG 19 331 E - 10\", \"VGG 16 331 E - 12\", \"VGG 19 - 331 E - 20\", \"VGG 16 224 E - 12\", \"VGG 16 192\", \"VGG 16 512 E - 12\", \"VGG 19 Customized\", \"Custom Model1\", \"Custom Model2\", \"VGG 16 512 Weights Freeze\"]\naccuracy_scores = [0.83435, 0.83384, 0.82643, 0.82322, 0.82255, 0.81733, 0.81265, 0.8116, 0.80122, 0.28821, 0.11022, 0.10125, 0.04212]\ncolors = ['blue', 'green', 'red', 'purple', 'orange', 'brown', 'pink', 'gray', 'cyan', 'magenta', 'yellow', 'lightblue', 'lightgreen']\n\nplt.figure(figsize=(20, 8))\nbars = plt.barh(versions, accuracy_scores, color=colors)\nplt.xlabel('Accuracy Scores')\nplt.title('Model Performance Across Versions')\nlegend_labels = versions\nplt.legend(bars, legend_labels, loc='upper right')\nfor bar, score in zip(bars, accuracy_scores):\n    width = bar.get_width()\n    plt.text(width, bar.get_y() + bar.get_height()/2, f'{score:.4f}', ha='left', va='center')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-13T05:37:27.746913Z","iopub.execute_input":"2023-11-13T05:37:27.747690Z","iopub.status.idle":"2023-11-13T05:37:28.103385Z","shell.execute_reply.started":"2023-11-13T05:37:27.747645Z","shell.execute_reply":"2023-11-13T05:37:28.102540Z"},"trusted":true},"execution_count":null,"outputs":[]}]}