{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"###### First things first - Go to Accelerator and turn on GPU\n\n###### Importing necessary files/ modules \nimport random, re\nimport numpy as np\nimport tensorflow as tf\nfrom kaggle_datasets import KaggleDatasets\nprint('Tensorflow version ' + tf.__version__)\nimport os","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"###### Seed Everything\nSEED = 42\nrandom.seed(SEED)\nnp.random.seed(SEED)\ntf.random.set_seed(SEED)\n\n###### Config\nDIM = 128\nIMAGE_SIZE = [DIM, DIM]\nEPOCHS = 5\nBATCH_SIZE = 64","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"####### In training we have internet enabled so we can use get_gcs_path. In inference notebook we cannot use internet so it will be done differently\nGCS_DS_PATH = KaggleDatasets().get_gcs_path('cassava-leaf-disease-classification')\n\nTRAINING_FILENAMES =  tf.io.gfile.glob(GCS_DS_PATH + '/train_tfrecords/*.tfrec')\nTEST_FILENAMES = tf.io.gfile.glob(GCS_DS_PATH + '/test_tfrecords/*.tfrec') \nprint(TRAINING_FILENAMES)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"####### Necessary functions for image augmentation and reading tf records\ndef 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.image.resize(image, [DIM, DIM])\n    image = tf.reshape(image, [DIM, DIM, 3])\n    return image\n\ndef read_labeled_tfrecord(example):\n    LABELED_TFREC_FORMAT = {\n        \"image\": tf.io.FixedLenFeature([], tf.string), \n        \"target\": tf.io.FixedLenFeature([], tf.int64), \n    }\n    example = tf.io.parse_single_example(example, LABELED_TFREC_FORMAT)\n    image = decode_image(example['image'])\n    label = tf.cast(example['target'], tf.int32)\n    return image, label \n\n\ndef load_dataset(filenames, labeled = True, ordered = False):\n    ignore_order = tf.data.Options()\n    if not ordered:\n        ignore_order.experimental_deterministic = False \n        \n    dataset = tf.data.TFRecordDataset(filenames)\n    dataset = dataset.with_options(ignore_order) \n    dataset = dataset.map(read_labeled_tfrecord ) \n    return dataset\n\n\ndef data_augment(image, label):\n    \n    image = tf.image.random_flip_left_right(image)\n    image = tf.image.random_flip_up_down(image)\n    switch = tf.random.uniform([], 0., 1., dtype=tf.float32)\n    if  switch >= 0.66 :\n        crop_size = int(DIM/2)\n        image = tf.image.random_crop(image, size=[crop_size, crop_size, 3])\n\n    else :\n        image = tf.image.random_saturation(image, 0.9, 1.1)\n        image = tf.image.random_contrast(image, 0.9, 1.1)\n        image = tf.image.random_brightness(image, 0.1)\n\n    image = tf.image.resize(image, [DIM, DIM])\n    image = tf.reshape(image, [DIM, DIM, 3])       \n    return image, label\n\n\ndef get_training_dataset(dataset, do_aug=True):\n    \n    dataset = dataset.repeat() \n    dataset = dataset.map(data_augment)\n    dataset = dataset.map(onehot)\n\n    dataset = dataset.shuffle(2048)\n    dataset = dataset.batch(BATCH_SIZE)\n    return dataset\n\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\nNUM_TRAINING_IMAGES = int( count_data_items(TRAINING_FILENAMES) )\nSTEPS_PER_EPOCH = NUM_TRAINING_IMAGES // BATCH_SIZE\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"####  We used categorical cross entropy and we have 5 type of outputs. So 2 will be represented as 0 0 1 0 0\ndef onehot(image,label):\n    CLASSES = 5\n    return image,tf.one_hot(label,CLASSES)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"######### Training the ResNet50 model and saving the trained model to be used in Inference. \n######### Either download the saved model or save the version using quick save and under advanced options make sure always save output is checked.\n\nloss = tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.05)\n\nhistories = []\nmodels = []\ndef train():\n   \n    train_dataset = load_dataset(TRAINING_FILENAMES, labeled = True)\n    rnet =  tf.keras.applications.ResNet50(   \n                input_shape=(IMAGE_SIZE[0], IMAGE_SIZE[1], 3),\n                weights='imagenet',  \n                include_top=False \n            )\n    rnet.trainable = True\n    model = tf.keras.Sequential([\n        rnet,\n        tf.keras.layers.GlobalAveragePooling2D(),\n        tf.keras.layers.Dense(5, activation='softmax',dtype='float32')\n    ])\n    model.compile(\n        optimizer='adam',\n        loss = loss ,\n        metrics=['categorical_accuracy'] )\n    model.fit(\n                get_training_dataset(train_dataset), \n                steps_per_epoch = STEPS_PER_EPOCH,\n                epochs = EPOCHS,\n                verbose=1 )\n    return model                   \n    \nmodel = train()\nmodel.save('model_Resnet50.h5')\n","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}