{"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":"# Introduction  \n\nWelcome to the Petals to the Metal competition! In this competition, you’re challenged to build a machine learning model to classify 104 types of flowers based on their images.\nIn this tutorial notebook, you'll learn how to build an image classifier in Keras and train it on a Tensor Processing Unit (TPU). At the end, you'll have a complete project you can build off of with ideas of your own.\n\nTo improve classification accuracy of the model on the test dataset, the following are explored:\n\n* Input image size\n* Pretrained model and number of trainable parameters of final model\n* Data augmentation\n* Regularization techniques\n* Use of learning rate schedule\n\n","metadata":{"_uuid":"fb0aa356-49b6-4a1c-8d40-be73df5b086b","_cell_guid":"366d3993-b8cd-463d-8192-e281a6bcaed7","trusted":true}},{"cell_type":"markdown","source":"# Step 0 : Import Libraries\n\nwe begin this notebook by importing useful analytics libraries, in which we import statistical, data visualization and milidating overfitting libraries along with tensorflow and keras.","metadata":{"_uuid":"501665c9-35fc-4ab3-8e02-d516305958ae","_cell_guid":"83ce8f39-7f65-4e23-9f07-ddd7cd638580","trusted":true}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed on Kaggle\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\nimport os\nimport re\nimport math\nimport numpy as np \nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom matplotlib import cm\nimport seaborn as sns\nimport random       \nimport plotly.express as px\nimport tensorflow as tf\nfrom tensorflow.keras import regularizers      # mitigate overfitting \nfrom kaggle_datasets  import KaggleDatasets    # import kaggle data files\n# Stop training when a monitored metric has stopped improving\nfrom tensorflow.keras.callbacks import EarlyStopping   \nprint(\"Tensorflow version \" + tf.__version__)  # verify tensorflow versionis 2.x","metadata":{"_uuid":"7f918df3-da7b-4402-ac0d-6e8335523186","_cell_guid":"2cf936cf-f227-4ad0-8264-490743564087","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2021-09-07T19:12:27.653250Z","iopub.execute_input":"2021-09-07T19:12:27.653791Z","iopub.status.idle":"2021-09-07T19:12:36.160022Z","shell.execute_reply.started":"2021-09-07T19:12:27.653648Z","shell.execute_reply":"2021-09-07T19:12:36.158978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Step 1: Distribution Strategy\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":{"_uuid":"2b56af92-3f6f-4a2d-89d5-360d71124215","_cell_guid":"b2ace8eb-b5b6-4b8f-927a-f77192c2b775","trusted":true}},{"cell_type":"markdown","source":"### What TPUClusterResolver() does? <br>\nTPUs are network-connected accelerators and you must first locate them on the network. In TPUStrategy, the main object is to contain the necessary distributed training code that will work on TPUs with their 8 compute cores. Whenever, you use the TPUStrategy by instantiating your model in the scope of the strategy. This creates the model on the TPU. Model size is constrained by the TPU RAM only, not by the amount of memory available on the VM running your Python code. Model creation and model training use the usual Keras APIs. Further read about [TPUClusterResolver() ](https://www.tensorflow.org/api_docs/python/tf/distribute/cluster_resolver/ClusterResolver) and\n[Kaggle TPU Doc](https://www.kaggle.com/docs/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    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    # default distribution strategy in Tensorflow. Works on CPU and single GPU.\n    strategy = tf.distribute.get_strategy() \n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)","metadata":{"_uuid":"f0788b15-73ff-46dc-9479-614d0949d83c","_cell_guid":"cc85de79-6f5f-4d20-9d66-8bca545aa9dd","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2021-09-07T19:12:36.161727Z","iopub.execute_input":"2021-09-07T19:12:36.162031Z","iopub.status.idle":"2021-09-07T19:12:42.133932Z","shell.execute_reply.started":"2021-09-07T19:12:36.162000Z","shell.execute_reply":"2021-09-07T19:12:42.132661Z"},"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.","metadata":{}},{"cell_type":"markdown","source":"# Step 2: Loading The Competition Data\n\n### Get GCS Path\nWhen used with TPUs, datasets need to be stored in a [Google Cloud Storage](https://cloud.google.com/storage/) bucket. 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_type":"code","source":"# you can list the bucket with \"!gsutil ls $GCS_DS_PATH\"\nGCS_DS_PATH = KaggleDatasets().get_gcs_path('tpu-getting-started')\nprint(GCS_DS_PATH)","metadata":{"_uuid":"c0550ca8-8566-4188-831b-1289bf1ee4e6","_cell_guid":"187faa00-29f1-4d08-a86c-69427f6d8064","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2021-09-07T19:12:42.136059Z","iopub.execute_input":"2021-09-07T19:12:42.136386Z","iopub.status.idle":"2021-09-07T19:12:42.586594Z","shell.execute_reply.started":"2021-09-07T19:12:42.136354Z","shell.execute_reply":"2021-09-07T19:12:42.585339Z"},"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","metadata":{}},{"cell_type":"markdown","source":"# Data Directories","metadata":{"_uuid":"c1ea2057-e1ca-4390-9563-285dfb986693","_cell_guid":"22e4006a-f139-48a3-8608-cfb4dccef1bd","trusted":true}},{"cell_type":"code","source":"# Input data files are available in the read-only \"kaggle/input/\" directory\n#   image files are in TFRecords format, each of which contains a sequeence\n#   of records and can only be read sequentially.\n\nTFRec_selected = '512x512'\nfor dirpath, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        if TFRec_selected in dirpath: # \n            print(os.path.join(dirpath, filename))","metadata":{"_uuid":"ef0403c6-be7d-432f-b75a-4a7e6f253f89","_cell_guid":"24c498eb-ce33-4bae-8b66-5faccfc158d2","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2021-09-07T19:12:42.588249Z","iopub.execute_input":"2021-09-07T19:12:42.588613Z","iopub.status.idle":"2021-09-07T19:12:43.127175Z","shell.execute_reply.started":"2021-09-07T19:12:42.588577Z","shell.execute_reply":"2021-09-07T19:12:43.126181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Step 3: Loading Data (Setting up the parameters)","metadata":{"_uuid":"b863c30d-651f-4aab-a6ee-0aaf62d7dcab","_cell_guid":"e86513b7-25ef-481b-aee5-54e5847099e5","trusted":true}},{"cell_type":"markdown","source":"\n\n\n\n\n\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_type":"markdown","source":"TPU's is basically used to allocate the larger models having huge training inputs and batches, equipped with upto 128GB of high-speed memory allocation. In this notebook, we used images dataset having pixel size is 512 x 512px, and see how TPU v3-8 handle it.\n* num_parallel_reads=AUTO is used to automatically read multiple file.\n* experimental_deterministic = False, we used \"experimental_deterministic\" to maintain the order of the data. Here, we disable the enforcement order to shuffle the data anyway.\n\n","metadata":{}},{"cell_type":"code","source":"IMAGE_SIZE = [512, 512] \n\nGCS_PATH = GCS_DS_PATH + '/tfrecords-jpeg-512x512'\nAUTO = tf.data.experimental.AUTOTUNE \n\nTRAINING_FILENAMES = tf.io.gfile.glob(GCS_PATH + '/train/*.tfrec')\nVALIDATION_FILENAMES = tf.io.gfile.glob(GCS_PATH + '/val/*.tfrec')\nTEST_FILENAMES = tf.io.gfile.glob(GCS_PATH + '/test/*.tfrec') \n\nCLASSES = ['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']  \n\n# 100 - 103\n\nprint (CLASSES)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:43.128836Z","iopub.execute_input":"2021-09-07T19:12:43.129253Z","iopub.status.idle":"2021-09-07T19:12:43.382820Z","shell.execute_reply.started":"2021-09-07T19:12:43.129210Z","shell.execute_reply":"2021-09-07T19:12:43.381918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Functions to Handle the Data","metadata":{}},{"cell_type":"code","source":"def decode_image(image_data):\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):\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'])\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):\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, to be predicted flower classes for the test dataset\n    }\n    example = tf.io.parse_single_example(example, UNLABELED_TFREC_FORMAT)\n    image = decode_image(example['image'])\n    idnum = example['id']\n    return image, idnum # returns a dataset of (image, idnum) pairs\n\ndef load_dataset(filenames, 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    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False # disable order, increase speed\n    \n    # automatically interleaves reads from multiple file\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTO) \n    \n    # uses data as soon as it streams in, rather than in its original order\n    dataset = dataset.with_options(ignore_order) \n    \n    # returns a dataset of (image, label) pairs if labeled=True or (image, id) pairs if labeled=False\n    dataset = dataset.map(read_labeled_tfrecord if labeled \n                          else read_unlabeled_tfrecord, num_parallel_calls=AUTO)\n    return dataset\n","metadata":{"_uuid":"1dde9afd-9506-4e4f-88eb-c99d614e60c7","_cell_guid":"7cb4547d-c169-4601-abaf-362f01fa8306","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2021-09-07T19:12:43.383909Z","iopub.execute_input":"2021-09-07T19:12:43.384326Z","iopub.status.idle":"2021-09-07T19:12:43.395129Z","shell.execute_reply.started":"2021-09-07T19:12:43.384296Z","shell.execute_reply":"2021-09-07T19:12:43.394318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Tuning the Additional [Flower Data](https://www.kaggle.com/kirillblinov/tf-flower-photo-tfrec)\n\nTo increase the proficiiency of data, I have to use the external flower dataset with the helping material from [Dmitry's](https://www.kaggle.com/dmitrynokhrin/densenet201-aug-additional-data) and [Araik's ](https://www.kaggle.com/atamazian/fc-ensemble-external-data-effnet-densenet)notebook. To visit the notebook to better understanding of the Ensamble learning and augmentation of the external dataste.","metadata":{}},{"cell_type":"code","source":"GCS_DS_PATH_EXT = KaggleDatasets().get_gcs_path('tf-flower-photo-tfrec')\n\n# External data\nGCS_PATH_SELECT_EXT = {\n    192: '/tfrecords-jpeg-192x192',\n    224: '/tfrecords-jpeg-224x224',\n    331: '/tfrecords-jpeg-331x331',\n    512: '/tfrecords-jpeg-512x512'\n}\nGCS_PATH_EXT = GCS_PATH_SELECT_EXT[IMAGE_SIZE[0]]\n\nIMAGENET_FILES = tf.io.gfile.glob(GCS_DS_PATH_EXT + '/imagenet' + GCS_PATH_EXT + '/*.tfrec')\nINATURELIST_FILES = tf.io.gfile.glob(GCS_DS_PATH_EXT + '/inaturalist' + GCS_PATH_EXT + '/*.tfrec')\nOPENIMAGE_FILES = tf.io.gfile.glob(GCS_DS_PATH_EXT + '/openimage' + GCS_PATH_EXT + '/*.tfrec')\nOXFORD_FILES = tf.io.gfile.glob(GCS_DS_PATH_EXT + '/oxford_102' + GCS_PATH_EXT + '/*.tfrec')\nTENSORFLOW_FILES = tf.io.gfile.glob(GCS_DS_PATH_EXT + '/tf_flowers' + GCS_PATH_EXT + '/*.tfrec')\n\nADDITIONAL_TRAINING_FILENAMES = IMAGENET_FILES + INATURELIST_FILES + OPENIMAGE_FILES + OXFORD_FILES + TENSORFLOW_FILES  \n\nTRAINING_FILENAMES = TRAINING_FILENAMES + ADDITIONAL_TRAINING_FILENAMES","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:43.396169Z","iopub.execute_input":"2021-09-07T19:12:43.396619Z","iopub.status.idle":"2021-09-07T19:12:44.175590Z","shell.execute_reply.started":"2021-09-07T19:12:43.396585Z","shell.execute_reply":"2021-09-07T19:12:44.174296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# parameters set for tfrecords-jpeg-512x512 TFRecord files\nIMAGE_SIZE        = [512, 512] \nHEIGHT            = IMAGE_SIZE[0]\nWIDTH             = IMAGE_SIZE[1]\nEPOCHS            = 20\nBATCH_SIZE        = 16 * strategy.num_replicas_in_sync\nNUM_TRAIN_IMAGES  = 12753\nNUM_VAL_IMAGES    = 3712\nNUM_TEST_IMAGES   = 7382\nSTEPS_PER_EPOCH   = NUM_TRAIN_IMAGES // BATCH_SIZE\nAUTO              = tf.data.experimental.AUTOTUNE\nTRAIN_FILENAMES   = tf.io.gfile.glob(GCS_DS_PATH + '/tfrecords-jpeg-512x512/train/*.tfrec') \nVAL_FILENAMES     = tf.io.gfile.glob(GCS_DS_PATH + '/tfrecords-jpeg-512x512/val/*.tfrec') \nTEST_FILENAMES    = tf.io.gfile.glob(GCS_DS_PATH + '/tfrecords-jpeg-512x512/test/*.tfrec')","metadata":{"_uuid":"3397dbb0-6b3f-467f-ab5c-732788ea4b53","_cell_guid":"65aa6627-ddda-4c99-a48b-9917558b4b69","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2021-09-07T19:12:44.176998Z","iopub.execute_input":"2021-09-07T19:12:44.177304Z","iopub.status.idle":"2021-09-07T19:12:44.438154Z","shell.execute_reply.started":"2021-09-07T19:12:44.177275Z","shell.execute_reply":"2021-09-07T19:12:44.437194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data Augmentation of the External Data\n\nNote: In-depth understanding of the data augmentation, visit [Dmitry's Notebook](https://www.kaggle.com/dmitrynokhrin/densenet201-aug-additional-data)\n","metadata":{}},{"cell_type":"code","source":"SEED = 2020\n\ndef random_blockout(img, sl=0.1, sh=0.2, rl=0.4):\n    p=random.random()\n    if p>=0.25:\n        w, h, c = IMAGE_SIZE[0], IMAGE_SIZE[1], 3\n        origin_area = tf.cast(h*w, tf.float32)\n\n        e_size_l = tf.cast(tf.round(tf.sqrt(origin_area * sl * rl)), tf.int32)\n        e_size_h = tf.cast(tf.round(tf.sqrt(origin_area * sh / rl)), tf.int32)\n\n        e_height_h = tf.minimum(e_size_h, h)\n        e_width_h = tf.minimum(e_size_h, w)\n\n        erase_height = tf.random.uniform(shape=[], minval=e_size_l, maxval=e_height_h, dtype=tf.int32)\n        erase_width = tf.random.uniform(shape=[], minval=e_size_l, maxval=e_width_h, dtype=tf.int32)\n\n        erase_area = tf.zeros(shape=[erase_height, erase_width, c])\n        erase_area = tf.cast(erase_area, tf.uint8)\n\n        pad_h = h - erase_height\n        pad_top = tf.random.uniform(shape=[], minval=0, maxval=pad_h, dtype=tf.int32)\n        pad_bottom = pad_h - pad_top\n\n        pad_w = w - erase_width\n        pad_left = tf.random.uniform(shape=[], minval=0, maxval=pad_w, dtype=tf.int32)\n        pad_right = pad_w - pad_left\n\n        erase_mask = tf.pad([erase_area], [[0,0],[pad_top, pad_bottom], [pad_left, pad_right], [0,0]], constant_values=1)\n        erase_mask = tf.squeeze(erase_mask, axis=0)\n        erased_img = tf.multiply(tf.cast(img,tf.float32), tf.cast(erase_mask, tf.float32))\n\n        return tf.cast(erased_img, img.dtype)\n    else:\n        return tf.cast(img, img.dtype)\n\n    \ndef data_augment_v2(image, label):\n    # Thanks to the dataset.prefetch(AUTO) statement in the next function (below), this happens essentially for free on TPU. \n    # Data pipeline code is executed on the \"CPU\" part of the TPU while the TPU itself is computing gradients.\n    \n    flag = random.randint(1,3)\n    coef_1 = random.randint(70, 90) * 0.01\n    coef_2 = random.randint(70, 90) * 0.01\n    \n    if flag == 1:\n        image = tf.image.random_flip_left_right(image, seed=SEED)\n    elif flag == 2:\n        image = tf.image.random_flip_up_down(image, seed=SEED)\n    else:\n        image = tf.image.random_crop(image, [int(IMAGE_SIZE[0]*coef_1), int(IMAGE_SIZE[0]*coef_2), 3],seed=SEED)\n        \n    image = random_blockout(image)\n    \n    return image, label ","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:44.440659Z","iopub.execute_input":"2021-09-07T19:12:44.440963Z","iopub.status.idle":"2021-09-07T19:12:44.458206Z","shell.execute_reply.started":"2021-09-07T19:12:44.440934Z","shell.execute_reply":"2021-09-07T19:12:44.457134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data Augmentation\nInspired from Xuanzhi Huang and Rahul Paul's [notebook](https://www.kaggle.com/xuanzhihuang/flower-classification-densenet-201)\n\n","metadata":{}},{"cell_type":"markdown","source":"TensorFlow Addons is a repository of contributions that conform to well-established API patterns, but implement new functionality not available in core TensorFlow. TensorFlow natively supports a large number of operators, layers, metrics, losses, and optimizers. [Read out more]([https://github.com/tensorflow/addons]) ","metadata":{}},{"cell_type":"code","source":"import tensorflow_addons as tfa\n\n# Randomly make some changes to the images and return the new images and labels\ndef data_augment_v3(image, label):\n        \n    # Set seed for data augmentation\n    seed = 100\n    \n    # Randomly resize and then crop images\n    image = tf.image.resize(image, [720, 720])\n    image = tf.image.random_crop(image, [512, 512, 3], seed = seed)\n\n    # Randomly reset brightness of images\n    image = tf.image.random_brightness(image, 0.6, seed = seed)\n    \n    # Randomly reset saturation of images\n    image = tf.image.random_saturation(image, 3, 5, seed = seed)\n        \n    # Randomly reset contrast of images\n    image = tf.image.random_contrast(image, 0.3, 0.5, seed = seed)\n\n    # Randomly reset hue of images, but this will make the colors really weird, which we think will not happen\n    # in common photography\n    # image = tf.image.random_hue(image, 0.5, seed = seed)\n    \n    # Blur images\n    image = tfa.image.mean_filter2d(image, filter_shape = 10)\n    \n    # Randomly flip images\n    image = tf.image.random_flip_left_right(image, seed = seed)\n    image = tf.image.random_flip_up_down(image, seed = seed)\n    \n    # Fail to rotate and transform images due to some bug in TensorFlow\n    # angle = random.randint(0, 180)\n    # image = tfa.image.rotate(image, tf.constant(np.pi * angle / 180))\n    # image = tfa.image.transform(image, [1.0, 1.0, -250, 0.0, 1.0, 0.0, 0.0, 0.0])\n    \n    return image, label\n","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:44.460141Z","iopub.execute_input":"2021-09-07T19:12:44.460427Z","iopub.status.idle":"2021-09-07T19:12:44.624972Z","shell.execute_reply.started":"2021-09-07T19:12:44.460400Z","shell.execute_reply":"2021-09-07T19:12:44.623945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Step4: Data Pipelines**","metadata":{"_uuid":"be386df4-fd88-446c-acd3-b44726c502bf","_cell_guid":"13037289-cb03-4574-a773-7462da69393f","trusted":true}},{"cell_type":"code","source":"# image augmentation                                  \ndef data_augment(image, label):\n    # Pad the image with a black, 3-pixel border\n    # image = tf.image.resize_with_crop_or_pad(image, HEIGHT + 6, WIDTH + 6)\n    # Randomly crop to original size from the padded image\n    # image = tf.image.random_crop(image, size=[*IMAGE_SIZE,3])\n    image = tf.image.random_flip_left_right(image)\n    #image = tf.image.random_contrast(image, 0.8, 1.2)\n    #image = tf.image.random_brightness(image, 0.1) \n    #image = tf.image.random_saturation(image, 0.7, 1.3)\n    return image, label \n\n# get training datatset with augmentation option\ndef get_training_dataset():\n    dataset = load_dataset(TRAINING_FILENAMES, 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","metadata":{"_uuid":"eee37425-1b5d-4163-91a4-ccd0493f54cd","_cell_guid":"b130af80-a092-4e37-bcdd-62a4d01811bd","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2021-09-07T19:12:44.626369Z","iopub.execute_input":"2021-09-07T19:12:44.626778Z","iopub.status.idle":"2021-09-07T19:12:44.634765Z","shell.execute_reply.started":"2021-09-07T19:12:44.626736Z","shell.execute_reply":"2021-09-07T19:12:44.633949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_validation_dataset(ordered=False):\n    dataset = load_dataset(VALIDATION_FILENAMES, 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(ordered=False):\n    dataset = load_dataset(TEST_FILENAMES, labeled=False, ordered=ordered)\n    dataset = dataset.batch(BATCH_SIZE)\n    dataset = dataset.prefetch(AUTO)\n    return dataset\n\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)\n\nNUM_TRAINING_IMAGES = count_data_items(TRAINING_FILENAMES)\nNUM_VALIDATION_IMAGES = count_data_items(VALIDATION_FILENAMES)\nNUM_TEST_IMAGES = count_data_items(TEST_FILENAMES)\nprint('Dataset: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAINING_IMAGES, NUM_VALIDATION_IMAGES, NUM_TEST_IMAGES))","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:44.636014Z","iopub.execute_input":"2021-09-07T19:12:44.636300Z","iopub.status.idle":"2021-09-07T19:12:44.655325Z","shell.execute_reply.started":"2021-09-07T19:12:44.636272Z","shell.execute_reply":"2021-09-07T19:12:44.653938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**To make TPU faster, increase the batch size**\n","metadata":{}},{"cell_type":"code","source":"strategy.num_replicas_in_sync","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:44.656996Z","iopub.execute_input":"2021-09-07T19:12:44.657562Z","iopub.status.idle":"2021-09-07T19:12:44.675118Z","shell.execute_reply.started":"2021-09-07T19:12:44.657512Z","shell.execute_reply":"2021-09-07T19:12:44.674252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"16 * strategy.num_replicas_in_sync","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:44.676424Z","iopub.execute_input":"2021-09-07T19:12:44.676954Z","iopub.status.idle":"2021-09-07T19:12:44.686430Z","shell.execute_reply.started":"2021-09-07T19:12:44.676923Z","shell.execute_reply":"2021-09-07T19:12:44.685643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 16 * strategy.num_replicas_in_sync\n\nds_train = get_training_dataset()\nds_valid = get_validation_dataset()\nds_test = get_validation_dataset()\n\n\nprint(\"Training:\" , ds_train)\nprint(\"Validation:\" , ds_valid)\nprint(\"Testing: \", ds_test)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:44.687643Z","iopub.execute_input":"2021-09-07T19:12:44.688161Z","iopub.status.idle":"2021-09-07T19:12:44.967777Z","shell.execute_reply.started":"2021-09-07T19:12:44.688131Z","shell.execute_reply":"2021-09-07T19:12:44.966687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"These datasets are tf.data.Dataset objects. You can think about a dataset in TensorFlow as a stream of data records. The training and validation sets are streams of (image, label) pairs.","metadata":{}},{"cell_type":"code","source":"np.set_printoptions(threshold=15, linewidth=80)\n\n\nprint(\"Training DataStream Shape: \")\nfor image, label in ds_train.take(5):\n    print(image.numpy().shape, label.numpy().shape)\nprint(\"Training datasteam label examples: \", label.numpy())\n    ","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:44.969035Z","iopub.execute_input":"2021-09-07T19:12:44.969344Z","iopub.status.idle":"2021-09-07T19:12:53.164965Z","shell.execute_reply.started":"2021-09-07T19:12:44.969314Z","shell.execute_reply":"2021-09-07T19:12:53.164202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The test set is a stream of (image, idnum) pairs; idnum here is the unique identifier given to the image that we'll use later when we make our submission as a csv file","metadata":{}},{"cell_type":"code","source":"print(\"Test DataStream Shape: \")\nfor image, idnum in ds_test.take(5):\n    print(image.numpy().shape, idnum.numpy().shape)\nprint(\"Test datasteam IDs examples: \", idnum.numpy().astype('U'))","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:53.166008Z","iopub.execute_input":"2021-09-07T19:12:53.166417Z","iopub.status.idle":"2021-09-07T19:12:57.991152Z","shell.execute_reply.started":"2021-09-07T19:12:53.166386Z","shell.execute_reply":"2021-09-07T19:12:57.990057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Step5: Data Exploration**","metadata":{}},{"cell_type":"code","source":"def 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, 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 the case for test data)\n    return numpy_images, numpy_labels\n    ","metadata":{"_uuid":"96f0db97-31d5-4a38-b596-81abd44b5df0","_cell_guid":"cafe2ad5-528a-4074-9704-f851ed1f74e7","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2021-09-07T19:12:57.992305Z","iopub.execute_input":"2021-09-07T19:12:57.992618Z","iopub.status.idle":"2021-09-07T19:12:57.998152Z","shell.execute_reply.started":"2021-09-07T19:12:57.992589Z","shell.execute_reply":"2021-09-07T19:12:57.997150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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], \n                                'OK' if correct else 'NO', \n                                u\"\\u2192\" if not correct else '',\n                                CLASSES[correct_label] if not correct else ''), correct","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:57.999731Z","iopub.execute_input":"2021-09-07T19:12:58.000026Z","iopub.status.idle":"2021-09-07T19:12:58.016770Z","shell.execute_reply.started":"2021-09-07T19:12:57.999997Z","shell.execute_reply":"2021-09-07T19:12:58.015474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:58.018330Z","iopub.execute_input":"2021-09-07T19:12:58.018691Z","iopub.status.idle":"2021-09-07T19:12:58.028274Z","shell.execute_reply.started":"2021-09-07T19:12:58.018658Z","shell.execute_reply":"2021-09-07T19:12:58.027343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_batch_of_images(databatch, predictions=None, display_mismatches_only=False):\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 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        if display_mismatches_only:\n            if predictions[i] != label:\n                subplot = display_one_flower(image, title, subplot, not correct, titlesize=dynamic_titlesize)\n        else:        \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()","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:58.029847Z","iopub.execute_input":"2021-09-07T19:12:58.030313Z","iopub.status.idle":"2021-09-07T19:12:58.045278Z","shell.execute_reply.started":"2021-09-07T19:12:58.030269Z","shell.execute_reply":"2021-09-07T19:12:58.044014Z"},"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.'])\n","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:58.046943Z","iopub.execute_input":"2021-09-07T19:12:58.047508Z","iopub.status.idle":"2021-09-07T19:12:58.060811Z","shell.execute_reply.started":"2021-09-07T19:12:58.047440Z","shell.execute_reply":"2021-09-07T19:12:58.059795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_training_curves_v2(training, validation, learning_rate_list, 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, color='b')\n    #ax.set_ylim(0.28,1.05)\n    ax.set_xlabel('epoch')\n    ax.legend(['train', 'valid.', 'learning rate'])        \n    \n    ax2 = ax.twinx() #The Axes. twinx() function in axes module of matplotlib library is used to create a twin Axes sharing the xaxis. \n    ax2.plot(learning_rate_list, 'g-')\n    ax2.set_ylabel('learning rate', color='g')","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:58.062176Z","iopub.execute_input":"2021-09-07T19:12:58.062500Z","iopub.status.idle":"2021-09-07T19:12:58.084404Z","shell.execute_reply.started":"2021-09-07T19:12:58.062439Z","shell.execute_reply":"2021-09-07T19:12:58.083555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You can display a single batch of images from a dataset with another of our helper functions. The next cell will turn the dataset into an iterator of batches of 50 images.","metadata":{}},{"cell_type":"markdown","source":"### Image Analysis with or without Augmentation ","metadata":{}},{"cell_type":"code","source":"# get original training_dataset without augmentation\nori_train_set = get_training_dataset()\n\nori_image_batch = (next(iter(ori_train_set.unbatch().batch(16)))) # get a batch for \nimages, _ = batch_to_numpy_images_and_labels(ori_image_batch)\n\n# function to show image with random data augmentation\ndef show_aug(image):\n    plt.figure(figsize=(12,2))\n    plt.subplot(1,6,1)\n    plt.imshow(image)\n    plt.title('no augmentation')\n    plt.axis('off')\n    plt.subplot(1,6,3)\n    plt.imshow(tf.image.random_flip_left_right(image))       # augmented with random flip\n    plt.title('rdm flip L/R')\n    plt.axis('off')    \n    plt.subplot(1,6,4)\n    plt.imshow(tf.image.random_contrast(image, 0.90, 0.99))  # augmented with contrast\n    plt.title('rdm contrast')\n    plt.axis('off')\n    plt.subplot(1,6,5)\n    plt.imshow(tf.image.random_brightness(image, 0.1))       # augmented with brightness\n    plt.title('rdm brightness')\n    plt.axis('off')\n    plt.subplot(1,6,6)\n    plt.imshow(tf.image.random_saturation(image, 0.8, 0.9))  # augmented with saturation\n    plt.title('rdm saturation')\n    plt.axis('off')\n    plt.subplot(1,6,2)\n    image = data_augment(image, None)\n    plt.imshow(image[0])  # any random combinations of the above augmenations, if any\n    plt.title('rdm aug combo')\n    plt.axis('off')    \n    plt.show()\n\n# show images\nprint('Training Dataset')\nprint('Sample Images: Original versus w/ Random Augmentation')\nfor im in images:\n    show_aug(im)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:12:58.085688Z","iopub.execute_input":"2021-09-07T19:12:58.085963Z","iopub.status.idle":"2021-09-07T19:13:11.434359Z","shell.execute_reply.started":"2021-09-07T19:12:58.085937Z","shell.execute_reply":"2021-09-07T19:13:11.433339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_iter = iter(ds_train.unbatch().batch(50))\n\n#Use the Python next function to pop out the next batch in the stream and display it with the helper function.\none_batch = next(ds_iter)\ndisplay_batch_of_images(one_batch)\n","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:11.435861Z","iopub.execute_input":"2021-09-07T19:13:11.436404Z","iopub.status.idle":"2021-09-07T19:13:19.097284Z","shell.execute_reply.started":"2021-09-07T19:13:11.436361Z","shell.execute_reply":"2021-09-07T19:13:19.096253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds_iter = iter(ds_train.unbatch().batch(50))\n\n#Use the Python next function to pop out the next batch in the stream and display it with the helper function.\none_batch = next(ds_iter)\ndisplay_batch_of_images(one_batch)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:19.098797Z","iopub.execute_input":"2021-09-07T19:13:19.099320Z","iopub.status.idle":"2021-09-07T19:13:27.065590Z","shell.execute_reply.started":"2021-09-07T19:13:19.099281Z","shell.execute_reply":"2021-09-07T19:13:27.064306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Step6: Data Augmentation Sample**","metadata":{}},{"cell_type":"code","source":"row = 4\ncol = 4\nBatch_elements = get_training_dataset().unbatch()\nsingle_element = tf.data.Dataset.from_tensors(next(iter(Batch_elements)))\n# Map the images to the data augmentation function for image processing\naugmented_element = single_element.repeat().map(data_augment).batch(row * col)\n\nfor (img, label) in augmented_element:\n    plt.figure(figsize = (15, int(15 * row / col)))\n    for j in range(row * col):\n        plt.subplot(row, col, j + 1)\n        plt.axis('off')\n        plt.imshow(img[j, ])\n    plt.show()\n    break","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:27.070589Z","iopub.execute_input":"2021-09-07T19:13:27.070916Z","iopub.status.idle":"2021-09-07T19:13:31.878005Z","shell.execute_reply.started":"2021-09-07T19:13:27.070887Z","shell.execute_reply":"2021-09-07T19:13:31.877000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Augmentation Sample V2 (Implementing Image Processing)","metadata":{"execution":{"iopub.status.busy":"2021-05-26T08:04:27.372986Z","iopub.execute_input":"2021-05-26T08:04:27.373408Z","iopub.status.idle":"2021-05-26T08:04:27.379636Z","shell.execute_reply.started":"2021-05-26T08:04:27.373342Z","shell.execute_reply":"2021-05-26T08:04:27.378343Z"}}},{"cell_type":"code","source":"# Map the images to the data augmentation function for image processing\naugmented_element = single_element.repeat().map(data_augment_v2).batch(row * col)\n\nfor (img, label) in augmented_element:\n    plt.figure(figsize = (15, int(15 * row / col)))\n    for j in range(row * col):\n        plt.subplot(row, col, j + 1)\n        #plt.axis('off')\n        plt.imshow(img[j, ])\n    plt.show()\n    break","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:31.882038Z","iopub.execute_input":"2021-09-07T19:13:31.882676Z","iopub.status.idle":"2021-09-07T19:13:35.635594Z","shell.execute_reply.started":"2021-09-07T19:13:31.882625Z","shell.execute_reply":"2021-09-07T19:13:35.633834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Augmentation Sample V3 (Implementing Image Processing)","metadata":{}},{"cell_type":"code","source":"augmented_element = single_element.repeat().map(data_augment_v3).batch(row * col)\n\nfor (img, label) in augmented_element:\n    plt.figure(figsize = (15, int(15 * row / col)))\n    for j in range(row * col):\n        plt.subplot(row, col, j + 1)\n        plt.axis('off')\n        plt.imshow(img[j, ])\n    plt.show()\n    break","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:35.637206Z","iopub.execute_input":"2021-09-07T19:13:35.637648Z","iopub.status.idle":"2021-09-07T19:13:46.014728Z","shell.execute_reply.started":"2021-09-07T19:13:35.637606Z","shell.execute_reply":"2021-09-07T19:13:46.013870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Step7: Defining The Model**","metadata":{}},{"cell_type":"markdown","source":"Now we're ready to create a neural network for classifying images! We'll use what's known as transfer learning. With transfer learning, you reuse part of a pretrained model to get a head-start on a new dataset.\n\nFor this tutorial, we'll to use a model called VGG16 pretrained on [ImageNet](https://image-net.org/)). Later, you might want to experiment with [other models ](https://www.tensorflow.org/api_docs/python/tf/keras/applications)included with Keras. ([Xception](https://www.tensorflow.org/api_docs/python/tf/keras/applications/xception/Xception) wouldn't be a bad choice.)\n\nThe distribution strategy we created earlier contains a [context manager](https://docs.python.org/3/reference/compound_stmts.html#with), strategy.scope. This context manager tells TensorFlow how to divide the work of training among the eight TPU cores. When using TensorFlow with a TPU, it's important to define your model in a strategy.scope() context.","metadata":{}},{"cell_type":"code","source":"# Check the image size(dimensions) before training the data\n[*IMAGE_SIZE, 3]","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:46.015846Z","iopub.execute_input":"2021-09-07T19:13:46.016235Z","iopub.status.idle":"2021-09-07T19:13:46.021368Z","shell.execute_reply.started":"2021-09-07T19:13:46.016205Z","shell.execute_reply":"2021-09-07T19:13:46.020618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\",\".join(tf.keras.applications.__dir__())","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:46.022470Z","iopub.execute_input":"2021-09-07T19:13:46.022856Z","iopub.status.idle":"2021-09-07T19:13:46.038360Z","shell.execute_reply.started":"2021-09-07T19:13:46.022827Z","shell.execute_reply":"2021-09-07T19:13:46.037077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## To kepp track the model performance and findout the best suitable model through model-monitoring instance","metadata":{}},{"cell_type":"code","source":"checkpoint_filepath = \"Petals_to_the_Metal-70K_images-trainable_True-MobileNetV2.h5\" #\"Petals_to_the_Metal-70K_images-trainable_True-DenseNet201.h5\"\n\ncheckpoint = tf.keras.callbacks.ModelCheckpoint(\n    filepath=checkpoint_filepath,\n    save_weights_only=True,\n    monitor='val_loss',\n    mode='min',\n    save_best_only=True\n)\n\n# This callback will stop the training when there is no improvement in the validation loss for three consecutive epochs. \nearly_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:46.039866Z","iopub.execute_input":"2021-09-07T19:13:46.040319Z","iopub.status.idle":"2021-09-07T19:13:46.050586Z","shell.execute_reply.started":"2021-09-07T19:13:46.040285Z","shell.execute_reply":"2021-09-07T19:13:46.049671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Important : How to track learning rate during model training?\n\nNote: Stochastic gradient descent is an optimization algorithm that estimates the error gradient for the current state of the model using examples from the training dataset, then updates the weights of the model using the back-propagation of errors algorithm, referred to as simply backpropagation.\nThe amount that the weights are updated during training is referred to as the step size or the “learning rate.”\nSpecifically, the learning rate is a configurable hyperparameter used in the training of neural networks that has a small positive value, often in the range between 0.0 and 1.0.\nFor more information review the article of Jason Brownlee \"[How to Configure the Learning Rate When Training Deep Learning Neural Networks](https://machinelearningmastery.com/learning-rate-for-deep-learning-neural-networks/)\"","metadata":{}},{"cell_type":"markdown","source":"[Track learning rate during Training](https://stackoverflow.com/questions/49127214/keras-how-to-output-learning-rate-onto-tensorboard)\nNotFoundError: Container worker does not exist. (Could not find resource: worker/_AnonymousVar8064) Encountered when executing an operation using EagerExecutor. This error cancels all future operations and poisons their output tensors.","metadata":{}},{"cell_type":"code","source":"NotFoundError = \"\"\"\nclass LRTensorBoard(TensorBoard):\n    def __init__(self, log_dir, **kwargs):  # add other arguments to __init__ if you need\n        super().__init__(log_dir=log_dir, **kwargs)\n\n    def on_epoch_end(self, epoch, logs=None):\n        logs = logs or {}\n        logs.update({'lr': K.eval(self.model.optimizer.lr)})\n        super().on_epoch_end(epoch, logs)\n\nlr_tracking = LRTensorBoard(log_dir=\"./lr_tracking\")\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:46.052182Z","iopub.execute_input":"2021-09-07T19:13:46.052562Z","iopub.status.idle":"2021-09-07T19:13:46.060912Z","shell.execute_reply.started":"2021-09-07T19:13:46.052532Z","shell.execute_reply":"2021-09-07T19:13:46.059951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Tuning Custom [Callbacks](https://www.tensorflow.org/guide/keras/custom_callback)","metadata":{}},{"cell_type":"code","source":"class LearningRateTracking(tf.keras.callbacks.Callback):\n    def on_epoch_end(self, epoch, logs=None):\n        keys = list(logs.keys())\n        print(\"End epoch {} of training; got log keys: {}\".format(epoch, keys))\n        \n        #logs = logs or {}\n        #logs.update({'lr': K.eval(self.model.optimizer.lr)}) #optimizer._decayed_lr('float32').numpy()\n        #return \n\n#lr_tracking = LearningRateTracking()\n\n# For reading about EfficientNetB7 visit https://keras.io/api/applications/efficientnet/#efficientnetb7-function\nuse_efficientnet = False #tuning9\nif use_efficientnet:\n    !pip install -q efficientnet\n    from efficientnet.tfkeras import EfficientNetB7  ","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:46.062244Z","iopub.execute_input":"2021-09-07T19:13:46.062569Z","iopub.status.idle":"2021-09-07T19:13:46.077078Z","shell.execute_reply.started":"2021-09-07T19:13:46.062541Z","shell.execute_reply":"2021-09-07T19:13:46.075934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Calculate the Weight of each [Flower Class](https://www.kaggle.com/xuanzhihuang/flower-classification-densenet-201)","metadata":{}},{"cell_type":"code","source":"weight_per_class = True\n\nif weight_per_class:\n    from collections import Counter\n    import gc #Garbage Collector https://docs.python.org/3/library/gc.html\n\n    gc.enable() #Enable automatic garbage collection.\n\n    def get_training_dataset_raw():\n        dataset = load_dataset(TRAINING_FILENAMES, labeled = True, ordered = False)\n        return dataset\n\n    raw_training_dataset = get_training_dataset_raw()\n\n    label_counter = Counter()\n    for images, labels in raw_training_dataset:\n        label_counter.update([labels.numpy()])\n\n    del raw_training_dataset    \n\n    TARGET_NUM_PER_CLASS = 122 #?\n\n    def get_weight_for_class(class_id):\n        counting = label_counter[class_id]\n        weight = TARGET_NUM_PER_CLASS / counting\n        return weight\n\n    weight_per_class = {class_id: get_weight_for_class(class_id) for class_id in range(104)}\n    \nif weight_per_class:\n    data = pd.DataFrame.from_dict(weight_per_class, orient='index', columns=['class_weight'])\n    plt.figure(figsize=(30, 9))\n\n    #barplot color based on value\n    bplot = sns.barplot(x=data.index, y='class_weight', data=data, palette= cm.Blues(data['class_weight']*0.15));\n    for p in bplot.patches:\n        bplot.annotate(format(p.get_height(), '.1f'), \n                       (p.get_x() + p.get_width() / 2., p.get_height()), \n                       ha = 'center', va = 'center', \n                       xytext = (0, 9), \n                       textcoords = 'offset points')\n    plt.xlabel(\"Class\", size=14)\n    plt.ylabel(\"Class weight (inverse of %)\", size=14)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:13:46.078378Z","iopub.execute_input":"2021-09-07T19:13:46.078845Z","iopub.status.idle":"2021-09-07T19:15:58.236920Z","shell.execute_reply.started":"2021-09-07T19:13:46.078807Z","shell.execute_reply":"2021-09-07T19:15:58.235811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Ensemble Learning Sample Code**","metadata":{}},{"cell_type":"code","source":"\"\"\"Model_type = \"Model1\"\nEPOCHS = 15\n\n#DenseNet201\ndef get_model1():\n    with strategy.scope():\n        dn201 = tf.keras.applications.DenseNet201(weights='imagenet', include_top=False, input_shape=[*IMAGE_SIZE, 3])\n        dn201.trainable = True # Full Training\n\n        model1 = tf.keras.Sequential([\n            dn201,\n            tf.keras.layers.GlobalAveragePooling2D(),\n            tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n        ])\n\n    model1.compile(\n        optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False),\n        loss = 'sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy']\n    )\n    return model1\n\n#Efficient Net B7\ndef get_model2():\n    with strategy.scope():\n        enb7 = efn.EfficientNetB7(weights='noisy-student', include_top=False, input_shape=[*IMAGE_SIZE, 3])\n        enb7.trainable = True # Full Training\n\n        model2 = tf.keras.Sequential([\n            enb7,\n            tf.keras.layers.GlobalAveragePooling2D(),\n            tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n        ])\n\n    model2.compile(\n        optimizer = tf.keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False),\n        loss = 'sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy']\n        )\n    return model2\n    \"\"\"","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:15:58.238473Z","iopub.execute_input":"2021-09-07T19:15:58.238824Z","iopub.status.idle":"2021-09-07T19:15:58.245878Z","shell.execute_reply.started":"2021-09-07T19:15:58.238790Z","shell.execute_reply":"2021-09-07T19:15:58.244874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Defining of Model without Ensemble Methods","metadata":{}},{"cell_type":"code","source":"ensemble_learning_models = False","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:15:58.247417Z","iopub.execute_input":"2021-09-07T19:15:58.247867Z","iopub.status.idle":"2021-09-07T19:15:58.263062Z","shell.execute_reply.started":"2021-09-07T19:15:58.247824Z","shell.execute_reply":"2021-09-07T19:15:58.261946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nAlternatively, data augmentation may be done by creating image preprocessing layers\n   and make them part of the model, as show below:  \n\ndata_augmentation = tf.keras.Sequential([\n   tf.keras.layers.experimental.preprocessing.RandomFlip(\"horizontal_and_vertical\", seed = SEED),\n   tf.keras.layers.experimental.preprocessing.RandomRotation(0.2, seed = SEED)\n])\n'''\n\nif not ensemble_learning_models:\n    with strategy.scope():\n        \n        #pretrained_model = tf.keras.applications.VGG16\n        #pretrained_model = tf.keras.applications.DenseNet201\n        #pretrained_model = tf.keras.applications.InceptionResNetV2\n        #pretrained_model = tf.keras.applications.InceptionV3\n        #pretrained_model = tf.keras.applications.MobileNet\n        #pretrained_model = tf.keras.applications.MobileNetV2\n        #pretrained_model = tf.keras.applications.NASNetMobile\n        #pretrained_model = tf.keras.applications.ResNet50\n        #pretrained_model = tf.keras.applications.ResNet101V2\n        #pretrained_model = tf.keras.applications.VGG19\n        #pretrained_model = tf.keras.applications.Xception\n        #pretrained_model = tf.keras.applications.DenseNet201 \n        #pretrained_model = EfficientNetB7\n\n        pretrained_model = tf.keras.applications.MobileNetV2(\n            include_top=False ,\n            weights='imagenet', #tuning weights='noisy-student' instead of 'imagenet'\n                                #Self-training with Noisy Student improves ImageNet classification https://arxiv.org/abs/1911.04252) \n            #pooling='avg'\n            input_shape=[*IMAGE_SIZE, 3]\n        )\n\n        pretrained_model.trainable = True #tuning pretrained_model.trainable = True\n\n        model = tf.keras.Sequential([\n            pretrained_model, #Base pretrained on ImageNet to extract features from images\n\n            tf.keras.layers.GlobalAveragePooling2D(), ##Attach a new head to act as a classifier\n            #tf.keras.layers.Dropout(0.3), #tuning\n            tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n        ])","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:15:58.264708Z","iopub.execute_input":"2021-09-07T19:15:58.265150Z","iopub.status.idle":"2021-09-07T19:16:07.626368Z","shell.execute_reply.started":"2021-09-07T19:15:58.265105Z","shell.execute_reply":"2021-09-07T19:16:07.625311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"  model.compile(\n        optimizer='nadam', #tuning2 optimizer='nadam',\n        loss = 'sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy'],\n    )\n    \nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:16:07.628307Z","iopub.execute_input":"2021-09-07T19:16:07.628649Z","iopub.status.idle":"2021-09-07T19:16:07.690815Z","shell.execute_reply.started":"2021-09-07T19:16:07.628619Z","shell.execute_reply":"2021-09-07T19:16:07.689788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.utils.plot_model(model, show_shapes=True)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:16:07.692073Z","iopub.execute_input":"2021-09-07T19:16:07.692361Z","iopub.status.idle":"2021-09-07T19:16:08.166408Z","shell.execute_reply.started":"2021-09-07T19:16:07.692324Z","shell.execute_reply":"2021-09-07T19:16:08.165314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Step8: Model Training**\n### Customize learning rate scheduler\n\nwe have to train this model using custom learning rate scheduling.\n","metadata":{}},{"cell_type":"code","source":"if not ensemble_learning_models:\n    # Learning Rate Schedule for Fine Tuning #\n    def exponential_lr(epoch,\n                       start_lr = 0.00001, min_lr = 0.00001, max_lr = 0.00005 * strategy.num_replicas_in_sync, #tuning1\n                       rampup_epochs = 5, sustain_epochs = 0,\n                       exp_decay = 0.75): #tuning1\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\n    lr_callback = tf.keras.callbacks.LearningRateScheduler(exponential_lr, verbose=True)\n\n    rng = [i for i in range(EPOCHS)]\n    y = [exponential_lr(x) for x in rng]\n    plt.plot(rng, y)\n    print(\"Learning rate schedule: {:.3g} to {:.3g} to {:.3g}\".format(y[0], max(y), y[-1]))","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:16:08.168093Z","iopub.execute_input":"2021-09-07T19:16:08.168381Z","iopub.status.idle":"2021-09-07T19:16:08.364944Z","shell.execute_reply.started":"2021-09-07T19:16:08.168352Z","shell.execute_reply":"2021-09-07T19:16:08.363814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Fit Model (Parameters)","metadata":{}},{"cell_type":"code","source":"if not ensemble_learning_models:\n    history = model.fit(\n        ds_train,\n        validation_data=ds_valid,\n        epochs=EPOCHS,\n        steps_per_epoch=STEPS_PER_EPOCH,\n        callbacks=[lr_callback, checkpoint], # Model weights are saved at the end of every epoch, if it's the best seen so far\n        # https://www.tensorflow.org/tutorials/distribute/multi_worker_with_keras\n        class_weight = weight_per_class #tuning11\n    )","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:16:08.366333Z","iopub.execute_input":"2021-09-07T19:16:08.366739Z","iopub.status.idle":"2021-09-07T19:26:29.074953Z","shell.execute_reply.started":"2021-09-07T19:16:08.366704Z","shell.execute_reply":"2021-09-07T19:26:29.073932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visualizing Model Performance\n\nFunctions used to known the training model performaces:\n* Loss\n* Metrics","metadata":{}},{"cell_type":"code","source":"if not ensemble_learning_models:\n    display_training_curves_v2( \n        history.history['loss'],\n        history.history['val_loss'],\n        history.history['lr'],\n        'loss',\n        211,\n    )\n\n    display_training_curves_v2(\n        history.history['sparse_categorical_accuracy'],\n        history.history['val_sparse_categorical_accuracy'],\n        history.history['lr'],\n        'accuracy',\n        212,\n    )","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:29.076134Z","iopub.execute_input":"2021-09-07T19:26:29.076419Z","iopub.status.idle":"2021-09-07T19:26:29.748018Z","shell.execute_reply.started":"2021-09-07T19:26:29.076393Z","shell.execute_reply":"2021-09-07T19:26:29.746965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create plots of loss and accuracy on the training and validation sets.\n\nacc = history.history['sparse_categorical_accuracy']\nval_acc = history.history['val_sparse_categorical_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs_range = range(1, len(history.history['loss'])+1)\n\nplt.figure(figsize=(14, 14))\nplt.subplot(2, 1, 1)\nplt.plot(epochs_range, acc, label='Training Accuracy')\nplt.plot(epochs_range, val_acc, label='Validation Accuracy')\nplt.legend(loc='lower right')\nplt.title('Training and Validation Accuracy')\nplt.xlabel('Epoch')\n\nplt.subplot(2, 1, 2)\nplt.plot(epochs_range, loss, label='Training Loss')\nplt.plot(epochs_range, val_loss, label='Validation Loss')\nplt.legend(loc='upper right')\nplt.title('Training and Validation Loss')\nplt.xlabel('Epoch')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:29.749484Z","iopub.execute_input":"2021-09-07T19:26:29.749803Z","iopub.status.idle":"2021-09-07T19:26:30.130510Z","shell.execute_reply.started":"2021-09-07T19:26:29.749772Z","shell.execute_reply":"2021-09-07T19:26:30.129388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"zoom_after = 10\nif not ensemble_learning_models:\n    display_training_curves(\n        history.history['loss'][zoom_after:],\n        history.history['val_loss'][zoom_after:],\n        'loss',\n        211,\n    )\n\n    display_training_curves(\n        history.history['sparse_categorical_accuracy'][zoom_after:],\n        history.history['val_sparse_categorical_accuracy'][zoom_after:],\n        'accuracy',\n        212,\n    )","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:30.131979Z","iopub.execute_input":"2021-09-07T19:26:30.132394Z","iopub.status.idle":"2021-09-07T19:26:30.551351Z","shell.execute_reply.started":"2021-09-07T19:26:30.132352Z","shell.execute_reply":"2021-09-07T19:26:30.550322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_filepath","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:30.552822Z","iopub.execute_input":"2021-09-07T19:26:30.553398Z","iopub.status.idle":"2021-09-07T19:26:30.559063Z","shell.execute_reply.started":"2021-09-07T19:26:30.553347Z","shell.execute_reply":"2021-09-07T19:26:30.557982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not ensemble_learning_models:\n    model.load_weights(checkpoint_filepath)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:30.560158Z","iopub.execute_input":"2021-09-07T19:26:30.560443Z","iopub.status.idle":"2021-09-07T19:26:32.578824Z","shell.execute_reply.started":"2021-09-07T19:26:30.560416Z","shell.execute_reply":"2021-09-07T19:26:32.577421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Deploy the model on mobile and IOT\n\nTo deploy the models into iot and mobile devices, we need to convert the .h5 into [Tensorflow lite](https://www.tensorflow.org/lite/convert)\n\n![image.png](attachment:f253a559-b008-4a3b-93ed-f9d48f213fd9.png)\n","metadata":{},"attachments":{"f253a559-b008-4a3b-93ed-f9d48f213fd9.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAzgAAAMxCAYAAAAngxZKAAAgAElEQVR4Aex9CZQURbo18gAfywNBBAGRQYcdxQ1XEBcE3BBERBFEXAZRZBEGRBYddFQUAR0XFlERnqOoIAOoIAj0yjTQ3Tx2fpBtoFkei3IcHY9vvv/cwCizk8yq6qqs6szI2+dkZ1VWRsQXN25EfDdjyTJl+EcEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIkAEiAARIAJEgAgQASJABIgAESACRIAIEAEiQASIABEgAkSACBABIhBQBESkjvCPCBABIkAEiAARIAJEgAikCYGAus00OygIUOCkqSYzGSJABIgAESACRIAIEAGFQFD8ZNoZUAQocNjSEAEiQASIABEgAkSACKQTgYC6zTQ7KAhQ4KSzOjMtIkAEiAARIAJEgAgQgaD4ybQzoAhQ4LCRIQJE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z3/+c431WubLpn//+9+7ckbLqL9VbpVf5Y3+tnr1atu6dav93//9X76yFPt0C0ngyD769+9vp59+uv3xj3/M6b1Reqpj6tataxdccIFdc801dtlll9l1111n//73v3N6rVwl9t133+UqqRpLR/VDEvNdY4AiFwoqmKYw8SOAwKkZgTNkyBBr2rSpTZs2za666ioXzCig8fuaNWtcICMxpE0B3dlnn22/+tWvIu7AzAucfv365TXA1kU/+OAD6969uzVv3txeffXVg/JRyP/5n//5Hxs2bJi9+OKLecNQaAJnzpw5Tkg3adLECfg2bdqY9pYtW7qArE6dOs4WV6xYYeKf602Cfe/eveU9qLlO36cnIdepUydXNl9Gfco3qIxq6Ih+37p1a+vVq5f97W9/80kU3GchCZy333673P5/97vf5fReS0TLxgYPHlxed0jYpBsKndMLVzMx3Xf5wSSJBdXfu3btcj1w1Sx2QZ0Wv4iYHAVFAIFTMwJHlYoCl8MNimtS4EjUdOjQwY477jj77LPPCsrxVlRY9WTpXj777LMVHXZYvxWawFm4cKELvjQc8rnnnrPHH3/ciXwN6VRvpsS+hLYCtD59+ri5A4cFOOXkn/zkJ651W3MS8rl9+OGHridUNuR3BXLnnHOO1a9f31atWuWGf/rfHn30UTdcNdqLm8/8xTHtQhI4//mf/2nt27d3Iue9997L2e1Qr8LYsWOdjUnoxH2TvZ900kk2dOjQuGf1oPxpXpPqhgcffPCg7/lPegJBBdMUJn4EEDg1J3DUGvv888+nf9JTvv3iiy/sf//3f91QKFVOfstW4GgI1W9/+1vTnB0FVdXZ5KQ130ZDJt599103REh5yjQh9e9//7truVIrZGXX1ERXLZigYXDa/NhzCUDl238vYaWeJN/KqE9NihUHLXSQbpy6ftfcJQWrOjebTfl5//337Y033nCfmcqocs2YMcPU03Dfffe5e6QeBV3H5zmb61V2TKEKnOnTp6dFo5ZmzR+QuJHIkejOZQv38OHDrWvXrs6u0mYgj1/q+b744ovdPLdHHnkkj1dKZtIInIrvW7R+yHSkjhk5cqRrJHjooYcyHVZj31eWZ81BlVC48MILayxPubiQhpSrnldPLVvlBOIXEZOjoAggcGpW4Kh1urJNzl/d3D169DC1LEe3ygSOgvt58+a5RQg6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IAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgAAEIQAACEIAABCAAAQhAAAIQgECABP4/CCnTDNDy55sAAAAASUVORK5CYII="}}},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:32.580689Z","iopub.execute_input":"2021-09-07T19:26:32.581100Z","iopub.status.idle":"2021-09-07T19:26:32.604672Z","shell.execute_reply.started":"2021-09-07T19:26:32.581057Z","shell.execute_reply":"2021-09-07T19:26:32.603498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#if ensemble_learning_models:\ntest_ds = get_test_dataset(ordered=True)\n        #best_alpha = 0.35\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\n\nprint('Generating submission.csv file...')\n        # 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(NUM_TEST_IMAGES))).numpy().astype('U')\n\n        # Write the submission file\nnp.savetxt('submission.csv', np.rec.fromarrays([test_ids, predictions]), fmt=['%s', '%d'], delimiter=',', header='id,label', comments='')\n        # Look at the first few predictions\n","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:32.606044Z","iopub.execute_input":"2021-09-07T19:26:32.606342Z","iopub.status.idle":"2021-09-07T19:26:52.743482Z","shell.execute_reply.started":"2021-09-07T19:26:32.606313Z","shell.execute_reply":"2021-09-07T19:26:52.742380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" !head submission.csv","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:52.745114Z","iopub.execute_input":"2021-09-07T19:26:52.745548Z","iopub.status.idle":"2021-09-07T19:26:53.516881Z","shell.execute_reply.started":"2021-09-07T19:26:52.745503Z","shell.execute_reply":"2021-09-07T19:26:53.515715Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(checkpoint_filepath)\ntflite_model_name = checkpoint_filepath.replace(\".h5\" , \".tflite\")\ntflite_model_name","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:53.518773Z","iopub.execute_input":"2021-09-07T19:26:53.519199Z","iopub.status.idle":"2021-09-07T19:26:53.527311Z","shell.execute_reply.started":"2021-09-07T19:26:53.519149Z","shell.execute_reply":"2021-09-07T19:26:53.526578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Convert the model\nconverter = tf.lite.TFLiteConverter.from_keras_model(model)\ntflite_model = converter.convert()\n\n# Save the model\nwith open(tflite_model_name, 'wb') as f:\n    f.write(tflite_model)\n    \nprint('TFLiteConversion completed successfully \\U0001F680')  ","metadata":{"execution":{"iopub.status.busy":"2021-09-03T10:03:16.720391Z","iopub.execute_input":"2021-09-03T10:03:16.720778Z","iopub.status.idle":"2021-09-03T10:03:54.219867Z","shell.execute_reply.started":"2021-09-03T10:03:16.720745Z","shell.execute_reply":"2021-09-03T10:03:54.218112Z"}}},{"cell_type":"markdown","source":"### Ensemble Learning","metadata":{}},{"cell_type":"code","source":"def get_pretrained_model(model_name, image_dataset_weights, trainable=True):\n    pretrained_model= model_name(\n        include_top=False ,\n        weights=image_dataset_weights, #tuning10 weights='noisy-student' instead of 'imagenet'\n                                       #Self-training with Noisy Student improves ImageNet classification https://arxiv.org/abs/1911.04252) \n        input_shape=[*IMAGE_SIZE, 3]\n    )\n\n    pretrained_model.trainable = trainable #tuning8 pretrained_model.trainable = True\n    \n    model = tf.keras.Sequential([\n        pretrained_model, \n        tf.keras.layers.GlobalAveragePooling2D(), \n        tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n    ])\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:53.528670Z","iopub.execute_input":"2021-09-07T19:26:53.528955Z","iopub.status.idle":"2021-09-07T19:26:53.540890Z","shell.execute_reply.started":"2021-09-07T19:26:53.528929Z","shell.execute_reply":"2021-09-07T19:26:53.539942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models = []\nhistories = []","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:53.542076Z","iopub.execute_input":"2021-09-07T19:26:53.542609Z","iopub.status.idle":"2021-09-07T19:26:53.553428Z","shell.execute_reply.started":"2021-09-07T19:26:53.542576Z","shell.execute_reply":"2021-09-07T19:26:53.552481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -q efficientnet\n\nimport efficientnet.tfkeras as efn","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:26:53.555060Z","iopub.execute_input":"2021-09-07T19:26:53.555763Z","iopub.status.idle":"2021-09-07T19:27:03.181691Z","shell.execute_reply.started":"2021-09-07T19:26:53.555718Z","shell.execute_reply":"2021-09-07T19:27:03.180602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Need this line so Google will recite some incantations\n# for Turing to magically load the model onto the TPU\nwith strategy.scope():\n    enet = efn.EfficientNetB7(\n        input_shape=(IMAGE_SIZE[0], IMAGE_SIZE[1], 3),\n        weights='imagenet',\n        include_top=False\n    )\n    \n    enet.trainable = True\n\n    model = tf.keras.Sequential([\n        enet,\n        tf.keras.layers.GlobalAveragePooling2D(),\n        tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n    ])\n            \nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(lr=0.0001),\n    loss = 'sparse_categorical_crossentropy',\n    metrics=['sparse_categorical_accuracy']\n)\n\nmodel.summary()\n\nmodels.append(model)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:27:03.183425Z","iopub.execute_input":"2021-09-07T19:27:03.183880Z","iopub.status.idle":"2021-09-07T19:27:50.897469Z","shell.execute_reply.started":"2021-09-07T19:27:03.183834Z","shell.execute_reply":"2021-09-07T19:27:50.896299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(\n    get_training_dataset(), \n    steps_per_epoch=STEPS_PER_EPOCH,\n    epochs=EPOCHS,\n    callbacks=[lr_callback],\n    validation_data=None if ensemble_learning_models else get_validation_dataset()\n)\n\nhistories.append(history)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T19:27:50.898978Z","iopub.execute_input":"2021-09-07T19:27:50.899396Z","iopub.status.idle":"2021-09-07T20:02:47.320960Z","shell.execute_reply.started":"2021-09-07T19:27:50.899350Z","shell.execute_reply":"2021-09-07T20:02:47.320167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not ensemble_learning_models:\n    display_training_curves(history.history['loss'], history.history['val_loss'], 'loss', 211)\n    display_training_curves(history.history['sparse_categorical_accuracy'], history.history['val_sparse_categorical_accuracy'], 'accuracy', 212)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:02:47.322118Z","iopub.execute_input":"2021-09-07T20:02:47.322580Z","iopub.status.idle":"2021-09-07T20:02:47.831464Z","shell.execute_reply.started":"2021-09-07T20:02:47.322542Z","shell.execute_reply":"2021-09-07T20:02:47.830669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications import DenseNet201","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:02:47.832592Z","iopub.execute_input":"2021-09-07T20:02:47.833030Z","iopub.status.idle":"2021-09-07T20:02:47.837377Z","shell.execute_reply.started":"2021-09-07T20:02:47.832999Z","shell.execute_reply":"2021-09-07T20:02:47.836372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with strategy.scope():\n    rnet = DenseNet201(\n        input_shape=(IMAGE_SIZE[0], IMAGE_SIZE[1], 3),\n        weights='imagenet',\n        include_top=False\n    )\n    \n    rnet.trainable = True\n\n    model = tf.keras.Sequential([\n        rnet,\n        tf.keras.layers.GlobalAveragePooling2D(),\n        tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n    ])\n        \nmodel.compile(\n    optimizer=tf.keras.optimizers.Adam(lr=0.0001),\n    loss = 'sparse_categorical_crossentropy',\n    metrics=['sparse_categorical_accuracy']\n)\n\nmodel.summary()\n\nmodels.append(model)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:02:47.838652Z","iopub.execute_input":"2021-09-07T20:02:47.838947Z","iopub.status.idle":"2021-09-07T20:03:25.773883Z","shell.execute_reply.started":"2021-09-07T20:02:47.838920Z","shell.execute_reply":"2021-09-07T20:03:25.772775Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(\n    get_training_dataset(), \n    steps_per_epoch=STEPS_PER_EPOCH,\n    epochs=EPOCHS, \n    callbacks=[lr_callback],\n    validation_data=None if ensemble_learning_models else get_validation_dataset()\n)\n\nhistories.append(history)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:03:57.579372Z","iopub.execute_input":"2021-09-07T20:03:57.579788Z","iopub.status.idle":"2021-09-07T20:25:04.412250Z","shell.execute_reply.started":"2021-09-07T20:03:57.579753Z","shell.execute_reply":"2021-09-07T20:25:04.411473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not ensemble_learning_models:\n    display_training_curves(history.history['loss'], history.history['val_loss'], 'loss', 211)\n    display_training_curves(history.history['sparse_categorical_accuracy'], history.history['val_sparse_categorical_accuracy'], 'accuracy', 212)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:25:04.415865Z","iopub.execute_input":"2021-09-07T20:25:04.416616Z","iopub.status.idle":"2021-09-07T20:25:04.911754Z","shell.execute_reply.started":"2021-09-07T20:25:04.416574Z","shell.execute_reply":"2021-09-07T20:25:04.910757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not ensemble_learning_models:\n    cmdataset = get_validation_dataset(ordered=True) # since we are splitting the dataset and iterating separately on images and labels, order matters.\n    images_ds = cmdataset.map(lambda image, label: image)\n    labels_ds = cmdataset.map(lambda image, label: label).unbatch()\n    cm_correct_labels = next(iter(labels_ds.batch(NUM_VALIDATION_IMAGES))).numpy() # get everything as one batch\n    cm_probabilities = (models[0].predict(images_ds) + models[1].predict(images_ds)) / 2\n    cm_predictions = np.argmax(cm_probabilities, axis=-1)\n    print(\"Correct   labels: \", cm_correct_labels.shape, cm_correct_labels)\n    print(\"Predicted labels: \", cm_predictions.shape, cm_predictions)","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:25:04.913433Z","iopub.execute_input":"2021-09-07T20:25:04.913793Z","iopub.status.idle":"2021-09-07T20:25:54.676789Z","shell.execute_reply.started":"2021-09-07T20:25:04.913763Z","shell.execute_reply":"2021-09-07T20:25:54.675617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import f1_score, precision_score, recall_score, confusion_matrix, ConfusionMatrixDisplay","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:25:54.678671Z","iopub.execute_input":"2021-09-07T20:25:54.679285Z","iopub.status.idle":"2021-09-07T20:25:54.848960Z","shell.execute_reply.started":"2021-09-07T20:25:54.679238Z","shell.execute_reply":"2021-09-07T20:25:54.848036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"if not ensemble_learning_models:\n    cmat = confusion_matrix(cm_correct_labels, cm_predictions, labels=range(len(CLASSES)))\n    score = f1_score(cm_correct_labels, cm_predictions, labels=range(len(CLASSES)), average='macro')\n    precision = precision_score(cm_correct_labels, cm_predictions, labels=range(len(CLASSES)), average='macro')\n    recall = recall_score(cm_correct_labels, cm_predictions, labels=range(len(CLASSES)), average='macro')\n    plot_confusion_matrix(cmat, score, precision, recall)\n    print('f1 score: {:.3f}, precision: {:.3f}, recall: {:.3f}'.format(score, precision, recall))","metadata":{"execution":{"iopub.status.busy":"2021-09-06T10:37:37.980257Z","iopub.status.idle":"2021-09-06T10:37:37.980659Z"}}},{"cell_type":"code","source":"if not ensemble_learning_models:\n    cmdataset = get_validation_dataset(ordered=True) # since we are splitting the dataset and iterating separately on images and labels, order matters.\n    images_ds = cmdataset.map(lambda image, label: image)\n    labels_ds = cmdataset.map(lambda image, label: label).unbatch()\n    cm_correct_labels = next(iter(labels_ds.batch(NUM_VALIDATION_IMAGES))).numpy() # get everything as one batch\n\n    m1 = models[0].predict(images_ds)\n    m2 = models[1].predict(images_ds)\n\n    scores = []\n    for alpha in np.linspace(0,1,100):\n        cm_probabilities = alpha*m1+(1-alpha)*m2\n        cm_predictions = np.argmax(cm_probabilities, axis=-1)\n        scores.append(f1_score(cm_correct_labels, cm_predictions, labels=range(len(CLASSES)), average='macro'))\n\n    print(\"Correct   labels: \", cm_correct_labels.shape, cm_correct_labels)\n    print(\"Predicted labels: \", cm_predictions.shape, cm_predictions)\n    plt.plot(scores)\n\n    best_alpha = np.argmax(scores)/100\n    cm_probabilities = best_alpha*m1+(1-best_alpha)*m2\n    cm_predictions = np.argmax(cm_probabilities, axis=-1)\n","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:25:54.850118Z","iopub.execute_input":"2021-09-07T20:25:54.850401Z","iopub.status.idle":"2021-09-07T20:26:07.951403Z","shell.execute_reply.started":"2021-09-07T20:25:54.850375Z","shell.execute_reply":"2021-09-07T20:26:07.950434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not ensemble_learning_models:\n    print(best_alpha, max(scores))","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:26:57.886052Z","iopub.execute_input":"2021-09-07T20:26:57.886433Z","iopub.status.idle":"2021-09-07T20:26:57.891563Z","shell.execute_reply.started":"2021-09-07T20:26:57.886405Z","shell.execute_reply":"2021-09-07T20:26:57.890647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if not ensemble_learning_models:\n    test_ds = get_test_dataset(ordered=True)\n    #best_alpha = 0.35\n\n    print('Computing predictions...')\n    test_images_ds = test_ds.map(lambda image, idnum: image)\n    probabilities1 = models[0].predict(test_images_ds)\n    probabilities2 = models[1].predict(test_images_ds)\n\n    probabilities = best_alpha * probabilities1 + (1 - best_alpha) * probabilities2\n\n    predictions = np.argmax(probabilities, axis=-1)\n    print(predictions)\n\n    print('Generating submission.csv file...')\n    # Get image ids from test set and convert to unicode\n    test_ids_ds = test_ds.map(lambda image, idnum: idnum).unbatch()\n    test_ids = next(iter(test_ids_ds.batch(NUM_TEST_IMAGES))).numpy().astype('U')\n\n    # Write the submission file\n    np.savetxt(\n        '../working/sample_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   ","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:32:25.466019Z","iopub.execute_input":"2021-09-07T20:32:25.466427Z","iopub.status.idle":"2021-09-07T20:32:52.119440Z","shell.execute_reply.started":"2021-09-07T20:32:25.466390Z","shell.execute_reply":"2021-09-07T20:32:52.118637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cmdataset = get_validation_dataset(ordered=True)\nimages_ds = cmdataset.map(lambda image, label: image)\nlabels_ds = cmdataset.map(lambda image, label: label).unbatch()\n\ncm_correct_labels = next(iter(labels_ds.batch(NUM_VALIDATION_IMAGES))).numpy()\n\nif not ensemble_learning_models:\n    print('using_ensemble_models')\n    probabilities1 = models[0].predict(images_ds)\n    probabilities2 = models[1].predict(images_ds)\n    cm_probabilities = best_alpha * probabilities1 + (1 - best_alpha) * probabilities2\nelse:\n    cm_probabilities = model.predict(images_ds)\n    \ncm_predictions = np.argmax(cm_probabilities, axis=-1)\n\nlabels = range(len(CLASSES))\ncmat = confusion_matrix(\n    cm_correct_labels,\n    cm_predictions,\n    labels=labels,\n)\ncmat = (cmat.T / cmat.sum(axis=1)).T # normalize","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:34:02.270421Z","iopub.execute_input":"2021-09-07T20:34:02.270954Z","iopub.status.idle":"2021-09-07T20:34:14.927211Z","shell.execute_reply.started":"2021-09-07T20:34:02.270917Z","shell.execute_reply":"2021-09-07T20:34:14.926292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cmat","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:34:14.928702Z","iopub.execute_input":"2021-09-07T20:34:14.929000Z","iopub.status.idle":"2021-09-07T20:34:14.935849Z","shell.execute_reply.started":"2021-09-07T20:34:14.928961Z","shell.execute_reply":"2021-09-07T20:34:14.934769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" !head sample_submission.csv","metadata":{"execution":{"iopub.status.busy":"2021-09-07T20:32:53.753799Z","iopub.execute_input":"2021-09-07T20:32:53.754111Z","iopub.status.idle":"2021-09-07T20:32:54.563153Z","shell.execute_reply.started":"2021-09-07T20:32:53.754080Z","shell.execute_reply":"2021-09-07T20:32:54.562099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}}]}