{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"#!pip install --upgrade pip efficientnet-pytorch\n!pip install ../input/timm031/timm-0.3.1-py3-none-any.whl\nsub = 0\nif sub==0:\n    !pip install --upgrade pip adabound","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\nimport timm\nimport os\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n    #for filename in filenames:\n       # print(os.path.join(dirname, filename))\n\nimport matplotlib.pyplot as plt\nimport cv2\nimport sys\nfrom sklearn import model_selection, metrics\nimport torch\nfrom PIL import Image\n#from tensorflow.keras.applications import EfficientNetB0\nfrom tensorflow.keras import models, layers\nfrom PIL import ImageEnhance, ImageOps\nimport pdb\nimport torchvision.transforms as transforms\nimport adabound\nimport random\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"BASE_DIR = '../input/cassava-leaf-disease-classification'\nTRAIN_PATH = BASE_DIR+\"/train_images/\"\nTEST_PATH = BASE_DIR+\"/test_images/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def read_image(path,label):\n    image_data = cv2.imread(path)\n    plt.title('label:{}'.format(label))\n    plt.imshow(image_data)\n    return image_data\nclass CassavaDataset(torch.utils.data.Dataset):\n    \"\"\"\n    Helper Class to create the pytorch dataset\n    \"\"\"\n    def __init__(self, df, data_path, mode=\"train\", transforms=None):\n        super().__init__()\n        self.df_data = df.values\n        self.data_path = data_path\n        self.transforms = transforms\n        self.mode = mode\n        self.data_dir = \"train_images\" if mode == \"train\" else \"test_images\"\n\n    def __len__(self):\n        return len(self.df_data)\n\n    def __getitem__(self, index):\n        img_name, label = self.df_data[index]\n        img = Image.open(img_name).convert(\"RGB\")\n\n        if self.transforms is not None:\n            img = self.transforms(img)\n\n        return img, label\nclass CassvaImgClassifier(torch.nn.Module):\n    def __init__(self, model_arch, n_class, pretrained=False):\n        super().__init__()\n        self.model = timm.create_model(model_arch, pretrained=pretrained)\n        n_features = self.model.classifier.in_features\n        self.model.classifier = torch.nn.Linear(n_features, n_class)\n        \n    def forward(self, x):\n        x = self.model(x)\n        return x\nclass CassavaNet(torch.nn.Module):\n    def __init__(self,model_name):\n        super().__init__()\n        backbone = timm.create_model(model_name, pretrained=True)\n        n_features = backbone.fc.in_features\n        self.backbone = torch.nn.Sequential(*backbone.children())[:-2]\n        self.classifier = torch.nn.Linear(n_features, 5)\n        self.pool = torch.nn.AdaptiveAvgPool2d((1, 1))\n\n    def forward_features(self, x):\n        x = self.backbone(x)\n        return x\n\n    def forward(self, x):\n        feats = self.forward_features(x)\n        x = self.pool(feats).view(x.size(0), -1)\n        x = self.classifier(x)\n        return x, feats","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train(net, epoch, trainLoader, optimizer, criterion):\n    # 训练一轮\n    sum_loss = 0\n    total = 0\n    correct = 0\n    net.train()\n    for i, data in enumerate(trainLoader, 0):\n        # 准备数据\n        length = len(data)\n        input, target = data\n        input, target = input.to(device), target.to(device)\n        # 训练\n        optimizer.zero_grad()\n        # forward + backward\n        output= net(input)\n        loss = criterion(output, target)\n        loss.backward()\n        optimizer.step()\n\n        # 每训练1个batch打印一次loss和准确率\n        sum_loss += loss.item()\n        _, predicted = torch.max(output.data, 1)\n        total += target.size(0)\n        correct += predicted.eq(target.data).cpu().sum()\n        if i % 49 == 0 and i != 0:\n            # save\n            log_string('[epoch:%d, batch:%d] Loss: %.03f | Acc: %.3f%% ' % (\n            epoch + 1, i + 1, sum_loss / total, 100. * float(correct) / float(total)))\n            # print('[epoch:%d, batch:%d] Loss: %.03f | Acc: %.3f%% '% (epoch + 1, i+1, sum_loss / total,100. * float(correct) / float(total)))\n    # save\n    log_string('[epoch:%d] Loss: %.03f | Acc: %.3f%% ' % (\n    epoch + 1, sum_loss / total, 100. * float(correct) / float(total)))\n    # print('[epoch:%d] Loss: %.03f | Acc: %.3f%% '% (epoch + 1,sum_loss / total,100. * float(correct) / float(total)))\n    return float(correct) / float(total)\n\ndef valid(net, EPOCH, validLoader):\n    # 验证一轮\n    total = 0\n    correct = 0\n    net.eval()\n    with torch.no_grad():\n        correct = 0\n        total = 0\n        for data in validLoader:\n            net.eval()\n            images, labels = data\n            images, labels = images.to(device), labels.to(device)\n            outputs = net(images)\n            # 取得分最高的那个类 (outputs.data的索引号)\n            _, predicted = torch.max(outputs.data, 1)\n            total += labels.size(0)\n            correct += (predicted == labels).cpu().sum()\n        # save\n        log_string('测试分类准确率为：%.3f%%' % (100. * float(correct) / float(total)))\n        #print('测试分类准确率为：%.3f%%' % (100. * float(correct) / float(total)))\n    return float(correct) / float(total)\ndef log_string(out_str):\n    LOG_FOUT.write(out_str + '\\n')\n    LOG_FOUT.flush()\n    print(out_str)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr = 1e-4\nBATCH_SIZE=8\nIMG_SIZE=512\nEPOCH=10\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\ndf = pd.read_csv(os.path.join(BASE_DIR,'train.csv'))\ndf.image_id = df.image_id.apply(lambda x : TRAIN_PATH+x)\nLOG_FOUT = open(os.path.join('./', 'log_train.txt'), 'w')\nif os.path.exists('./models')==0: # 存放训练好的模型\n    os.mkdir('./models')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import StratifiedKFold\ndef one_epoch(fold):\n    log_string('fold:%d, batch_size:%d,lr:%f,fold_epech:%d,device:%s' % (fold , BATCH_SIZE,lr,2,device))\n    folds= StratifiedKFold(n_splits=fold).split(df['image_id'],df['label'])\n    acc_train_all= []\n    acc_valid_all= []\n    best_acc = 0\n    for i,(train_index,valid_index) in enumerate(folds):\n        train_df = df.loc[train_index,:].reset_index(drop=True)\n        valid_df = df.loc[valid_index,:].reset_index(drop=True)\n        train_dataset = CassavaDataset(train_df,BASE_DIR,transforms=transforms.Compose([\n            transforms.RandomResizedCrop(IMG_SIZE),\n            transforms.RandomHorizontalFlip(p=0.5),\n            transforms.RandomVerticalFlip(p=0.5),\n            transforms.RandomRotation(45),\n            transforms.ColorJitter(brightness=0.1,contrast=0.1),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n        ]))\n        valid_dataset = CassavaDataset(valid_df,BASE_DIR,transforms=transforms.Compose([\n            transforms.CenterCrop(IMG_SIZE),\n            transforms.ToTensor(),\n            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n        ]))\n        trainLoader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=BATCH_SIZE,shuffle=True)\n        validLoader = torch.utils.data.DataLoader(dataset=valid_dataset,batch_size=BATCH_SIZE)\n        acc= train(net, i, trainLoader, optimizer, criterion)\n        acc_train_all.append(acc)\n        acc= valid(net ,i, validLoader)\n        acc_valid_all.append(acc)\n        if acc > best_acc:\n            best_acc = acc\n            torch.save(net, './models/efficientnetb4_fold5_2.pth')\n        scheduler.step()\n    plt.plot(acc_train_all)\n    plt.plot(acc_valid_all)\n    plt.ylabel('Accuracy')\n    plt.xlabel('Epoch')\n    plt.legend(['Train', 'Valid'], loc='upper left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\nmodel_name = 'tf_efficientnet_b4_ns'\nnet = CassvaImgClassifier(model_name,5,True)\nnet.to(device)\ncriterion = torch.nn.CrossEntropyLoss()\noptimizer=adabound.AdaBound(net.parameters(),lr=lr,final_lr=0.1)\nscheduler=torch.optim.lr_scheduler.CosineAnnealingLR(optimizer,T_max=5)\nfor i in range(2):\n    one_epoch(5)\n'''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def test_one(model_name , file_name):\n    net = CassvaImgClassifier(model_name,5, False)\n    net.to(device)\n    net.load_state_dict(torch.load(filename).state_dict())\n    net.eval()\n    preds = []\n    submit = pd.read_csv(os.path.join(BASE_DIR, \"sample_submission.csv\"))\n    for image_id in submit.image_id:\n        img = Image.open(BASE_DIR+\"/test_images/\"+image_id).convert(\"RGB\")\n        img = transform1(img).unsqueeze(0).to(device)\n        pred = net(img) # 概率\n        # _,pred = torch.max(pred.data,1)  # 预测的类别\n        pred = pred.cpu().detach().numpy().astype('int')\n        preds.extend(pred)\n    return preds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"file_name = ['a','b','c']\nmodel_name = ['a','b','c']\ntransform1 = transforms.Compose([\n    transforms.CenterCrop(IMG_SIZE),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n])\nall_preds = []\nfor i in range(3):  \n    all_preds.append(test_one(model_name[i],file_name[i]))\n\nsubmit['label'] = np.argmax(np.mean(all_preds, axis=0), axis=1)\n#print(submit)\nsubmit.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}