{"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 numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport os","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:39.094741Z","iopub.execute_input":"2022-01-02T22:23:39.095603Z","iopub.status.idle":"2022-01-02T22:23:39.122621Z","shell.execute_reply.started":"2022-01-02T22:23:39.095485Z","shell.execute_reply":"2022-01-02T22:23:39.121875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_path='/kaggle/input/cassava-leaf-disease-classification/'\ntrain=pd.read_csv(input_path+\"train.csv\")\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:39.124147Z","iopub.execute_input":"2022-01-02T22:23:39.124497Z","iopub.status.idle":"2022-01-02T22:23:39.165398Z","shell.execute_reply.started":"2022-01-02T22:23:39.124451Z","shell.execute_reply":"2022-01-02T22:23:39.164750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[\"label\"].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:39.166705Z","iopub.execute_input":"2022-01-02T22:23:39.166983Z","iopub.status.idle":"2022-01-02T22:23:39.178539Z","shell.execute_reply.started":"2022-01-02T22:23:39.166949Z","shell.execute_reply":"2022-01-02T22:23:39.177899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain, val, _, _ =train_test_split(train, train['label'],test_size=0.1,stratify=train['label'])","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:39.180734Z","iopub.execute_input":"2022-01-02T22:23:39.181282Z","iopub.status.idle":"2022-01-02T22:23:40.013723Z","shell.execute_reply.started":"2022-01-02T22:23:39.181245Z","shell.execute_reply":"2022-01-02T22:23:40.012901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torchvision\nimport cv2\nimport time\nimport copy\nfrom PIL import Image\nfrom tqdm import tqdm\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision import transforms as T\nfrom torchvision.transforms import functional as TF","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:40.015143Z","iopub.execute_input":"2022-01-02T22:23:40.015415Z","iopub.status.idle":"2022-01-02T22:23:41.898899Z","shell.execute_reply.started":"2022-01-02T22:23:40.015379Z","shell.execute_reply":"2022-01-02T22:23:41.898001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CassavaDataset(Dataset):\n    def __init__(self, root_dir, csv):\n        self.root_dir=root_dir\n        self.img_list=csv[\"image_id\"].values\n        self.labels=csv[\"label\"].values\n    def __len__(self):\n        return len(self.labels)\n    def __getitem__(self,idx):\n        image=Image.open( self.root_dir+self.img_list[idx] )\n        image=TF.to_tensor(image)\n        label=self.labels[idx]\n        return image, label","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:41.900573Z","iopub.execute_input":"2022-01-02T22:23:41.901158Z","iopub.status.idle":"2022-01-02T22:23:41.908592Z","shell.execute_reply.started":"2022-01-02T22:23:41.901113Z","shell.execute_reply":"2022-01-02T22:23:41.907746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = CassavaDataset(input_path+\"train_images/\", train)\nval_dataset = CassavaDataset(input_path+\"val_images/\", val)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:41.910215Z","iopub.execute_input":"2022-01-02T22:23:41.910496Z","iopub.status.idle":"2022-01-02T22:23:41.919527Z","shell.execute_reply.started":"2022-01-02T22:23:41.910460Z","shell.execute_reply":"2022-01-02T22:23:41.918741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transformers=dict()\nkeys=['orig','orig2','hflip','vflip','hvflip']\n\ntransformers['orig']=T.Compose([T.Resize(512),\n                        T.Normalize( [0.485,0.456,0.406],[0.229,0.224,0.225] ) ] )\ntransformers['orig2']=T.Compose([T.Resize(256),\n                        T.CenterCrop(224),\n                        T.Normalize( [0.485,0.456,0.406],[0.229,0.224,0.225] ) ] )\ntransformers['hflip']=T.Compose([\n                            T.RandomHorizontalFlip(p=1.0),\n                            T.Resize(256),\n                            T.RandomCrop(224),\n                            T.Normalize( [0.485,0.456,0.406],[0.229,0.224,0.225] )])\ntransformers['vflip']=T.Compose([\n                            T.RandomVerticalFlip(p=1.0),\n                            T.Resize(256),\n                            T.RandomCrop(224),\n                            T.Normalize( [0.485,0.456,0.406],[0.229,0.224,0.225] )])\ntransformers['hvflip']=T.Compose([\n                            T.RandomHorizontalFlip(p=1.0),\n                            T.RandomVerticalFlip(p=1.0),\n                            T.Resize(256),\n                            T.RandomCrop(224),\n                            T.Normalize( [0.485,0.456,0.406],[0.229,0.224,0.225] )])","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:41.921160Z","iopub.execute_input":"2022-01-02T22:23:41.921495Z","iopub.status.idle":"2022-01-02T22:23:41.936042Z","shell.execute_reply.started":"2022-01-02T22:23:41.921455Z","shell.execute_reply":"2022-01-02T22:23:41.935290Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_epoch(model,criterion,optimizer,dataset,epoch):\n    train_dataset=dataset\n    data_loader=DataLoader(dataset,batch_size=4,shuffle=True,num_workers=4,pin_memory=True)\n    dataset_size=len(dataset)\n    print(f\"Epoch#{epoch}. Train\")\n    \n    model.train()\n    \n    running_loss=0.0   #накопление лосса\n    running_corrects=0.0 #накопление для accuracy\n    \n    epoch_loss=0.0\n    epoch_acc=0.0\n    #keys2=[ keys[(epoch-1)%len(keys)] ]\n    keys2 = [\"orig2\"]\n    for inputs,labels in tqdm( data_loader):\n        inputs=inputs.to('cuda').type(torch.float)\n        labels=labels.to('cuda') #передаем батч на GPU(cuda)\n        optimizer.zero_grad()\n        \n        out_list=[]\n        for key in ['orig']:\n            img=transformers[key](inputs)\n            output=model(img)\n            out_list.append(output)\n        \n        outputs=sum(out_list)/len(out_list)\n        _,preds=torch.max(outputs,dim=1)\n        loss=criterion(outputs,labels)\n        loss.backward() # обратное распостранение градиента\n        optimizer.step() # шаг оптимизатора\n        running_loss+=loss.item()*inputs.size(0)\n        running_corrects += torch.sum(preds == labels.data)\n    \n    epoch_loss = running_loss / dataset_size\n    epoch_acc = running_corrects / dataset_size\n    \n    print(f'Loss: { epoch_loss } Acc: { epoch_acc }')\n    print(f\"Epoch#{epoch} (Train) completed. \")\n    return model, epoch_loss, epoch_acc","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:41.940737Z","iopub.execute_input":"2022-01-02T22:23:41.941026Z","iopub.status.idle":"2022-01-02T22:23:41.952958Z","shell.execute_reply.started":"2022-01-02T22:23:41.940998Z","shell.execute_reply":"2022-01-02T22:23:41.952091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def valid_epoch(model,criterion,optimizer,dataset,epoch):\n    val_dataset=dataset\n    data_loader=DataLoader(dataset,batch_size=4,shuffle=True,num_workers=4,pin_memory=True)\n    dataset_size=len(val_dataset)\n    print(f\"Epoch#{epoch}. Validation\")\n    model.eval()\n    running_loss=0.0 # накопление лосса\n    running_corrects=0\n    \n    epoch_loss=0.0\n    epoch_acc=0.0\n    with torch.no_grad():\n        for inputs,labels in tqdm( data_loader):\n            inputs=inputs.to('cuda').type(torch.float)\n            labels=labels.to('cuda') #передаем батч на GPU(cuda)\n        \n            out_list=[]\n            for key in ['orig']:\n                img=transformers[key](inputs)\n                output=model(img)\n                out_list.append(output)\n        \n            outputs=sum(out_list)/len(out_list)\n            _,preds=torch.max(outputs,dim=1)\n            loss=criterion(outputs,labels)\n        \n            running_loss+=loss.item()*inputs.size(0)\n            running_corrects += torch.sum(preds == labels.data)\n    \n    epoch_loss = running_loss / dataset_size\n    epoch_acc = running_corrects / dataset_size\n    \n    print(f'Loss: { epoch_loss } Acc: { epoch_acc }')\n    print(f\"Epoch#{epoch} (Validation) completed.  \")\n    return model, epoch_loss, epoch_acc","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:41.954006Z","iopub.execute_input":"2022-01-02T22:23:41.954203Z","iopub.status.idle":"2022-01-02T22:23:41.968032Z","shell.execute_reply.started":"2022-01-02T22:23:41.954178Z","shell.execute_reply":"2022-01-02T22:23:41.967090Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_ft = torchvision.models.resnext50_32x4d(pretrained=True)\nmodel_ft.fc=torch.nn.Linear(model_ft.fc.in_features,5)\nmodel_ft = model_ft.to('cuda') #передали сетку на cuda","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:41.969656Z","iopub.execute_input":"2022-01-02T22:23:41.969998Z","iopub.status.idle":"2022-01-02T22:23:51.340310Z","shell.execute_reply.started":"2022-01-02T22:23:41.969961Z","shell.execute_reply":"2022-01-02T22:23:51.339595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = torch.nn.CrossEntropyLoss()\noptimizer=torch.optim.Adam(params=model_ft.parameters(),lr=3e-5)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:51.341421Z","iopub.execute_input":"2022-01-02T22:23:51.342159Z","iopub.status.idle":"2022-01-02T22:23:51.348342Z","shell.execute_reply.started":"2022-01-02T22:23:51.342119Z","shell.execute_reply":"2022-01-02T22:23:51.347537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"best_model=model_ft\nbest_acc=0.0\nbest_epoch=1\n\nnum_epochs=5\n\ntrain_loss_history=[]\ntrain_acc_history=[]\n\nval_loss_history=[]\nval_acc_history=[]\n\nfor epoch in range(1,num_epochs+1):\n    #тренировка\n    root_dir='/kaggle/input/cassava-leaf-disease-classification/train_images/'\n    train_dataset=CassavaDataset(root_dir=root_dir,csv=train)\n    model_ft, train_loss, train_acc=train_epoch(model_ft,criterion,optimizer,train_dataset,epoch)\n    train_loss_history.append(train_loss)\n    train_acc_history.append(train_acc)\n    #валидация\n    val_dataset = CassavaDataset(root_dir=root_dir, csv = val)\n    model_ft, val_loss, val_acc=valid_epoch(model_ft,criterion,optimizer,val_dataset,epoch)\n    val_loss_history.append(val_loss)\n    val_acc_history.append(val_acc)\n    \n    if(val_acc>best_acc):\n        best_acc=val_acc\n        best_model=model_ft\n        best_epoch=epoch","metadata":{"execution":{"iopub.status.busy":"2022-01-02T22:23:51.349440Z","iopub.execute_input":"2022-01-02T22:23:51.349894Z","iopub.status.idle":"2022-01-02T23:52:38.109130Z","shell.execute_reply.started":"2022-01-02T22:23:51.349858Z","shell.execute_reply":"2022-01-02T23:52:38.099886Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#saving\noutput_model_file = 'best_model.bin'\ntorch.save(best_model, output_model_file)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T23:52:45.849407Z","iopub.execute_input":"2022-01-02T23:52:45.849688Z","iopub.status.idle":"2022-01-02T23:52:46.033606Z","shell.execute_reply.started":"2022-01-02T23:52:45.849655Z","shell.execute_reply":"2022-01-02T23:52:46.032853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.read_csv(input_path+\"sample_submission.csv\")\ntest","metadata":{"execution":{"iopub.status.busy":"2022-01-02T23:53:34.722600Z","iopub.execute_input":"2022-01-02T23:53:34.722881Z","iopub.status.idle":"2022-01-02T23:53:34.744611Z","shell.execute_reply.started":"2022-01-02T23:53:34.722848Z","shell.execute_reply":"2022-01-02T23:53:34.743796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['label'] = 0","metadata":{"execution":{"iopub.status.busy":"2022-01-02T23:53:41.016420Z","iopub.execute_input":"2022-01-02T23:53:41.016882Z","iopub.status.idle":"2022-01-02T23:53:41.025127Z","shell.execute_reply.started":"2022-01-02T23:53:41.016835Z","shell.execute_reply":"2022-01-02T23:53:41.023971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset=CassavaDataset(root_dir=input_path+'test_images/',csv = test)\ndata_loader=DataLoader(test_dataset,batch_size=32,shuffle=False,num_workers=4,pin_memory=True)\ndataset_size=len(test_dataset)\n\npred_list=[]\nbest_model.eval()\nwith torch.no_grad():\n    for inputs,labels in tqdm( data_loader):\n        inputs=inputs.to('cuda').type(torch.float)\n        labels=labels.to('cuda') #передаем батч на GPU(cuda)\n        \n        out_list=[]\n        for key in ['orig']:\n            img=transformers[key](inputs)\n            out_list.append(best_model(img))\n        outputs=sum(out_list)/len(out_list)\n        _,preds=torch.max(outputs,dim=1)\n        pred_list.append(preds)\n\ntorch.cat(pred_list)","metadata":{"execution":{"iopub.status.busy":"2022-01-02T23:54:57.653021Z","iopub.execute_input":"2022-01-02T23:54:57.653302Z","iopub.status.idle":"2022-01-02T23:54:57.910745Z","shell.execute_reply.started":"2022-01-02T23:54:57.653271Z","shell.execute_reply":"2022-01-02T23:54:57.910000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y = torch.cat(pred_list).cpu().detach().numpy()","metadata":{"execution":{"iopub.status.busy":"2022-01-02T23:55:06.669308Z","iopub.execute_input":"2022-01-02T23:55:06.669569Z","iopub.status.idle":"2022-01-02T23:55:06.674209Z","shell.execute_reply.started":"2022-01-02T23:55:06.669539Z","shell.execute_reply":"2022-01-02T23:55:06.673431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['label']=y\ntest.to_csv(\"submission_resnext.csv\",index=False)\ntest","metadata":{"execution":{"iopub.status.busy":"2022-01-02T23:55:10.397674Z","iopub.execute_input":"2022-01-02T23:55:10.398202Z","iopub.status.idle":"2022-01-02T23:55:10.411556Z","shell.execute_reply.started":"2022-01-02T23:55:10.398162Z","shell.execute_reply":"2022-01-02T23:55:10.410885Z"},"trusted":true},"execution_count":null,"outputs":[]}]}