{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.10","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport copy\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision.datasets \nimport torchvision.transforms as transforms\nimport pandas as pd\nfrom tqdm.auto import tqdm\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts,ExponentialLR\nfrom sklearn.model_selection import train_test_split\nfrom PIL import Image\nimport cv2\nimport albumentations\nfrom albumentations.pytorch.transforms import ToTensorV2","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-09-11T14:22:48.740163Z","iopub.execute_input":"2023-09-11T14:22:48.741231Z","iopub.status.idle":"2023-09-11T14:22:48.748777Z","shell.execute_reply.started":"2023-09-11T14:22:48.741191Z","shell.execute_reply":"2023-09-11T14:22:48.747828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#标签和类别数进行对应\ntrain = pd.read_csv(\"/kaggle/input/classify-leaves/train.csv\")\nlabels = list(pd.read_csv(\"/kaggle/input/classify-leaves/train.csv\")['label'])\nlabels_unique = list(set(list(labels))) #list index--labels\nlabel_nums = []\nfor i in range(len(labels)):\n    label_nums.append(labels_unique.index(labels[i]))\ntrain['number'] = label_nums\n# train.to_csv(\"./train_num_label.csv\", index = 0) #记录对应关系","metadata":{"execution":{"iopub.status.busy":"2023-09-11T14:19:53.445834Z","iopub.execute_input":"2023-09-11T14:19:53.446713Z","iopub.status.idle":"2023-09-11T14:19:53.530223Z","shell.execute_reply.started":"2023-09-11T14:19:53.446665Z","shell.execute_reply":"2023-09-11T14:19:53.529265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.read_csv(\"/kaggle/input/classify-leaves/test.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-09-11T14:13:14.879816Z","iopub.execute_input":"2023-09-11T14:13:14.880603Z","iopub.status.idle":"2023-09-11T14:13:14.898599Z","shell.execute_reply.started":"2023-09-11T14:13:14.880563Z","shell.execute_reply":"2023-09-11T14:13:14.897706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data,eval_data = train_test_split(train,test_size=0.2,stratify=train['number'])","metadata":{"execution":{"iopub.status.busy":"2023-09-11T14:13:15.297521Z","iopub.execute_input":"2023-09-11T14:13:15.298373Z","iopub.status.idle":"2023-09-11T14:13:15.323147Z","shell.execute_reply.started":"2023-09-11T14:13:15.298342Z","shell.execute_reply":"2023-09-11T14:13:15.322159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Leaf_Dataset(Dataset):\n    '''\n    树叶数据集的训练集 自定义Dataset\n    '''\n    def __init__(self, train_csv, transform = None, test = False):\n        '''\n        train_path : 传入记录图像路径及其标号的csv文件\n        transform : 对图像进行的变换\n        '''\n        super().__init__()\n        self.train_csv = train_csv\n        self.image_path = list(self.train_csv['image']) #图像所在地址记录\n        self.test = test\n        if not self.test:\n            self.label_nums = list(self.train_csv['number']) #图像的标号记录\n        self.transform = transform\n    def __getitem__(self, idx):\n        '''\n        idx : 所需要获取的图像的索引\n        return : image， label\n        '''\n        image = cv2.imread(os.path.join(\"/kaggle/input/classify-leaves\", self.image_path[idx]))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n#         image = Image.open(os.path.join(\"/kaggle/input/classify-leaves\", self.image_path[idx]))\n        if(self.transform != None):\n            image = self.transform(image = image)['image']\n        if not self.test:\n            label = self.label_nums[idx]\n            return image, label\n        else:\n            return image\n    \n    def __len__(self):\n        return len(self.image_path)","metadata":{"execution":{"iopub.status.busy":"2023-09-11T14:20:21.899770Z","iopub.execute_input":"2023-09-11T14:20:21.900133Z","iopub.status.idle":"2023-09-11T14:20:21.910127Z","shell.execute_reply.started":"2023-09-11T14:20:21.900103Z","shell.execute_reply":"2023-09-11T14:20:21.909012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# #data agumentation\n# transforms_train = torchvision.transforms.Compose([\n#     transforms.Resize((320, 320)),\n#     transforms.RandomHorizontalFlip(p=0.5),\n#     transforms.RandomVerticalFlip(p=0.5),\n#     transforms.ColorJitter(brightness=0.2,contrast=0.2, saturation=0.2, hue=0),\n#     transforms.ToTensor(),\n#     transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n\n# ])\n# transforms_test = torchvision.transforms.Compose([\n#     transforms.Resize((320, 320)),\n#     transforms.ToTensor(),\n#     transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n# ])","metadata":{"execution":{"iopub.status.busy":"2023-09-11T14:20:23.091880Z","iopub.execute_input":"2023-09-11T14:20:23.092777Z","iopub.status.idle":"2023-09-11T14:20:23.098147Z","shell.execute_reply.started":"2023-09-11T14:20:23.092735Z","shell.execute_reply":"2023-09-11T14:20:23.096934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transforms_train = albumentations.Compose(\n    [\n        albumentations.Resize(320, 320),\n        albumentations.HorizontalFlip(p=0.5),\n        albumentations.VerticalFlip(p=0.5),\n        albumentations.Rotate(limit=180, p=0.7),\n        albumentations.RandomBrightnessContrast(),\n        albumentations.ShiftScaleRotate(\n            shift_limit=0.25, scale_limit=0.1, rotate_limit=0\n        ),\n        albumentations.Normalize(\n            [0.485, 0.456, 0.406], [0.229, 0.224, 0.225],\n            max_pixel_value=255.0, always_apply=True\n        ),\n        ToTensorV2(p=1.0),\n    ]\n)\ntransforms_test = albumentations.Compose(\n        [\n            albumentations.Resize(320, 320),\n            albumentations.Normalize(\n                [0.485, 0.456, 0.406], [0.229, 0.224, 0.225],\n                max_pixel_value=255.0, always_apply=True\n            ),\n            ToTensorV2(p=1.0)\n        ]\n    )","metadata":{"execution":{"iopub.status.busy":"2023-09-11T14:20:23.483858Z","iopub.execute_input":"2023-09-11T14:20:23.484742Z","iopub.status.idle":"2023-09-11T14:20:23.493513Z","shell.execute_reply.started":"2023-09-11T14:20:23.484702Z","shell.execute_reply":"2023-09-11T14:20:23.492042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(train_loader, valid_loader, device = torch.device(\"cuda:0\")):\n    net = torchvision.models.resnet50(weights = torchvision.models.ResNet50_Weights.IMAGENET1K_V1)\n    in_features = net.fc.in_features\n    net.fc = nn.Linear(in_features, 176)\n    net = net.to(device)\n    epoch = 30\n    best_epoch = 0\n    best_score = 0.0\n    best_model_state = None\n    early_stopping_round = 3\n    losses = []\n    optimizer = optim.Adam(net.parameters(), lr=0.0001,weight_decay=1e-5)\n    loss = nn.CrossEntropyLoss(reduction='mean')\n#     scheduler = CosineAnnealingWarmRestarts(optimizer, T_0=10, T_mult=2, eta_min = 1e-6)\n    scheduler = ExponentialLR(optimizer, gamma=0.9,verbose=True)\n    for i in range(epoch):\n        acc = 0\n        loss_sum = 0\n        net.train()\n        for x, y in tqdm(train_loader):\n            x = torch.as_tensor(x, dtype=torch.float)\n            x = x.to(device)\n            y = y.to(device)\n            y_hat = net(x)\n            loss_temp = loss(y_hat, y)\n            loss_sum += loss_temp\n            optimizer.zero_grad()\n            loss_temp.backward()\n            optimizer.step()\n#             scheduler.step()\n            acc += torch.sum(y_hat.argmax(dim=1).type(y.dtype) == y)\n        scheduler.step()\n        losses.append(loss_sum.cpu().detach().numpy() / len(train_loader))\n        print( \"epoch: \", i, \"loss=\", loss_sum.item(), \"训练集准确度=\",(acc/(len(train_loader)*train_loader.batch_size)).item(),end=\"\")\n\n        test_acc = 0\n        net.eval()\n        for x, y in tqdm(valid_loader):\n            x = x.to(device)\n            x = torch.as_tensor(x, dtype=torch.float)\n            y = y.to(device)\n            y_hat = net(x)\n            test_acc += torch.sum(y_hat.argmax(dim=1).type(y.dtype) == y)\n        print(\"验证集准确度\", (test_acc / (len(valid_loader)*valid_loader.batch_size)).item())\n        if test_acc > best_score:\n            best_model_state = copy.deepcopy(net.state_dict())\n            best_score = test_acc\n            best_epoch = i\n            print('best epoch save!')\n        if i - best_epoch >= early_stopping_round:\n            break\n    net.load_state_dict(best_model_state)\n    testset = Leaf_Dataset(test, transform = transforms_test,test = True)\n    test_loader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False, drop_last=False)\n    device = torch.device(\"cuda:0\")\n    predictions = []\n    with torch.no_grad():\n        for x in tqdm(test_loader):\n            x = x.to(device)\n            x = torch.as_tensor(x, dtype=torch.float)\n            y_hat = net(x)\n            predict = torch.argmax(y_hat,dim=1).reshape(-1)\n            predict = list(predict.cpu().detach().numpy())\n            predictions.extend(predict)\n    return predictions","metadata":{"execution":{"iopub.status.busy":"2023-09-11T14:21:54.099961Z","iopub.execute_input":"2023-09-11T14:21:54.100365Z","iopub.status.idle":"2023-09-11T14:21:54.117497Z","shell.execute_reply.started":"2023-09-11T14:21:54.100338Z","shell.execute_reply":"2023-09-11T14:21:54.116582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_data,eval_data = train_test_split(train,test_size=0.2,stratify=train['number'])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import StratifiedKFold\nskf = StratifiedKFold(n_splits=5,shuffle=True,random_state=2023)\nprediction_df = pd.DataFrame()\nfor fold_n, (trn_idx, val_idx) in enumerate(skf.split(train, train['number'])):\n    print(f'fold {fold_n} training...')\n    train_data = train.iloc[trn_idx]\n    eval_data = train.iloc[val_idx]\n    trainset = Leaf_Dataset(train_data, transform = transforms_train)\n    evalset = Leaf_Dataset(eval_data, transform = transforms_test)\n    train_loader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True, drop_last=False)\n    eval_loader = torch.utils.data.DataLoader(evalset, batch_size=32, shuffle=False, drop_last=False)\n    predictions = train_model(train_loader, eval_loader)\n    prediction_df[f'fold_{fold_n}'] = predictions","metadata":{"execution":{"iopub.status.busy":"2023-09-11T14:23:15.137146Z","iopub.execute_input":"2023-09-11T14:23:15.138039Z","iopub.status.idle":"2023-09-11T16:32:00.102732Z","shell.execute_reply.started":"2023-09-11T14:23:15.137992Z","shell.execute_reply":"2023-09-11T16:32:00.101016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_predictions = list(prediction_df.mode(axis=1)[0].astype(int))\npredict_label = []\nfor i in range(len(all_predictions)):\n    predict_label.append(labels_unique[all_predictions[i]])\n\nsubmission = pd.read_csv(\"/kaggle/input/classify-leaves/test.csv\")\nsubmission[\"label\"] = pd.Series(predict_label)\nsubmission.to_csv(\"result.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-09-11T16:32:05.345033Z","iopub.execute_input":"2023-09-11T16:32:05.345780Z","iopub.status.idle":"2023-09-11T16:32:07.409613Z","shell.execute_reply.started":"2023-09-11T16:32:05.345747Z","shell.execute_reply":"2023-09-11T16:32:07.408649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission","metadata":{"execution":{"iopub.status.busy":"2023-09-11T16:32:12.810307Z","iopub.execute_input":"2023-09-11T16:32:12.810666Z","iopub.status.idle":"2023-09-11T16:32:12.827318Z","shell.execute_reply.started":"2023-09-11T16:32:12.810637Z","shell.execute_reply":"2023-09-11T16:32:12.826375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# trainset = Leaf_Dataset(train_data, transform = transforms_train)\n# evalset = Leaf_Dataset(eval_data, transform = transforms_test)\n# # testset = Leaf_Test_Dataset(\"\", transform = transforms_test)\n\n# train_loader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True, drop_last=False)\n# eval_loader = torch.utils.data.DataLoader(evalset, batch_size=32, shuffle=False, drop_last=False)\n# # test_loader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False, drop_last=False)\n# net = train(train_loader, eval_loader)","metadata":{"execution":{"iopub.status.busy":"2023-09-11T08:33:22.632847Z","iopub.execute_input":"2023-09-11T08:33:22.633182Z","iopub.status.idle":"2023-09-11T09:38:10.632024Z","shell.execute_reply.started":"2023-09-11T08:33:22.633153Z","shell.execute_reply":"2023-09-11T09:38:10.630799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2023-09-10T15:47:39.243962Z","iopub.execute_input":"2023-09-10T15:47:39.244358Z","iopub.status.idle":"2023-09-10T15:47:39.250966Z","shell.execute_reply.started":"2023-09-10T15:47:39.244326Z","shell.execute_reply":"2023-09-10T15:47:39.249910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # TTA eval\n# device = torch.device(\"cuda:0\")\n# testset = Leaf_Dataset(eval_data, transform = transforms_train)\n# test_loader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False, drop_last=False)\n# all_predictions = []\n# for i in range(5):\n#     predictions = []\n#     with torch.no_grad():\n#         for x,_ in tqdm(test_loader):\n#             x = x.to(device)\n#             x = torch.as_tensor(x, dtype=torch.float)\n#             y_hat = net(x)\n#             predict = torch.argmax(y_hat,dim=1).reshape(-1)\n#             predict = list(predict.cpu().detach().numpy())\n#             predictions.extend(predict)\n#     all_predictions.append(predictions)\n# all_predictions = list(pd.DataFrame(all_predictions).T.mode(axis=1)[0].astype(int))\n# from sklearn.metrics import accuracy_score\n# accuracy_score(all_predictions,eval_data['number'])","metadata":{"execution":{"iopub.status.busy":"2023-09-11T09:38:18.730330Z","iopub.execute_input":"2023-09-11T09:38:18.731413Z","iopub.status.idle":"2023-09-11T09:41:33.618818Z","shell.execute_reply.started":"2023-09-11T09:38:18.731381Z","shell.execute_reply":"2023-09-11T09:41:33.617875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# testset = Leaf_Dataset(test, transform = transforms_test,test = True)\n# test_loader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False, drop_last=False)\n# device = torch.device(\"cuda:0\")\n# predictions = []\n# with torch.no_grad():\n#     for x in tqdm(test_loader):\n#         x = x.to(device)\n#         x = torch.as_tensor(x, dtype=torch.float)\n#         y_hat = net(x)\n#         predict = torch.argmax(y_hat,dim=1).reshape(-1)\n#         predict = list(predict.cpu().detach().numpy())\n#         predictions.extend(predict)\n\n# predict_label = []\n# for i in range(len(predictions)):\n#     predict_label.append(labels_unique[predictions[i]])\n\n# submission = pd.read_csv(\"/kaggle/input/classify-leaves/test.csv\")\n# submission[\"label\"] = pd.Series(predict_label)\n# submission.to_csv(\"result.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-09-11T09:41:33.620824Z","iopub.execute_input":"2023-09-11T09:41:33.621363Z","iopub.status.idle":"2023-09-11T09:43:47.711122Z","shell.execute_reply.started":"2023-09-11T09:41:33.621327Z","shell.execute_reply":"2023-09-11T09:43:47.710241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # TTA test\n# device = torch.device(\"cuda:0\")\n# testset = Leaf_Dataset(test, transform = transforms_train, test=True)\n# test_loader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False, drop_last=False)\n# all_predictions = []\n# for i in range(5):\n#     predictions = []\n#     with torch.no_grad():\n#         for x in tqdm(test_loader):\n#             x = x.to(device)\n#             x = torch.as_tensor(x, dtype=torch.float)\n#             y_hat = net(x)\n#             predict = torch.argmax(y_hat,dim=1).reshape(-1)\n#             predict = list(predict.cpu().detach().numpy())\n#             predictions.extend(predict)\n#     all_predictions.append(predictions)\n# all_predictions = list(pd.DataFrame(all_predictions).T.mode(axis=1)[0].astype(int))\n# predict_label = []\n# for i in range(len(all_predictions)):\n#     predict_label.append(labels_unique[all_predictions[i]])\n\n# submission = pd.read_csv(\"/kaggle/input/classify-leaves/test.csv\")\n# submission[\"label\"] = pd.Series(predict_label)\n# submission.to_csv(\"result2.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-09-11T09:43:47.712638Z","iopub.execute_input":"2023-09-11T09:43:47.713004Z","iopub.status.idle":"2023-09-11T09:51:43.161389Z","shell.execute_reply.started":"2023-09-11T09:43:47.712957Z","shell.execute_reply":"2023-09-11T09:51:43.160423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}],"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"}}