"""
## Attempting the Cassava Leaf Disease Prediction with FastAI using Resnet34 Model.
"""
import pandas as pd
from fastai.vision.all import *
import fastai as fa
import os
from fastai import losses
fa.__version__
"""
## Loading the dataset
"""
path = Path('../input/cassava-leaf-disease-classification')
train_df = pd.read_csv(path/'train.csv')
train_df
"""
Removing the Mislabeled and Duplicates as per a discussion

"""
train_df = train_df[~train_df['image_id'].isin(['1562043567.jpg', '3551135685.jpg', '2252529694.jpg'])]
"""
## Data Labeling 
"""
def get_x(r):
    return path/'train_images'/r['image_id']

def get_y(r):
    return r['label']
"""
## Data Generators with Augmentations 
"""
def get_data(size=224,bs=128,data_df=train_df):
    dblock = DataBlock(blocks=(ImageBlock, CategoryBlock),
                       splitter=RandomSplitter(seed=42),
                       get_x=get_x, 
                       get_y=get_y,
                       item_tfms = RandomResizedCrop(460),
                       batch_tfms = [*aug_transforms(size=size),Normalize.from_stats(*imagenet_stats)]
                      )
    return dblock.dataloaders(data_df,bs=bs)
"""
## View of a batch of images 
"""
dls = get_data()
dls.show_batch()
"""
## Moving resnet34 pretrained model to checkpoints 
"""
if not os.path.exists('/root/.cache/torch/hub/checkpoints/'):
        os.makedirs('/root/.cache/torch/hub/checkpoints/')
!cp '../input/resnet34/resnet34.pth' '/root/.cache/torch/hub/checkpoints/resnet34-333f7ec4.pth'
"""
## Using LabelSmoothingCE & MixUp Augmentations in training loop
"""
loss_func = losses.LabelSmoothingCrossEntropy()
cbs = MixUp
learn = cnn_learner(dls, resnet34, loss_func=loss_func, metrics=accuracy, cbs=cbs).to_native_fp16()
"""
## Smart LRFind to predict perfect LR to start
"""
learn.lr_find()
"""
## Fine Tuning with EarlyStopping
"""
learn.fine_tune(50, freeze_epochs=8, cbs=EarlyStoppingCallback(monitor='valid_loss', min_delta=0.003, patience=3))
learn = learn.to_native_fp32()
submission_df = pd.read_csv(path/'sample_submission.csv')
len(submission_df)
"""
## Remapping the labels for test and Making Predictions
"""
test_data_path = submission_df['image_id'].apply(lambda x: path/'test_images'/x)
tst_dl = learn.dls.test_dl(test_data_path)
predictions = learn.tta(dl = tst_dl, n=10)

submission_df['label'] = np.argmax(predictions[0],axis=1)
submission_df
"""
## Preparing Submission
"""
submission_df.to_csv('submission.csv',index=False)