{"cells":[{"metadata":{},"cell_type":"markdown","source":"# PREPROCESSING","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# SET UP\n**Importing necessary modules**","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np, pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom kaggle_datasets import KaggleDatasets\nimport os\nimport re\nfrom tensorflow import keras\nimport tensorflow_datasets as tfds\nfrom sklearn.metrics import classification_report, confusion_matrix","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tf.compat.v1.disable_eager_execution()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tf.executing_eagerly()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# XLA GPU\nSET STRATEGY FOR TF","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"strategy = tf.distribute.get_strategy()\ntf.config.optimizer.set_jit(True)\n    \nprint(strategy)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# FOLDERS AND CLASS LABELS","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"CLASSES = ['pink primrose',    'hard-leaved pocket orchid', 'canterbury bells', 'sweet pea',     'wild geranium',     'tiger lily',           'moon orchid',              'bird of paradise', 'monkshood',        'globe thistle',         # 00 - 09\n           'snapdragon',       \"colt's foot\",               'king protea',      'spear thistle', 'yellow iris',       'globe-flower',         'purple coneflower',        'peruvian lily',    'balloon flower',   'giant white arum lily', # 10 - 19\n           'fire lily',        'pincushion flower',         'fritillary',       'red ginger',    'grape hyacinth',    'corn poppy',           'prince of wales feathers', 'stemless gentian', 'artichoke',        'sweet william',         # 20 - 29\n           'carnation',        'garden phlox',              'love in the mist', 'cosmos',        'alpine sea holly',  'ruby-lipped cattleya', 'cape flower',              'great masterwort', 'siam tulip',       'lenten rose',           # 30 - 39\n           'barberton daisy',  'daffodil',                  'sword lily',       'poinsettia',    'bolero deep blue',  'wallflower',           'marigold',                 'buttercup',        'daisy',            'common dandelion',      # 40 - 49\n           'petunia',          'wild pansy',                'primula',          'sunflower',     'lilac hibiscus',    'bishop of llandaff',   'gaura',                    'geranium',         'orange dahlia',    'pink-yellow dahlia',    # 50 - 59\n           'cautleya spicata', 'japanese anemone',          'black-eyed susan', 'silverbush',    'californian poppy', 'osteospermum',         'spring crocus',            'iris',             'windflower',       'tree poppy',            # 60 - 69\n           'gazania',          'azalea',                    'water lily',       'rose',          'thorn apple',       'morning glory',        'passion flower',           'lotus',            'toad lily',        'anthurium',             # 70 - 79\n           'frangipani',       'clematis',                  'hibiscus',         'columbine',     'desert-rose',       'tree mallow',          'magnolia',                 'cyclamen ',        'watercress',       'canna lily',            # 80 - 89\n           'hippeastrum ',     'bee balm',                  'pink quill',       'foxglove',      'bougainvillea',     'camellia',             'mallow',                   'mexican petunia',  'bromelia',         'blanket flower',        # 90 - 99\n           'trumpet creeper',  'blackberry lily',           'common tulip',     'wild rose']                                                                                                                                             ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMAGE_SIZES = [(192, 192), (224, 224), (331, 331), (512, 512)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"IMAGE_SIZE = IMAGE_SIZES[1]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"stem = \"/kaggle/input/tpu-getting-started/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"FOLDER_PATHS = [stem + str(item) for item in os.listdir(\"/kaggle/input/tpu-getting-started\") if \"contains\" not in str(item)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"for i, p in enumerate(FOLDER_PATHS):\n    if \"224\" in str(p):\n        PATH = FOLDER_PATHS[i]","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Return all the files so they can be used in the dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def return_files(f):\n    return [f + \"/\" + item for item in os.listdir(f)]\n\ntrain_files = []\ntest_files = []\nval_files = []\n\n#if \"sample\" not in str(p):\nfor p in FOLDER_PATHS:\n    if \"sample\" not in str(p):\n        train_folder = p + \"/train\"\n        test_folder = p + \"/test\"\n        val_folder = p + \"/val\"\n\n        print(train_folder)\n        for f in return_files(train_folder):\n            train_files.append(f)\n        for f in return_files(test_folder):\n            test_files.append(f)\n        for f in return_files(val_folder):\n            val_files.append(f)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_files","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Define Image Reading Dictionaries**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"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}\nUNLABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string),\n        \"id\": tf.io.FixedLenFeature([], tf.string),\n}","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# DATA PROCESSING","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Image Decoding and Reading Functions","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def decode_image(image_data):\n    image = tf.image.decode_jpeg(image_data, channels=3)\n    image = tf.image.resize(image,[224,224],method='nearest', preserve_aspect_ratio=True,)\n    image = tf.cast(image, tf.float32) / 255.0\n    #image = tf.image.resize(image,[224,224],method='nearest', preserve_aspect_ratio=True,)\n    #image = tf.reshape(image, [*IMAGE_SIZE, 3])\n    return image\n\ndef read_labeled_record(example_proto):\n    ex = tf.io.parse_single_example(example_proto, LABELED_TFREC_FORMAT)\n    img = decode_image(ex[\"image\"])\n    label = tf.cast(ex[\"class\"], tf.int64)\n    return img, label\n\ndef read_unlabeled_record(example_proto):\n    ex = tf.io.parse_single_example(example_proto, UNLABELED_TFREC_FORMAT)\n    img = decode_image(ex)\n    label = tf.cast(ex[\"class\"], tf.int64)\n    return img, label","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Data augmentation function","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def data_augment(image, label):\n    #image = tf.image.resize(image,(224,224))\n    image = tf.image.random_flip_left_right(image, seed=None)\n    image = tf.image.random_flip_up_down(image, seed=None)\n    image = tf.image.random_saturation(image, lower=0, upper=2, seed=None)\n#     image = tf.image.random_contrast(image, lower=.8, upper=2, seed=seed)\n#     image = tf.image.random_brightness(image, max_delta=.2, seed=seed)\n    image = tf.image.random_crop(image, size=[int(224), int(224), 3], seed=None)\n\n    return image, label","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Counts number of data items in files","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def 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)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Loads dataset with tfds","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_dataset(filenames, augment):\n    ignore_order = tf.data.Options()\n\n    dataset = tf.data.TFRecordDataset(filenames)\n    dataset = dataset.with_options(ignore_order)\n    dataset = dataset.map(read_labeled_record)\n    #dataset = dataset.map(reshape)\n    if augment:\n        dataset = dataset.map(data_augment, num_parallel_calls=AUTO)\n    \n    return dataset","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN_LEN = count_data_items(train_files)\nVAL_LEN = count_data_items(val_files)\nprint(\"There are \" + str(TRAIN_LEN) + \" training pictures.\")\nprint(\"There are \" + str(VAL_LEN) + \" validation pictures.\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# TRAINING","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Define Batch Fetching function","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def BatchGen(files, augment):\n    data = load_dataset(files, augment)\n    iterator = tf.compat.v1.data.make_one_shot_iterator(data)\n    next_element = iterator.get_next()\n    \n    #tf.compat.v1.disable_eager_execution()\n    train_x = []\n    train_y = []\n    \n    with tf.compat.v1.Session() as s:                \n        try:\n            while True:\n                data_record = s.run(next_element)\n                train_x.append(data_record[0])\n                train_y.append(data_record[1])\n        except:\n            pass\n        \n    return train_x, train_y","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Some more constants","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#CLASS_WEIGHT = \nEPOCHS=5\nAUTO = tf.data.experimental.AUTOTUNE\nLEARNING_RATE = 0.000051","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Defining the Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, LearningRateScheduler","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras import layers","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#base_model = keras.applications.xception.Xception(weights=\"imagenet\", include_top=False)\ndef get_model():\n    with strategy.scope():\n        global model\n        base_model = tf.keras.applications.DenseNet201(\n            include_top=False,\n            weights=\"imagenet\",\n            input_shape=[None, None, 3],\n        )\n\n        base_model.trainable = False\n\n        set_trainable = False\n\n            # Un-freeze the last 256 layers\n        for layer in base_model.layers:\n            if layer == base_model.layers[-2]: \n                set_trainable = True\n            if set_trainable:\n                layer.trainable = True\n            else:\n                layer.trainable = False\n\n        N_CLASSES = len(CLASSES)\n\n        model = tf.keras.Sequential([\n            base_model,\n            layers.GlobalAveragePooling2D(),\n            layers.Dropout(0.075),\n            layers.Dense(N_CLASSES*10, activation='relu'),\n            layers.Dropout(0.075),\n            layers.Dense(N_CLASSES, activation='softmax')\n        ])\n        \n        return model\nmodel = get_model()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Compiling the model and initializing callbacks","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer=tf.keras.optimizers.Adam(lr=LEARNING_RATE), loss='sparse_categorical_crossentropy', run_eagerly=False, metrics=[\"sparse_categorical_accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tensorboard_callback = tf.keras.callbacks.EarlyStopping(\n    monitor=\"sparse_categorical_accuracy\",\n    min_delta=0,\n    patience=2,\n    verbose=1,\n    mode=\"auto\",\n    baseline=None,\n    restore_best_weights=False,\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def scheduler(epoch, lr):\n    if epoch < 10:\n        return LEARNING_RATE*1.1\n    elif epoch < 20:\n        return lr * 0.9\n    else:\n        return lr * 0.8\n\nlr_scheduler = tf.keras.callbacks.LearningRateScheduler(scheduler, verbose=0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Training Function","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#To run the 64 files multiple times\nfor t in range(10):\n    print(\"Iteration: \", t)\n    for i, file in enumerate(train_files):\n        train_x, train_y = BatchGen(file, augment=True)\n        print(\"File Number: \", i, \"Number of Records: \", len(train_x))\n        train_x, train_y = np.asarray(train_x), np.asarray(train_y)\n                \n        model.fit(train_x, train_y, epochs=25, \n                  batch_size=24, \n                  verbose=1, shuffle=False,\n              callbacks=[tensorboard_callback, lr_scheduler])\n\nprint(\"Model fit completed!!\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Train the model","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# VALIDATION","execution_count":null},{"metadata":{"trusted":true},"cell_type":"markdown","source":"Validation function that predicts data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"pred_arr = []\nlabel_arr = []\nfor file in val_files:\n    val_x, val_y = BatchGen(file, False)\n    val_x = np.asarray(val_x)\n    \n    pred = model.predict(val_x)\n    pred = np.argmax(pred, axis=-1)\n    \n    for p in pred:\n        pred_arr.append(p)\n    for label in val_y:\n        label_arr.append(label)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Accuracy Analysis","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix, precision_score","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(pred_arr))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(label_arr))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"confusion_matrix(label_arr, pred_arr)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"arr = classification_report(label_arr, pred_arr, target_names=CLASSES)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(arr)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}