{"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":"import pandas as pd\nimport matplotlib.pyplot as plt\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn.model_selection import train_test_split\n%matplotlib inline\nimport albumentations as A\nimport os\nimport numpy as np\nimport pandas as pd\n\nimport albumentations as A\nimport cv2\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torch.optim as optim\n\nfrom tqdm.notebook import tqdm\nfrom torch.utils.data import Dataset, DataLoader\nfrom albumentations.pytorch import ToTensorV2\n\nfrom sklearn.metrics import roc_auc_score\nfrom sklearn.model_selection import KFold, StratifiedKFold\n\nimport plotly.express as px\nimport plotly.graph_objects as go\nfrom plotly.subplots import make_subplots\n\nimport warnings  \nwarnings.filterwarnings('ignore')\n\n__print__ = print\n\ndef print(string):\n    os.system(f'echo \\\"{string}\\\"')\n    __print__(string)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS=20\nSAMPLE_LEN=100\nIMAGE_PATH=\"../input/plant-pathology-2021-fgvc8/train_images\"\nTRAIN_PATH=\"../input/plant-pathology-2021-fgvc8/train.csv\"\nSUB_PATH=\"../input/plant-pathology-2021-fgvc8/sample_submission.csv\"\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub=pd.read_csv(SUB_PATH)\ntrain_data=pd.read_csv(TRAIN_PATH)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.labels.value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.groupby(\"labels\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"a=train_data['labels'].unique()\nb=train_data['labels'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DATASET","metadata":{}},{"cell_type":"code","source":"DIR_INPUT = '../input/plant-pathology-2021-fgvc8'\n\nSEED = 42\nN_FOLDS = 5\nN_EPOCHS = 10\nBATCH_SIZE = 64\nSIZE = 224","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"encoded=dict(zip(list(train_data['labels'].value_counts().keys()),range(12)))\ntrain_data=train_data.replace({'labels':encoded})","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"encoded","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train,valid=train_test_split(train_data,stratify=train_data.labels,test_size=0.30)\n#valid,_=train_test_split(valid,stratify=valid.labels,test_size=.95)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Percentage of each labels in the validation set","metadata":{}},{"cell_type":"code","source":"((valid.labels.value_counts())/valid.shape[0])*100","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Percentage of each labels in the train set","metadata":{}},{"cell_type":"code","source":"((train.labels.value_counts())/train.shape[0])*100","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.loc[5,'labels']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset","metadata":{}},{"cell_type":"code","source":"class PlantDataset(Dataset):\n    def __init__(self,df,transforms=None):\n        self.image_id=df.image.values\n        self.labels=df.labels.values\n        self.transforms=transforms\n        \n    def __len__(self):\n        return len(self.image_id)\n    \n    def __getitem__(self,idx):\n        path=DIR_INPUT+'/train_images'+'/'+self.image_id[idx]\n        image=cv2.imread(path,cv2.IMREAD_COLOR)\n        image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)\n        labels=self.labels[idx]\n        \n        if self.transforms:\n            image=self.transforms(image=image)['image']\n            \n        return image,labels","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PlantTestDataset(Dataset):\n    def __init__(self,df,transforms=None):\n        self.image_id=df.image.values\n        self.tranforms=transforms\n        \n    def __len__(self):\n        return len(self.image_id)\n    def __getitem__(self,idx):\n        path=DIR_INPUT+'/train_images'+'/'+self.image_id[idx]\n        image=cv2.imread(path,cv2.IMREAD_COLOR)\n        image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)\n        if self.transforms:\n            image=self.transforms(image=image)['image']\n            \n        return image    \n        ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"class Plantmodel(nn.Module):\n    \n    def __init__(self,num_classes=12):\n        super().__init__()\n        self.model=torchvision.models.resnet18(pretrained=True)\n        in_features=self.model.fc.in_features\n        self.model.fc=nn.Linear(in_features,num_classes)\n    def forward(self,x):\n        batch_size, C, H, W = x.shape\n        x=self.model(x)\n       # x=self.backbone.maxpool(x)\n        \n       # x=self.backbone.layer1(x)\n       # x=self.backbone.layer2(x)\n       # x=self.backbone.layer3(x)\n       # x=self.backbone.layer4(x)\n        \n       # x=F.adaptive_avg_pool2d(x,1).reshape(batch_size,-1)\n       # x=F.dropout(x,0.25,self.training)\n       # x=self.classifier(x)\n        return x\n        ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transforms_train = A.Compose([\n    A.RandomResizedCrop(height=SIZE, width=SIZE, p=1.0),\n    A.Flip(),\n    A.ShiftScaleRotate(rotate_limit=1.0, p=0.8),\n\n    # Pixels\n    A.OneOf([\n        A.IAAEmboss(p=1.0),\n        A.IAASharpen(p=1.0),\n        A.Blur(p=1.0),\n    ], p=0.5),\n\n    # Affine\n    A.OneOf([\n        A.ElasticTransform(p=1.0),\n        A.IAAPiecewiseAffine(p=1.0)\n    ], p=0.5),\n\n    A.Normalize(p=1.0),\n    ToTensorV2(p=1.0),\n])\n\ntransforms_valid = A.Compose([\n    A.Resize(height=SIZE, width=SIZE, p=1.0),\n    A.Normalize(p=1.0),\n    ToTensorV2(p=1.0),\n])\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset=PlantDataset(train,transforms_train)\ntrain_loader=DataLoader(train_dataset,batch_size=64,num_workers=0,shuffle=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_dataset=PlantDataset(valid,transforms_valid)\nvalid_loader=DataLoader(valid_dataset,batch_size=64,num_workers=0,shuffle=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"For each epoch we go through the following steps:\n  model.train()\n  iterate through each batch\n \n     load image and labels\n     load image and labels to device\n     pass image through model and get output\n     calculate loss\n     calculate gradient through loss.backward()\n     optimizer.step()\n     zero the optimizer\n \n","metadata":{}},{"cell_type":"code","source":"device = torch.device(\"cuda\")\nmodel=Plantmodel()\nmodel.to(device)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x=torch.tensor([[1,2,3,5],[1,2,3,5],[1,2,3,5]])\ny=torch.tensor([1,2,3])\nb=torch.argmax(x,dim=1)\ntorch.mean((y==b).type(torch.FloatTensor))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ncriterion=nn.CrossEntropyLoss()\noptimizer=torch.optim.Adam(model.parameters(),lr=5e-5)\nmin_acc=0\nfor epoch in range(10):\n    print(f\"Epoch{epoch}\")\n    model.train()\n    train_loss=0\n    loop=tqdm(enumerate(train_loader),total=len(train_loader),leave=False)\n    for step,batch in loop :\n        optimizer.zero_grad()\n        image=batch[0]\n        labels=batch[1]\n        \n        image=image.to(device,dtype=torch.float)\n        labels=labels.to(device,dtype=torch.long)\n        \n        output=model(image)\n        pred=torch.exp(output)\n        pred=torch.argmax(output,dim=1)\n        acc=torch.mean(((labels==pred).type(torch.FloatTensor)))\n       # print(f\" Training Accuracy {acc*100}%\")\n        loss=criterion(output,labels)\n        loop.set_postfix(loss=loss.item(),accuracy=acc)\n       \n        \n       \n        loss.backward()\n        optimizer.step()\n    model.eval()\n    for data,labels in valid_loader:\n        image,labels=data,labels\n        image=image.to(device,dtype=torch.float)\n        labels=labels.to(device,dtype=torch.long)\n        \n        output=model(image)\n        pred=torch.exp(output)\n        pred=torch.argmax(output,dim=1)\n        acc=torch.mean(((labels==pred).type(torch.FloatTensor)))\n        loss=criterion(output,labels)\n        valid_loss=loss.item()*data.size(0)\n        print(f\" Validation Accuracy {acc*100}%\")\n        \n        if min_acc< acc:\n            min_acc=acc\n            print(f\"Validation accuracy increased {min_acc*100:.2f} --> {acc*100:.2f} \\t Saving Yhe Model\")\n            torch.save(model.state_dict(),'saved_model.pth')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.save(model.state_dict(),'Plant_2021_epoch10.pth')","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}