{"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":"code","source":"# load the libraries for image processing\nimport tensorflow as tf\nimport numpy as np\n# import pandas as pd\nimport matplotlib.pyplot as plt\nimport glob\nimport os\nimport pickle\n# GCS_DS_PATH\nfrom kaggle_datasets import KaggleDatasets\nfrom tensorflow.keras.layers import Input\n\nfrom tensorflow.keras import layers\nfrom tensorflow.keras import models\nfrom tensorflow.keras import optimizers\nfrom tensorflow.keras import losses\nfrom tensorflow.keras import metrics\nfrom tensorflow.keras import callbacks\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.models import load_model\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-08T04:17:35.881415Z","iopub.execute_input":"2023-06-08T04:17:35.882300Z","iopub.status.idle":"2023-06-08T04:17:44.787754Z","shell.execute_reply.started":"2023-06-08T04:17:35.882255Z","shell.execute_reply":"2023-06-08T04:17:44.786690Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# get the path of the files containg .tfrec files\npath = '/kaggle/input/tpu-getting-started/tfrecords-jpeg-192x192'\n\n\n# get the list of all the files in the path\ntrain = tf.io.gfile.glob(path + '/train/*.tfrec')\nval = tf.io.gfile.glob(path + '/val/*.tfrec')\ntest = tf.io.gfile.glob(path + '/test/*.tfrec')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-08T04:17:44.789573Z","iopub.execute_input":"2023-06-08T04:17:44.790495Z","iopub.status.idle":"2023-06-08T04:17:44.823926Z","shell.execute_reply.started":"2023-06-08T04:17:44.790438Z","shell.execute_reply":"2023-06-08T04:17:44.822999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load the training dataset\ntrain_dataset = tf.data.TFRecordDataset(train)\n# load the validation dataset\nval_dataset = tf.data.TFRecordDataset(val)\n# load the test dataset\ntest_dataset = tf.data.TFRecordDataset(test)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T04:17:44.830039Z","iopub.execute_input":"2023-06-08T04:17:44.830758Z","iopub.status.idle":"2023-06-08T04:17:48.801116Z","shell.execute_reply.started":"2023-06-08T04:17:44.830723Z","shell.execute_reply":"2023-06-08T04:17:48.800173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define the image size\nIMAGE_SIZE = [192, 192]\n\n# define the batch size\nBATCH_SIZE = 32\n\n# define the number of epochs\nEPOCHS = 30\n\n# define the number of classes\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# define the number of classes\nNUM_CLASSES = len(CLASSES)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T04:17:48.802556Z","iopub.execute_input":"2023-06-08T04:17:48.802915Z","iopub.status.idle":"2023-06-08T04:17:48.813559Z","shell.execute_reply.started":"2023-06-08T04:17:48.802878Z","shell.execute_reply":"2023-06-08T04:17:48.812296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import re\n# define the number of training images\ndef count_data_items(filenames):\n    n = [int(re.compile(r\"-([0-9]*)\\.\").search(filename).group(1)) for filename in filenames]\n    return np.sum(n)\n\n\n# define the number of training images\nNUM_TRAIN_IMAGES = count_data_items(train)\n# define the number of validation images\nNUM_VAL_IMAGES = count_data_items(val)\n# define the number of test images\nNUM_TEST_IMAGES = count_data_items(test)\n\n\n#print the number of training, validation and test images\nprint('Dataset: {} training images, {} validation images, {} unlabeled test images'.format(NUM_TRAIN_IMAGES, NUM_VAL_IMAGES, NUM_TEST_IMAGES))","metadata":{"execution":{"iopub.status.busy":"2023-06-08T04:17:48.814958Z","iopub.execute_input":"2023-06-08T04:17:48.815555Z","iopub.status.idle":"2023-06-08T04:17:48.830543Z","shell.execute_reply.started":"2023-06-08T04:17:48.815523Z","shell.execute_reply":"2023-06-08T04:17:48.829293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.data.experimental import AUTOTUNE\nAUTO=AUTOTUNE\n\n# define the function to decode the image\ndef decode_image(image):\n    # decode the image\n    image = tf.image.decode_jpeg(image, channels=3)\n    # convert the image to the float32 dtype\n    image = tf.cast(image, tf.float32)\n    # resize the image\n    image = tf.image.resize(image, IMAGE_SIZE)\n    # return the image\n    return image\n\n# define the function to read the labeled TFRecord files\ndef read_labeled_tfrecord(example):\n    # define the data that we want to extract\n    LABELED_TFREC_FORMAT = {\n        # tf.string means bytestring\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        # shape [] means single element\n        \"class\": tf.io.FixedLenFeature([], tf.int64),\n    }\n    # extract the data from the TFRecord file\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    # decode the image\n    image = decode_image(example['image'])\n    # extract the label\n    label = tf.cast(example['class'], tf.int32)\n    # return the image and the label\n    return image, label # returns a dataset of (image, label) pairs\n\n# define the function to read the unlabeled TFRecord files\ndef read_unlabeled_tfrecord(example):\n    # define the data that we want to extract\n    UNLABELED_TFREC_FORMAT = {\n        # tf.string means bytestring\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        # shape [] means single element\n        \"id\": tf.io.FixedLenFeature([], tf.string),\n        # class is missing\n    }\n    # extract the data from the TFRecord file\n    example = tf.io.parse_single_example(example, UNLABELED_TFREC_FORMAT)\n    # decode the image\n    image = decode_image(example['image'])\n    # extract the id\n    idnum = example['id']\n    # return the image and the id\n    return image, idnum # returns a dataset of image(s)\n\n# define the function to load the dataset\ndef load_dataset(filenames, labeled=True, ordered=False):\n    # read from TFRecords. For optimal performance, reading from multiple files at once and disregarding data order. Order does not matter since we will be shuffling the data anyway\n    ignore_order = tf.data.Options()\n    # disable order, increase speed\n    ignore_order.experimental_deterministic = False\n    # automatically interleaves reads from multiple files\n    dataset = tf.data.TFRecordDataset(filenames, num_parallel_reads=AUTO)\n    # use data as soon as it streams in, rather than in its original order\n    dataset = dataset.with_options(ignore_order)\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 else read_unlabeled_tfrecord, 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\n\n# define the function to get the training dataset\ndef get_training_dataset():\n    # load the dataset\n    dataset = load_dataset(train, labeled=True, ordered=False)\n    # shuffle the dataset\n    dataset = dataset.shuffle(buffer_size=2048)\n    # repeat the dataset\n    dataset = dataset.repeat()\n    # batch the dataset\n    dataset = dataset.batch(BATCH_SIZE)\n    # prefetch the dataset\n    dataset = dataset.prefetch(AUTO)\n    # return the dataset\n    return dataset\n\n# define the function to get the validation dataset\ndef get_validation_dataset():\n    # load the dataset\n    dataset = load_dataset(val, labeled=True, ordered=False)\n    # batch the dataset\n    dataset = dataset.batch(BATCH_SIZE)\n    # cache the dataset\n    dataset = dataset.cache()\n    # prefetch the dataset\n    dataset = dataset.prefetch(AUTO)\n    # return the dataset\n    return dataset\n\n# define the function to get the test dataset\ndef get_test_dataset():\n    # load the dataset\n    dataset = load_dataset(test, labeled=False, ordered=True)\n    # batch the dataset\n    dataset = dataset.batch(BATCH_SIZE)\n    # prefetch the dataset\n    dataset = dataset.prefetch(AUTO)\n    # return the dataset\n    return dataset\n\n#get the training dataset\ntraining_dataset = get_training_dataset()\n#get the validation dataset\nvalidation_dataset = get_validation_dataset()\n#get the test dataset\ntest_dataset = get_test_dataset()","metadata":{"execution":{"iopub.status.busy":"2023-06-08T04:17:48.832545Z","iopub.execute_input":"2023-06-08T04:17:48.833049Z","iopub.status.idle":"2023-06-08T04:17:49.135913Z","shell.execute_reply.started":"2023-06-08T04:17:48.833017Z","shell.execute_reply":"2023-06-08T04:17:49.134895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(training_dataset)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T04:17:49.138583Z","iopub.execute_input":"2023-06-08T04:17:49.138879Z","iopub.status.idle":"2023-06-08T04:17:49.146001Z","shell.execute_reply.started":"2023-06-08T04:17:49.138855Z","shell.execute_reply":"2023-06-08T04:17:49.145008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_model():\n    model = tf.keras.Sequential([\n        tf.keras.applications.DenseNet201(\n            input_shape=(IMAGE_SIZE[0], IMAGE_SIZE[1], 3),\n            weights='imagenet',\n            include_top=False\n        ),\n        tf.keras.layers.GlobalAveragePooling2D(),\n        tf.keras.layers.Dense(len(CLASSES), activation='softmax')\n    ])\n    model.compile(\n        optimizer='adam',\n        loss = 'sparse_categorical_crossentropy',\n        metrics=['sparse_categorical_accuracy']\n    )\n    return model\n\n# create the model\nmodel = create_model()\n# print the model summary\nmodel.summary()\n\n# define the learning rate scheduler\nlr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(\n    monitor='val_sparse_categorical_accuracy',\n    patience=3,\n    verbose=1,\n    factor=0.5,\n    min_lr=1e-7\n)\n\n# define the early stopping\nearly_stopping = tf.keras.callbacks.EarlyStopping(\n    monitor='val_sparse_categorical_accuracy',\n    patience=10,\n    verbose=1,\n    restore_best_weights=True\n)\n\n# define the checkpoint\ncheckpoint = tf.keras.callbacks.ModelCheckpoint(\n    'model.h5',\n    monitor='val_sparse_categorical_accuracy',\n    verbose=1,\n    save_best_only=True,\n    save_weights_only=True\n)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T04:17:49.147672Z","iopub.execute_input":"2023-06-08T04:17:49.148836Z","iopub.status.idle":"2023-06-08T04:17:57.441245Z","shell.execute_reply.started":"2023-06-08T04:17:49.148803Z","shell.execute_reply":"2023-06-08T04:17:57.440295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# define steps per epoch\nSTEPS_PER_EPOCH = NUM_TRAIN_IMAGES // BATCH_SIZE\n# define validation steps\nVALIDATION_STEPS = NUM_VAL_IMAGES // BATCH_SIZE","metadata":{"execution":{"iopub.status.busy":"2023-06-08T04:17:57.445200Z","iopub.execute_input":"2023-06-08T04:17:57.446036Z","iopub.status.idle":"2023-06-08T04:17:57.451725Z","shell.execute_reply.started":"2023-06-08T04:17:57.445998Z","shell.execute_reply":"2023-06-08T04:17:57.450400Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# fit the model\nhistory = model.fit(\n    training_dataset,\n    epochs=EPOCHS,\n    callbacks=[lr_scheduler, early_stopping, checkpoint],\n    steps_per_epoch=STEPS_PER_EPOCH,\n    validation_data=validation_dataset\n)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T04:17:57.455222Z","iopub.execute_input":"2023-06-08T04:17:57.456320Z","iopub.status.idle":"2023-06-08T05:36:23.758311Z","shell.execute_reply.started":"2023-06-08T04:17:57.456285Z","shell.execute_reply":"2023-06-08T05:36:23.757105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plot the training and validation accuracy\nplt.plot(history.history['sparse_categorical_accuracy'])\nplt.plot(history.history['val_sparse_categorical_accuracy'])\nplt.title('Accuracy')\nplt.xlabel('epoch')\nplt.ylabel('accuracy')\nplt.legend(['train', 'validation'], loc='upper left')\nplt.show()\n\n# plot the training and validation loss\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Loss')\nplt.xlabel('epoch')\nplt.ylabel('loss')\nplt.legend(['train', 'validation'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-08T05:36:23.760071Z","iopub.execute_input":"2023-06-08T05:36:23.760524Z","iopub.status.idle":"2023-06-08T05:36:24.480947Z","shell.execute_reply.started":"2023-06-08T05:36:23.760490Z","shell.execute_reply":"2023-06-08T05:36:24.480064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load the model weights\nmodel.load_weights('model.h5')","metadata":{"execution":{"iopub.status.busy":"2023-06-08T05:36:24.482178Z","iopub.execute_input":"2023-06-08T05:36:24.483000Z","iopub.status.idle":"2023-06-08T05:36:25.355271Z","shell.execute_reply.started":"2023-06-08T05:36:24.482966Z","shell.execute_reply":"2023-06-08T05:36:25.354308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#find the evaluation metric\nloss, accuracy = model.evaluate(validation_dataset)\nprint('Test accuracy :', accuracy)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T05:36:25.357362Z","iopub.execute_input":"2023-06-08T05:36:25.357731Z","iopub.status.idle":"2023-06-08T05:36:37.584772Z","shell.execute_reply.started":"2023-06-08T05:36:25.357699Z","shell.execute_reply":"2023-06-08T05:36:37.583477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# get the test images and labels\ntest_images_ds = test_dataset.map(lambda image, idnum: image)\nprobabilities = model.predict(test_images_ds)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T05:36:37.586377Z","iopub.execute_input":"2023-06-08T05:36:37.587383Z","iopub.status.idle":"2023-06-08T05:37:21.765502Z","shell.execute_reply.started":"2023-06-08T05:36:37.587349Z","shell.execute_reply":"2023-06-08T05:37:21.764400Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = np.argmax(probabilities, axis=-1)\nprint(predictions)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T05:37:21.767142Z","iopub.execute_input":"2023-06-08T05:37:21.767524Z","iopub.status.idle":"2023-06-08T05:37:21.775761Z","shell.execute_reply.started":"2023-06-08T05:37:21.767490Z","shell.execute_reply":"2023-06-08T05:37:21.774678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Generate a csv file\nprint('Generating submission.csv file...')\ntest_ids_ds = test_dataset.map(lambda image, idnum: idnum).unbatch()\ntest_ids = next(iter(test_ids_ds.batch(NUM_TEST_IMAGES))).numpy().astype('U') # all in one batch\nnp.savetxt('submission.csv', np.rec.fromarrays([test_ids, predictions]), fmt=['%s', '%d'], delimiter=',', header='id,label', comments='')\n!head submission.csv\n","metadata":{"execution":{"iopub.status.busy":"2023-06-08T05:37:21.777281Z","iopub.execute_input":"2023-06-08T05:37:21.778522Z","iopub.status.idle":"2023-06-08T05:37:27.313585Z","shell.execute_reply.started":"2023-06-08T05:37:21.778489Z","shell.execute_reply":"2023-06-08T05:37:27.312243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cp submission.csv /kaggle/working/submission_copy.csv\n","metadata":{"execution":{"iopub.status.busy":"2023-06-08T05:37:27.317202Z","iopub.execute_input":"2023-06-08T05:37:27.318119Z","iopub.status.idle":"2023-06-08T05:37:28.400834Z","shell.execute_reply.started":"2023-06-08T05:37:27.318076Z","shell.execute_reply":"2023-06-08T05:37:28.399378Z"},"trusted":true},"execution_count":null,"outputs":[]}]}