{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"from torchvision.models import resnext50_32x4d as resnext\nfrom torchvision.models import vgg16\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nimport pandas as pd \nimport numpy as np\nimport cv2\nfrom PIL import Image\nimport os\nimport tqdm\n\nfrom matplotlib import cm\nimport matplotlib.pyplot as plt\nfrom torchvision import transforms\nfrom sklearn.model_selection import train_test_split\nprint('gpu,',torch.cuda.is_available())\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class LeafNet(nn.Module): \n    def __init__(self, hidden_size=1280,num_cls=5):\n        super(LeafNet, self).__init__()\n        self.model_base = resnext().double()\n        #self.model_base = vgg16().double()\n        self.linear1 = nn.Linear(1000,hidden_size)\n        self.linear2 = nn.Linear(hidden_size,hidden_size)\n        self.linear3 = nn.Linear(hidden_size,num_cls)\n        self.dropout = nn.Dropout(0.5)\n        self.relu = nn.ReLU()\n        self.loss = nn.CrossEntropyLoss() \n        self.bn0 = nn.BatchNorm2d(1000)\n        self.bn1 = nn.BatchNorm2d(hidden_size)\n        self.bn2 = nn.BatchNorm2d(hidden_size)\n        ####self.loss = nn.BCEWithLogitsLoss() 不应该用bce loss，你上面的ce loss是对的\n        \n    def forward(self,inputs):\n        '''\n        inputs: B x [img_size x img_size x num_channel]\n        labels: B x num_cls\n        '''\n        img,labels = inputs\n        x = self.model_base(img)\n        x = self.dropout(self.relu(self.linear1(x)))\n        x = self.dropout(self.relu(self.linear2(x)))\n        x = self.linear3(x)\n        ls = self.loss(x,labels)\n        return ls\n    \n    def inference(self,inputs):\n        '''\n        inputs: B x [img_size x img_size x num_channel]\n        labels: B x num_cls\n        '''\n        img = inputs\n        x = self.model_base(img)\n        x = self.dropout(self.relu(self.linear1(x)))\n        x = self.dropout(self.relu(self.linear2(x)))\n        x = self.linear3(x)\n        x = torch.argmax(x,dim=1)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\ndef one_hot(lst,num_cls):\n    tables = np.zeros((len(lst),num_cls))\n    for i,line in enumerate(lst):\n        tables[i,line] = 1\n    return tables\n'''\nfrom albumentations import (\n    HorizontalFlip, VerticalFlip, IAAPerspective, ShiftScaleRotate, CLAHE, RandomRotate90,\n    Transpose, ShiftScaleRotate, Blur, OpticalDistortion, GridDistortion, HueSaturationValue,\n    IAAAdditiveGaussianNoise, GaussNoise, MotionBlur, MedianBlur, IAAPiecewiseAffine, RandomResizedCrop,\n    IAASharpen, IAAEmboss, RandomBrightnessContrast, Flip, OneOf, Compose, Normalize, Cutout, CoarseDropout, ShiftScaleRotate, CenterCrop, Resize\n)\n\nfrom albumentations.pytorch import ToTensorV2\nimport albumentations as A\nclass Leafdataset(Dataset):\n    def __init__(self,path,mode_train=False,num_cls=5):\n        self.mode_train = mode_train\n        '''\n        if self.mode_train:\n            image_base = os.path.join(path,'train_images/')\n            csv_path = os.path.join(path,'train.csv')\n        else:\n            image_base = os.path.join(path,'test_images/')\n            csv_path = os.path.join(path,'test.csv')\n        '''\n        \n        image_base = os.path.join(path,'train_images/')\n        csv_path = os.path.join(path,'train.csv')\n        info = pd.read_csv(csv_path)\n        \n        labels = []\n        for i in range(len(info['label'])):\n            #print(info['label'][i])\n            labels.append(info['label'][i])\n        \n        img_names = info['image_id']\n        \n        num_total = len(labels)\n        imgs = list()\n        \n        for img_name in img_names:\n            img_name = os.path.join(image_base,img_name)\n            imgs.append(img_name)\n            \n        if self.mode_train:\n            self.imgs = imgs#[:int(0.98*len(imgs))]\n            self.labels = labels#[:int(0.*len(labels))]\n        else:\n            self.imgs = imgs[int(0.8*len(imgs)):]\n            self.labels = labels[int(0.8*len(labels)):]\n            \n        self.preprocess = A.Compose([\n                                              CenterCrop(256,256, p=1.),\n                                              Resize(256,256),\n                                              Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),\n                                              ToTensorV2(p=1.0),\n                                              ])\n        self.augmentation = A.Compose([\n            #transforms.Resize(256),\n            RandomResizedCrop(256, 256),\n            Transpose(p=0.5),\n            HorizontalFlip(p=0.5),\n            VerticalFlip(p=0.5),\n            ShiftScaleRotate(p=0.5),\n            HueSaturationValue(hue_shift_limit=0.2, sat_shift_limit=0.2, val_shift_limit=0.2, p=0.5),\n            RandomBrightnessContrast(brightness_limit=(-0.1,0.1), contrast_limit=(-0.1, 0.1), p=0.5),\n            Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),\n            CoarseDropout(p=0.5),\n            Cutout(p=0.5),\n            ToTensorV2(p=1.0),\n        ])\n        print(len(self.labels),len(self.imgs))\n        \n    def __len__(self):\n        return len(self.labels)\n\n    def __getitem__(self,idx):\n        #print(idx,len(self.labels),self.labels)\n        img_name = self.imgs[idx]\n        img = Image.open(img_name)\n        img = np.array(img)\n        if self.mode_train:\n            img = self.augmentation(image=img)['image'].float()\n        else:\n            img = self.preprocess(image=img)['image'].float()\n        label = torch.tensor(self.labels[idx])\n        return img,label\n\nclass Leafdataset_val(Dataset):\n    def __init__(self,path,num_cls=5):\n        import glob\n        image_base = os.path.join(path,'test_images/')\n        self.imgs = glob.glob(image_base+'*.jpg')\n        \n        \n        self.preprocess = A.Compose([\n                                      CenterCrop(256,256, p=1.),\n                                      Resize(256,256),\n                                      Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),\n                                      ToTensorV2(p=1.0),\n                                      ])\n        print(len(self.imgs))\n        \n    def __len__(self):\n        return len(self.imgs)\n\n    def __getitem__(self,idx):\n        #print(idx,len(self.labels),self.labels)\n        img_name = self.imgs[idx]\n        img = Image.open(img_name)\n        img = np.array(img)\n        \n        img = self.preprocess(image=img)['image'].float()\n        return img_name.split('/')[-1],img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train():\n    seed=42\n    torch.manual_seed(seed)\n\n    lr = 1e-4\n    batch_size = 50\n    num_epochs = 10\n    path = \"../input/cassava-leaf-disease-classification/\"\n\n    dataset_train = Leafdataset(path, mode_train=True)\n    dataset_test = Leafdataset(path, mode_train=False)\n    dataset_val = Leafdataset_val(path)\n    train_loader = DataLoader(dataset_train,batch_size=batch_size,shuffle=True)\n\n    model = LeafNet().float().cuda()\n\n    #if opt.resume:\n        #model, optimizer = load_checkpoint(os.path.join(checkpoint_dir,'model_best'),model,optimizer)\n\n    num_total_instance = len(dataset_train)\n    num_batch =  np.ceil(num_total_instance/batch_size)\n\n    optimizer = optim.Adam([\n                            {\n                            \"params\":model.parameters(), \"lr\":lr,\n                            },\n                            #{\n                            #\"params\": model.model_base.parameters(), \"lr\":lr*0.1,\n                            #}\n                            ]\n                           )\n    \n    lr_schedule = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=3574,\n                                                             eta_min=1e-6)\n    model.to(device)\n    min_loss = float('inf')\n    \n    for epoch in range(num_epochs):\n        training_loss=0.0\n        validate_test(model,dataset_val)\n        #validate(model,dataset_test)\n        model.train()\n        \n        for index,(imgs,labels) in enumerate(train_loader):\n            labels = labels.squeeze()\n            imgs = imgs.to(device)\n            labels = labels.to(device)\n            inputs = imgs,labels\n            loss = model(inputs)\n            \n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n            training_loss += loss.item()\n            if index %10 ==0:\n                print(\"Epoch:[%d|%d], Batch:[%d|%d] loss: %f\"%(epoch,num_epochs,index,num_batch,loss.item()/batch_size))\n            \n        #validate(model,dataset_test)\n        training_loss_epoch = training_loss/(len(train_loader)*batch_size)\n        \n        \n    if training_loss_epoch < min_loss:\n        min_loss = training_loss_epoch\n        print('New best performance! saving...')\n        #torch.save(model.state_dict(),'ckpt_best.pt')\n    validate_test(model,dataset_val)\n    #torch.save(model.state_dict(),'ckpt_routine_{}.pt'.format(epoch))\n\ndef validate_test(model,dataset_test):\n    predictions = []\n    ids = []\n    \n    for i,(img_name,img) in enumerate(dataset_test):\n        img = img.unsqueeze(0).to(device)\n        pred = model.inference(img).cpu().detach().item()\n        predictions.append(pred)\n        ids.append(img_name)\n    sub = pd.DataFrame({'image_id': ids, 'label': predictions})\n    sub.to_csv('submission.csv', index = False)\n        \ndef validate(model,dataset_test):\n    model.eval()\n    \n    num_corr = 0\n    num_total = len(dataset_test)\n    for i,(img,label) in enumerate(dataset_test):\n        img = img.unsqueeze(0).to(device)\n        pred = model.inference(img).cpu().detach().item()\n        \n        label = label.cpu().detach().item()\n        \n        if pred==label:\n            num_corr += 1\n    \n    print(\"accuracy is\", num_corr*1.0/num_total, num_corr,'/',num_total)\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}