{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Imports\nImport necessary tensorflow and keras functions and tensorflow data api functions."},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.data import Dataset\nfrom tensorflow.data.experimental import AUTOTUNE\nfrom tensorflow import image, cast, float32\nfrom tensorflow.io import decode_image, read_file\nfrom tensorflow.keras.applications.efficientnet import preprocess_input\nfrom tensorflow.keras import Model\nfrom tensorflow.keras.layers import Conv2D,Input,Dense,GlobalAveragePooling2D,Dropout,BatchNormalization\nfrom tensorflow.keras.applications import EfficientNetB3\nfrom tensorflow.keras.optimizers import RMSprop\nfrom tensorflow.keras.callbacks import LearningRateScheduler,ModelCheckpoint,TensorBoard\nfrom tensorflow.keras.losses import SparseCategoricalCrossentropy\nfrom tensorflow.keras.models import load_model\nfrom tensorflow import numpy_function\nfrom tensorflow.keras.preprocessing.image import load_img,img_to_array\n\nfrom sklearn.model_selection import StratifiedKFold\n\nimport albumentations as A\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport pandas as pd\nimport numpy as np\nimport time\nimport os\nimport glob\n\nos.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'\n\n#Global Values\nBATCH_SIZE = 64\nROW = 300\nCOL = 300\n\ntrain_csv_loc = '../input/cassava-leaf-disease-classification/train.csv'\ntrain_location = '../input/cassava-leaf-disease-classification/train_images/'\ntest_location = '../input/cassava-leaf-disease-classification/test_images'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Import Data and Augmentations with pre-processing"},{"metadata":{"trusted":false},"cell_type":"code","source":"def augmentations(file):\n\n    file = read_file(file)\n    \n    file = image.decode_jpeg(file, channels=3)\n\n    transform = A.Compose([\n        A.RandomRotate90(),\n        A.Flip(),\n        A.Transpose(),\n        A.OneOf([\n            A.IAAAdditiveGaussianNoise(),\n            A.GaussNoise(),\n        ], p=0.2),\n        A.OneOf([\n            A.MotionBlur(p=.2),\n            A.MedianBlur(blur_limit=3, p=0.1),\n            A.Blur(blur_limit=3, p=0.1),\n        ], p=0.2),\n        A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.2, rotate_limit=45, p=0.2),\n        A.OneOf([\n            A.OpticalDistortion(p=0.3),\n            A.GridDistortion(p=.1),\n            A.IAAPiecewiseAffine(p=0.3),\n        ], p=0.2),\n        A.OneOf([\n            A.CLAHE(clip_limit=2),\n            A.IAASharpen(),\n            A.IAAEmboss(),\n            A.RandomBrightnessContrast(),\n            A.HueSaturationValue(hue_shift_limit=30),\n            A.RandomFog(p=.3)            \n        ], p=0.7),\n        A.HueSaturationValue(p=0.3),\n        A.OneOf([\n            A.CoarseDropout(max_holes=16, max_height=16, max_width=16),\n            A.Cutout(num_holes=16, max_h_size=16, max_w_size=16),\n            A.ElasticTransform(alpha=1, sigma=25)            \n        ], p=0.4),\n    ])\n\n    file = transform(image=file.numpy())['image']\n    \n    file = preprocess_input(file)\n\n    file = image.resize(file, [ROW, COL])\n\n    return file","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"def fetch_image_without_aug(filename , label):\n    \n    image_file = read_file(filename)\n\n    image_file = image.decode_jpeg(image_file, channels=3)\n\n    image_file = preprocess_input(image_file)\n\n    image_file = image.resize(image_file, [ROW, COL])\n\n    return image_file, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"def fetch_image_with_aug(filename , label):\n\n    aug_img = numpy_function(func=augmentations, inp=[filename], Tout=float32)\n\n    return aug_img, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"def getDatasetFromDataframe(train_files, train_labels, val_files, val_labels):\n\n    train_ds = Dataset.from_tensor_slices((train_files, train_labels))\n    train_ds = train_ds.shuffle(len(train_files))\n    train_ds = train_ds.map(fetch_image_with_aug , num_parallel_calls=16)\n    train_ds = train_ds.batch(BATCH_SIZE)\n    train_ds = train_ds.prefetch(AUTOTUNE)\n\n    val_ds = Dataset.from_tensor_slices((val_files, val_labels))\n    val_ds = val_ds.shuffle(len(val_files))\n    val_ds = val_ds.map(fetch_image_without_aug , num_parallel_calls=16)\n    val_ds = val_ds.batch(BATCH_SIZE)\n    val_ds = val_ds.prefetch(AUTOTUNE)\n    \n    return train_ds , val_ds","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Callbacks"},{"metadata":{"trusted":false},"cell_type":"code","source":"def scheduler(epoch, lr):\n    if epoch < 8:\n        return lr\n    else:\n        return lr * np.exp(-0.05)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"def create_callbacks(Folder_name):\n    if not os.path.exists(os.path.join(\"Weights\" , Folder_name)):\n        os.mkdir(os.path.join(\"Weights\", Folder_name))\n\n    if not os.path.exists(os.path.join(\"Weights\", \"logs\" , Folder_name)):\n        os.mkdir(os.path.join(\"Weights\", \"logs\", Folder_name))\n\n    lr_scheduler = LearningRateScheduler(scheduler)\n\n    weight_save = ModelCheckpoint(os.path.join(\"Weights\", Folder_name),\n        monitor=\"val_accuracy\", verbose=1, save_best_only=True, save_weights_only=False)\n\n    weight_save_only = ModelCheckpoint(os.path.join(\"Weights\", Folder_name + \".h5\"),\n        monitor=\"val_accuracy\", verbose=0, save_best_only=True, save_weights_only=True)\n\n    tensorboard = TensorBoard(os.path.join(\n        \"Weights\", \"logs\", Folder_name), histogram_freq=1)\n\n    callbacks = [lr_scheduler, weight_save, tensorboard, weight_save_only]\n\n    return callbacks,histories\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Build The Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_model(training = True, weights = \"imagenet\"):\n    base_model = EfficientNetB3(weights=weights , include_top=False , input_shape=(ROW,COL,3))\n\n    x = Input(shape = (ROW,COL,3))\n    out_1 = base_model(x,training = training)\n    out_1 = GlobalAveragePooling2D(name = 'encoding')(out_1)\n    out_1 = Dropout(0.5)(out_1)\n    output = Dense(5 , activation=\"softmax\")(out_1)\n\n    final_model = Model(inputs = x , outputs = output)\n\n    final_model.summary()\n\n    return final_model","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Final Training"},{"metadata":{"trusted":false},"cell_type":"code","source":"train_csv = pd.read_csv(train_csv_loc)\ntrain_csv['image_id'] = train_csv['image_id'].map(lambda x: train_location+x)\n\n#Folder_name = \"EfficientNetB0_\" + str(time.time())[-5:] + \"_Fold_\"\nFolder_name = \"Exp_\"\n\ncreate_k_folds = StratifiedKFold(n_splits=5)\n\nfold_number = 1\n\nfor train_index, test_index in create_k_folds.split(train_csv['image_id'] , train_csv['label']):\n\n    print(\"Fold Number {} is starting it's training\".format(fold_number))\n    print(\"Creating Callbacks...\")\n    Folder_name = Folder_name + str(fold_number)\n    callbacks, histories = create_callbacks(Folder_name)\n    \n    print(\"Importing Datasets...\")\n    X_train, X_test = train_csv['image_id'].loc[train_index], train_csv['image_id'].loc[test_index]\n    y_train, y_test = train_csv['label'].loc[train_index], train_csv['label'].loc[test_index]\n\n    train_ds, val_ds = getDatasetFromDataframe(X_train, y_train, X_test, y_test)\n\n    final_model = create_model()\n\n    final_model.compile(optimizer=RMSprop(learning_rate=1e-4),\n                    loss=SparseCategoricalCrossentropy(), metrics=['accuracy'])\n\n    try:\n        print(\"Starting training...\")\n        hist = final_model.fit(train_ds, epochs=15,\n                            validation_data=val_ds, callbacks=callbacks, workers=16)\n    except:\n#         histories.sendCrash()\n        print(\"Error...\")\n\n    fold_number += 1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Inference"},{"metadata":{"trusted":true},"cell_type":"code","source":"checkpoints = glob.glob(os.path.join('../input/efficient-net-weights/Weights2' , 'Exp2_*.h5'))\n\nModels = []\nfor checkpoint in checkpoints:\n    new_model = create_model(training = False, weights = None)\n    new_model.load_weights(checkpoint)\n    Models.append(new_model)\n\nprint('Models loaded...')\n\nimages = os.listdir(test_location)\nresults = []\n\nfor single in images:\n\n    image = load_img(test_location+'/'+single , target_size=(ROW,COL))\n    image = img_to_array(image)\n    image = preprocess_input(image)\n    batch = np.array([image])\n    res = []\n    for model in Models:\n        res.append(model.predict(batch))\n    res = np.mean(res , 0)\n    results.append({\"image_id\" : single , \"label\" : np.argmax(res)})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.DataFrame(results)\nsubmission.to_csv('submission.csv' , index = False)","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}