{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":34375,"databundleVersionId":3405142,"sourceType":"competition"},{"sourceId":3363509,"sourceType":"datasetVersion","datasetId":995777},{"sourceId":8416442,"sourceType":"datasetVersion","datasetId":5009815},{"sourceId":8458221,"sourceType":"datasetVersion","datasetId":5041481},{"sourceId":8518126,"sourceType":"datasetVersion","datasetId":5085674}],"dockerImageVersionId":30177,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"package_paths = [\n    '../input/pytorch-image-library/pytorch-image-models-master/pytorch-image-models-master',\n]\n\nimport sys\n\n\nfor pth in package_paths:\n    sys.path.append(pth)","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:30:51.881227Z","iopub.execute_input":"2024-05-27T02:30:51.881512Z","iopub.status.idle":"2024-05-27T02:30:51.886799Z","shell.execute_reply.started":"2024-05-27T02:30:51.881483Z","shell.execute_reply":"2024-05-27T02:30:51.885897Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport cv2\nimport timm\nimport torch\nimport torch.nn as nn\nimport albumentations as A\nimport pytorch_lightning as pl\nimport matplotlib.pyplot as plt\nimport torchmetrics\nimport math\nfrom torch.utils.data import Dataset, DataLoader\nfrom albumentations.core.composition import Compose, OneOf\nfrom albumentations.pytorch import ToTensorV2\n\nfrom pytorch_lightning import Trainer, seed_everything\nfrom pytorch_lightning import Callback\nfrom pytorch_lightning.loggers import CSVLogger\nfrom pytorch_lightning.callbacks import ModelCheckpoint, EarlyStopping\nfrom sklearn.model_selection import StratifiedKFold","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-27T02:30:52.424998Z","iopub.execute_input":"2024-05-27T02:30:52.425740Z","iopub.status.idle":"2024-05-27T02:30:52.432286Z","shell.execute_reply.started":"2024-05-27T02:30:52.425692Z","shell.execute_reply":"2024-05-27T02:30:52.431427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"PyTorch Lightning version: {pl.__version__}\")","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:30:53.395029Z","iopub.execute_input":"2024-05-27T02:30:53.395920Z","iopub.status.idle":"2024-05-27T02:30:53.400232Z","shell.execute_reply.started":"2024-05-27T02:30:53.395874Z","shell.execute_reply":"2024-05-27T02:30:53.399398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Config","metadata":{}},{"cell_type":"code","source":"DEBUG = False\n\nclass CFG:\n    seed = 42\n#     model_name = 'tf_efficientnet_b4_ns'\n#     model_name = 'tf_efficientnet_b6_ns'\n#     model_name = 'tf_efficientnetv2_s_in21k'\n    model_name = 'tf_efficientnet_b0_ns'\n    pretrained = True\n    img_size = 512\n    num_classes = 100\n    lr = 1e-5\n    max_lr = 1e-3\n    pct_start = 0.2\n    div_factor = 1.0e+3\n    final_div_factor = 1.0e+3\n    num_epochs = 40\n    batch_size = 16\n    accum = 1\n    precision = 16\n    n_fold = 4\n    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:44.285689Z","iopub.execute_input":"2024-05-27T02:31:44.285994Z","iopub.status.idle":"2024-05-27T02:31:44.293426Z","shell.execute_reply.started":"2024-05-27T02:31:44.285961Z","shell.execute_reply":"2024-05-27T02:31:44.292601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seed_everything(CFG.seed)\nimg = cv2.imread(\"../input/sorghum-id-fgvc-9/train_images/2017-06-01__10-26-27-479.png\")\nprint(img.shape)","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:44.565064Z","iopub.execute_input":"2024-05-27T02:31:44.565313Z","iopub.status.idle":"2024-05-27T02:31:44.597050Z","shell.execute_reply.started":"2024-05-27T02:31:44.565286Z","shell.execute_reply":"2024-05-27T02:31:44.596263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PATH = \"../input/sorghum-id-fgvc-9/\"\n\nTRAIN_DIR = PATH + 'train_images/'\n# TRAIN_DIR = \"../input/sorghum-cultivar-identification-512512/train/\"\n# TRAIN_DIR = '../input/sorghum-cultivar-identification-256256/train/'\nTEST_DIR = PATH + 'test/'","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:44.790569Z","iopub.execute_input":"2024-05-27T02:31:44.791246Z","iopub.status.idle":"2024-05-27T02:31:44.795078Z","shell.execute_reply.started":"2024-05-27T02:31:44.791207Z","shell.execute_reply":"2024-05-27T02:31:44.794302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all = pd.read_csv(PATH + \"train_cultivar_mapping.csv\")\n# print(df_all.isna().loc[df_all.isna()[\"cultivar\"] == True])\ndf_all.dropna(inplace=True)\nprint(df_all.iloc[3328])\ndf_all.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:45.013849Z","iopub.execute_input":"2024-05-27T02:31:45.014468Z","iopub.status.idle":"2024-05-27T02:31:45.051710Z","shell.execute_reply.started":"2024-05-27T02:31:45.014436Z","shell.execute_reply":"2024-05-27T02:31:45.050968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unique_cultivars = list(df_all[\"cultivar\"].unique())\nnum_classes = len(unique_cultivars)\n\nCFG.num_classes = num_classes\nprint(num_classes)","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:45.238365Z","iopub.execute_input":"2024-05-27T02:31:45.238606Z","iopub.status.idle":"2024-05-27T02:31:45.245239Z","shell.execute_reply.started":"2024-05-27T02:31:45.238559Z","shell.execute_reply":"2024-05-27T02:31:45.244450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all[\"file_path\"] = df_all[\"image\"].apply(lambda image: TRAIN_DIR + image)\ndf_all[\"is_exist\"] = df_all[\"file_path\"].apply(lambda file_path: os.path.exists(file_path))\ndf_all = df_all[df_all.is_exist==True]\ndf_all.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:45.467267Z","iopub.execute_input":"2024-05-27T02:31:45.467480Z","iopub.status.idle":"2024-05-27T02:31:55.518022Z","shell.execute_reply.started":"2024-05-27T02:31:45.467454Z","shell.execute_reply":"2024-05-27T02:31:55.517313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all[\"cultivar_index\"] = df_all[\"cultivar\"].map(lambda item: unique_cultivars.index(item))\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.519461Z","iopub.execute_input":"2024-05-27T02:31:55.519681Z","iopub.status.idle":"2024-05-27T02:31:55.567808Z","shell.execute_reply.started":"2024-05-27T02:31:55.519655Z","shell.execute_reply":"2024-05-27T02:31:55.567118Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df_all.loc[df_all[\"is_exist\"]==False])","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.568771Z","iopub.execute_input":"2024-05-27T02:31:55.568978Z","iopub.status.idle":"2024-05-27T02:31:55.578986Z","shell.execute_reply.started":"2024-05-27T02:31:55.568952Z","shell.execute_reply":"2024-05-27T02:31:55.578314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if DEBUG == True:\n    df_all = df_all[:200]\n    CFG.num_epochs = 10","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.580668Z","iopub.execute_input":"2024-05-27T02:31:55.580876Z","iopub.status.idle":"2024-05-27T02:31:55.587343Z","shell.execute_reply.started":"2024-05-27T02:31:55.580851Z","shell.execute_reply":"2024-05-27T02:31:55.586624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# StratifiedKFold","metadata":{}},{"cell_type":"code","source":"skf = StratifiedKFold(n_splits=CFG.n_fold, shuffle=True, random_state=CFG.seed)\n\nfor train_idx, valid_idx in skf.split(df_all['image'], df_all[\"cultivar_index\"]):\n    df_train = df_all.iloc[train_idx]\n    df_valid = df_all.iloc[valid_idx]\n#     print(len(df_train))\n#     print(len(df_valid))\n#     print(f\"train size: {len(df_train)}\")\n#     print(df_valid)\n\n\n\n# print(df_train.cultivar.value_counts())\n# print(df_valid.cultivar.value_counts())\n\n\nprint(df_train.iloc[0][2])","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.588368Z","iopub.execute_input":"2024-05-27T02:31:55.588568Z","iopub.status.idle":"2024-05-27T02:31:55.614462Z","shell.execute_reply.started":"2024-05-27T02:31:55.588544Z","shell.execute_reply":"2024-05-27T02:31:55.613762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **计算均值和方差**","metadata":{}},{"cell_type":"code","source":"import torch\nfrom torchvision.datasets import ImageFolder\n\n\ndef getStat(train_data):\n    '''\n    Compute mean and variance for training data\n    :param train_data: 自定义类Dataset(或ImageFolder即可)\n    :return: (mean, std)\n    '''\n    print('Compute mean and variance for training data.')\n    print(len(train_data))\n    train_loader = torch.utils.data.DataLoader(\n        train_data, batch_size=1, shuffle=False, num_workers=0,\n        pin_memory=True)\n    mean = torch.zeros(3)\n    std = torch.zeros(3)\n    for X in train_loader:\n        for d in range(3):\n            X1 = X.get('image')\n            X1 = X1.float()\n            mean[d] += X1[:, :, :, d].mean()\n            std[d] += X1[:, :, :, d].std()\n    mean.div_(len(train_data))\n    std.div_(len(train_data))\n    return [round(i/255,4) for i in list(mean.numpy())], [round(i/255,4) for i in list(std.numpy())]\n\nclass MyDataset(Dataset):\n    def __init__(self, df, transform=None):\n        self.image_path = df['file_path'].values\n        self.labels = df[\"cultivar_index\"].values\n\n    def __len__(self):\n        return len(self.labels)\n\n    def __getitem__(self, idx):\n        image_path = self.image_path[idx]\n        image = cv2.imread(image_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        return {'image':image}\n\n# if __name__ == '__main__':\n#     train_dataset = MyDataset(df_all)\n#     print(getStat(train_dataset))\n    \n# train_dataset ([91.446175, 97.5628, 74.73816], [41.21325, 42.197006, 32.888214])\n# test  ([0.4006, 0.4237, 0.3203], [0.1812, 0.1842, 0.1457])\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.615346Z","iopub.execute_input":"2024-05-27T02:31:55.615528Z","iopub.status.idle":"2024-05-27T02:31:55.627256Z","shell.execute_reply.started":"2024-05-27T02:31:55.615505Z","shell.execute_reply":"2024-05-27T02:31:55.626621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define Dataset","metadata":{}},{"cell_type":"code","source":"class SorghumDataset(Dataset):\n    def __init__(self, df, transform=None):\n        self.image_path = df['file_path'].values\n        self.labels = df[\"cultivar_index\"].values\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.labels)\n\n    def __getitem__(self, idx):\n#         image_id = self.image_id[idx]\n        label = torch.tensor(self.labels[idx], dtype=torch.float32)\n        image_path = self.image_path[idx]\n        image = cv2.imread(image_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        \n        augmented = self.transform(image=image)\n        image = augmented['image']\n        return {'image':image, 'target': label}","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.628113Z","iopub.execute_input":"2024-05-27T02:31:55.628300Z","iopub.status.idle":"2024-05-27T02:31:55.639918Z","shell.execute_reply.started":"2024-05-27T02:31:55.628275Z","shell.execute_reply":"2024-05-27T02:31:55.639244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Augmant","metadata":{}},{"cell_type":"code","source":"def get_transform(phase: str):\n    if phase == 'train':\n        return Compose([\n            A.RandomResizedCrop(height=CFG.img_size, width=CFG.img_size),\n            A.Flip(p=0.5),\n            A.HorizontalFlip(p=0.5),\n            A.RandomRotate90(p=0.5),\n            A.ShiftScaleRotate(p=0.5),\n            A.HueSaturationValue(p=0.5),\n            A.OneOf([\n                A.RandomBrightnessContrast(p=0.5),\n                A.RandomGamma(p=0.5),\n            ], p=0.5),\n            A.OneOf([\n                A.Blur(p=0.1),\n                A.GaussianBlur(p=0.1),\n                A.MotionBlur(p=0.1),\n            ], p=0.1),\n            A.OneOf([\n                A.GaussNoise(p=0.1),\n                A.ISONoise(p=0.1),\n                A.GridDropout(ratio=0.5, p=0.2),\n                A.CoarseDropout(max_holes=16, min_holes=8, max_height=16, max_width=16, min_height=8, min_width=8, p=0.2)\n            ], p=0.2),\n            A.Normalize(\n#                 mean=[0.485, 0.456, 0.406],\n#                 std=[0.229, 0.224, 0.225],\n                mean=[0.359,0.383,0.293],\n                std=[0.162,0.165,0.129],\n            ),\n            ToTensorV2(),\n        ])\n    elif phase == 'valid':\n        return Compose([\n            A.Resize(height=CFG.img_size, width=CFG.img_size),\n            A.Normalize(\n#                 mean=[0.485, 0.456, 0.406],\n#                 std=[0.229, 0.224, 0.225],\n                mean=[0.359,0.383,0.293],\n                std=[0.162,0.165,0.129],\n            ),\n            ToTensorV2(),\n        ])\n    else:\n        return Compose([\n            A.Resize(height=CFG.img_size, width=CFG.img_size),\n            A.Normalize(\n#                 mean=[0.485, 0.456, 0.406],\n#                 std=[0.229, 0.224, 0.225],\n                mean=[0.401, 0.424, 0.320],\n                std=[0.181, 0.184, 0.146]\n            ),\n            ToTensorV2(),\n        ])","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.640865Z","iopub.execute_input":"2024-05-27T02:31:55.641054Z","iopub.status.idle":"2024-05-27T02:31:55.654366Z","shell.execute_reply.started":"2024-05-27T02:31:55.641029Z","shell.execute_reply":"2024-05-27T02:31:55.653661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = SorghumDataset(df_train, get_transform('train'))\nvalid_dataset = SorghumDataset(df_valid, get_transform('valid'))\n\nprint(len(train_dataset))\n\n\ntrain_loader = DataLoader(train_dataset, batch_size=CFG.batch_size, shuffle=True, pin_memory=True, drop_last=True, num_workers=4)\nvalid_loader = DataLoader(valid_dataset, batch_size=CFG.batch_size, shuffle=False, pin_memory=True, num_workers=4)\n# from sklearn.2_selection import train_test_split\n# X = df_all.drop([],)\n# X_train, X_valid, y_train, y_valid = train_test_split(X,y, train_size=0.8)","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.655479Z","iopub.execute_input":"2024-05-27T02:31:55.655961Z","iopub.status.idle":"2024-05-27T02:31:55.671282Z","shell.execute_reply.started":"2024-05-27T02:31:55.655924Z","shell.execute_reply":"2024-05-27T02:31:55.670629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CFG.steps_per_epoch = len(train_loader)\nCFG.steps_per_epoch","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.673414Z","iopub.execute_input":"2024-05-27T02:31:55.673627Z","iopub.status.idle":"2024-05-27T02:31:55.683886Z","shell.execute_reply.started":"2024-05-27T02:31:55.673599Z","shell.execute_reply":"2024-05-27T02:31:55.683193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define Model","metadata":{}},{"cell_type":"code","source":"#     Arcface网络结构：\nclass ArcNet(nn.Module):\n    def __init__(self, feature_num, cls_num):\n        super(ArcNet, self).__init__()\n        self.w = nn.Parameter(torch.randn((feature_num, cls_num)), requires_grad=True)\n\n    def forward(self, x, s=30, m=0.3):\n        x_norm = nn.functional.normalize(x, dim=1)\n        w_norm = nn.functional.normalize(self.w, dim=0)\n        cosa = torch.matmul(x_norm, w_norm) / s\n        a = torch.acos(cosa)\n        arcsoftmax = torch.exp(\n            s * torch.cos(a + m)) / (torch.sum(torch.exp(s * cosa), dim=1, keepdim=True) - torch.exp(\n            s * cosa) + torch.exp(s * torch.cos(a + m)))\n\n        return torch.log(arcsoftmax)\n\n#     InstanceNorm2d层\nclass in_InvertedResidual(nn.Module):\n    def __init__(self, model):\n        super(in_InvertedResidual, self).__init__()\n        self.model = model\n        self.IN = nn.InstanceNorm2d(model.bn3.num_features, affine=True, track_running_stats=True)\n        \n    def forward(self, x):\n        x = self.model(x)\n        x = self.IN(x)\n        return x\n\nclass head_in_InvertedResidual(nn.Module):\n    def __init__(self, num_features):\n        super(head_in_InvertedResidual, self).__init__()\n        self.IN = nn.InstanceNorm2d(num_features, affine=True, track_running_stats=True)\n        self.silu = nn.SiLU(inplace=True)\n        \n    def forward(self, x):\n        x = self.IN(x)\n        x = self.silu(x)\n        return x\n\nclass CustomEffNet(nn.Module):\n    def __init__(self, model_name='tf_efficientnet_b0_ns', pretrained=True):\n        super().__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        in_features = self.model.get_classifier().in_features\n        self.model.classifier = nn.Sequential(\n            nn.Linear(in_features, in_features),\n#             nn.ReLU(inplace=True),\n            nn.RReLU(inplace=True),\n            nn.Dropout(0.5),\n            ArcNet(in_features, CFG.num_classes)\n#             nn.Linear(in_features,CFG.num_classes)\n        )\n        \n    def forward(self, x):\n        x = self.model(x)\n        return x\n    \n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.685110Z","iopub.execute_input":"2024-05-27T02:31:55.685400Z","iopub.status.idle":"2024-05-27T02:31:55.702927Z","shell.execute_reply.started":"2024-05-27T02:31:55.685365Z","shell.execute_reply":"2024-05-27T02:31:55.702075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import timm\nfrom pprint import pprint\nmodel_names = timm.list_models(pretrained=True)\n# pprint(model_names)","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.703977Z","iopub.execute_input":"2024-05-27T02:31:55.704624Z","iopub.status.idle":"2024-05-27T02:31:55.718496Z","shell.execute_reply.started":"2024-05-27T02:31:55.704572Z","shell.execute_reply":"2024-05-27T02:31:55.717866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\nclass LitSorghum(pl.LightningModule):\n    def __init__(self, model):\n        super(LitSorghum, self).__init__()\n        self.model = model\n        self.metric = torchmetrics.Accuracy(threshold=0.5, num_classes=CFG.num_classes)\n#         self.criterion = nn.CrossEntropyLoss()\n        self.criterion = nn.NLLLoss()\n        self.lr = CFG.lr\n\n    def forward(self, x, *args, **kwargs):\n        return self.model(x)\n\n    def configure_optimizers(self):\n#         pg0, pg1, pg2 = [], [], []  # optimizer parameter groups\n#         for k, v in self.model.named_modules():\n#             if hasattr(v, 'weight') and isinstance(v.weight, nn.Parameter):\n#                 pg1.append(v.weight)  # apply decay\n# #             if isinstance(v, nn.BatchNorm2d):\n# #                 pg0.append(v.weight)  # no decay\n#             if hasattr(v, 'bias') and isinstance(v.bias, nn.Parameter):\n#                 pg2.append(v.bias)  # biases\n#         self.optimizer = torch.optim.Adam(params=pg2)\n#         self.optimizer.add_param_group({'params': pg1, 'weight_decay': 1e-5})  # add pg1 with weight_decay\n        self.optimizer = torch.optim.Adam(params=model.parameters())\n        self.scheduler = torch.optim.lr_scheduler.OneCycleLR(self.optimizer, \n                                                             epochs=CFG.num_epochs, steps_per_epoch=CFG.steps_per_epoch,\n                                                             max_lr=CFG.max_lr, pct_start=CFG.pct_start, \n                                                             div_factor=CFG.div_factor, final_div_factor=CFG.final_div_factor)\n#         self.scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(self.optimizer, mode='min', factor=0.1, patience=2)\n\n        scheduler = {'scheduler': self.scheduler, 'interval': 'step',}\n\n        return [self.optimizer], [scheduler]\n\n    def training_step(self, batch, batch_idx):\n        image = batch['image']\n        target = batch['target'].long()\n        output = self.model(image)\n        loss = self.criterion(output, target)\n        score = self.metric(output.argmax(1), target)\n        logs = {'train_loss': loss, 'train_acc': score, 'lr': self.optimizer.param_groups[0]['lr']}\n        self.log_dict(\n            logs,\n            on_step=False, on_epoch=True, prog_bar=True, logger=True\n        )\n        return loss\n    \n    def validation_step(self, batch, batch_idx):\n        image = batch['image']\n        target = batch['target'].long()\n        output = self.model(image)\n        loss = self.criterion(output, target)\n        score = self.metric(output.argmax(1), target)\n        logs = {'valid_loss': loss, 'valid_acc': score}\n        self.log_dict(\n            logs,\n            on_step=False, on_epoch=True, prog_bar=True, logger=True\n        )\n        return loss\n\n\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.719547Z","iopub.execute_input":"2024-05-27T02:31:55.719823Z","iopub.status.idle":"2024-05-27T02:31:55.734257Z","shell.execute_reply.started":"2024-05-27T02:31:55.719797Z","shell.execute_reply":"2024-05-27T02:31:55.733507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = CustomEffNet(model_name=CFG.model_name, pretrained=CFG.pretrained)\n\ndef model_structure(model):\n    blank = ' '\n    print('-' * 90)\n    print('|' + ' ' * 11 + 'weight name' + ' ' * 10 + '|' \\\n          + ' ' * 15 + 'weight shape' + ' ' * 15 + '|' \\\n          + ' ' * 3 + 'number' + ' ' * 3 + '|')\n    print('-' * 90)\n    num_para = 0\n    type_size = 1  # 如果是浮点数就是4\n\n    for index, (key, w_variable) in enumerate(model.named_parameters()):\n        if len(key) <= 30:\n            key = key + (30 - len(key)) * blank\n        shape = str(w_variable.shape)\n        if len(shape) <= 40:\n            shape = shape + (40 - len(shape)) * blank\n        each_para = 1\n        for k in w_variable.shape:\n            each_para *= k\n        num_para += each_para\n        str_num = str(each_para)\n        if len(str_num) <= 10:\n            str_num = str_num + (10 - len(str_num)) * blank\n\n#         print('| {} | {} | {} |'.format(key, shape, str_num))\n    print('-' * 90)\n    print('The total number of parameters: ' + str(num_para))\n    print('The parameters of Model {}: {:4f}M'.format(model._get_name(), num_para * type_size / 1000 / 1000))\n    print('-' * 90)\n\n# model_structure(model)\n# model.model.blocks[1][1]\n# model.model.blocks[2][1]\n# model.model.blocks[3][1]  \n# model.model.blocks[3][2] \n# model.model.blocks[4][1]  \n# model.model.blocks[4][2] \n# model.model.blocks[5][1]  \n# model.model.blocks[5][2] \n# model.model.blocks[5][3] \n\n\n# print(model.model.conv_head.out_channels)\n\n# print('------------------------****************************-----------------------------')\n# temp = [list(model.model.blocks[0][0].bn1.children())[0],nn.InstanceNorm2d(32, affine=True),list(model.model.blocks[0][0].bn1.children())[1]]\n# print(temp)\n# model.model.blocks[0][0].bn1=nn.Sequential(*temp)\n# print('------------------------****************************-----------------------------')\n# print(model.model.blocks[0][0])\n\n\n\n# print(model.model.bn2.children)\n# for name, param in model.named_modules():\n#     param.add_module()\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.735184Z","iopub.execute_input":"2024-05-27T02:31:55.735399Z","iopub.status.idle":"2024-05-27T02:31:55.935035Z","shell.execute_reply.started":"2024-05-27T02:31:55.735375Z","shell.execute_reply":"2024-05-27T02:31:55.934401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 未添加in模块的模型权重\ncheckpoint1 = \"/kaggle/input/b0-512-arcface300-3/epoch08-valid_loss12.5171-valid_acc0.9252.ckpt\"\nmodel.load_state_dict(torch.load(checkpoint1,map_location='cuda')['state_dict'])\n\n\n# 添加in模块\n# inblock_list = [[1,1],[2,1],[3,1],[3,2],[4,1],[4,2],[5,1],[5,2],[5,3]]\ninblock_list = [[1,1],[2,1]]\n\nfor i in inblock_list: \n#     print(model.model.blocks[i[0]][i[1]])\n    block_temp = in_InvertedResidual(model.model.blocks[i[0]][i[1]])\n    model.model.blocks[i[0]][i[1]] = block_temp \n\n\nmodel.model.bn1 = head_in_InvertedResidual(32)\n\n# checkpoint1 = \"/kaggle/working/last.ckpt\"\n# model.load_state_dict(torch.load(checkpoint1,map_location='cuda')['state_dict'])\n\n# print(model.model)\n# checkpoint1 = \"/kaggle/input/ibn2block/epoch27-valid_loss12.5402-valid_acc0.8825.ckpt\"\n# model.load_state_dict(torch.load(checkpoint1,map_location='cuda')['state_dict'])\n\n\n# print(model.model)\n# print(list(model.model.bn2.children()))\n# block_temp = in_InvertedResidual(model.model.blocks[5][3])\n# model.model.blocks[5][3] = block_temp  \n\n\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:55.936060Z","iopub.execute_input":"2024-05-27T02:31:55.936280Z","iopub.status.idle":"2024-05-27T02:31:56.038265Z","shell.execute_reply.started":"2024-05-27T02:31:55.936252Z","shell.execute_reply":"2024-05-27T02:31:56.037525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lit_model = LitSorghum(model.model)","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:56.039295Z","iopub.execute_input":"2024-05-27T02:31:56.039552Z","iopub.status.idle":"2024-05-27T02:31:56.044827Z","shell.execute_reply.started":"2024-05-27T02:31:56.039523Z","shell.execute_reply":"2024-05-27T02:31:56.044086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"logger = CSVLogger(save_dir='logs/', name=CFG.model_name)\nlogger.log_hyperparams(CFG.__dict__)\ncheckpoint_callback = ModelCheckpoint(monitor='valid_acc',\n                                      save_top_k=3,\n                                      save_last=True,\n                                      save_weights_only=True,\n                                      filename='{epoch:02d}-{valid_loss:.4f}-{valid_acc:.4f}',\n                                      verbose=True,\n                                      mode='max',\n                                      dirpath='./'\n                                     )\n\ntrainer = Trainer(\n    max_epochs=CFG.num_epochs,\n    gpus=[0],\n#     accelerator=\"auto\", \n#     devices=\"auto\",\n    accumulate_grad_batches=CFG.accum,\n    precision=CFG.precision,\n    callbacks=[checkpoint_callback], \n    logger=logger,\n    weights_summary='top',\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:56.045809Z","iopub.execute_input":"2024-05-27T02:31:56.046011Z","iopub.status.idle":"2024-05-27T02:31:56.064090Z","shell.execute_reply.started":"2024-05-27T02:31:56.045986Z","shell.execute_reply":"2024-05-27T02:31:56.063504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model.half() \n\n# torch.nn.Module.to()\n# from sklearn.ensemble import RandomForestClassifier\n# from sklearn.metrics import classification_report\n# from sklearn.model_selection import train_test_split\n# from tqdm import tqdm\n# import numpy as np\n\n\n# train_dataset1 = SorghumDataset(df_all, get_transform('train'))\n# train_loader1 = DataLoader(train_dataset1, batch_size=CFG.batch_size, shuffle=False, num_workers=2)\n\n# model.cuda()\n# model.eval()\n\n# predictions1 = []\n# predictions2 = []\n# for batch in tqdm(train_loader1):\n#     image = batch['image'].cuda()\n#     with torch.no_grad():\n#         outputs = model(image)\n#         preds = outputs.detach().cpu()\n#         predictions1.append(preds)\n# predictions2 = []\n# for i in range(0,len(predictions1)):\n#     for j in range(0,len(predictions1[i])):\n#         predictions2.append(np.array(predictions1[i][j]))\n# #     tmp = torch.cat((tmp, predictions1[i+1]))\n    \n# print(len(predictions2[0]))\n# X = predictions2\n# y = df_all[\"cultivar_index\"]\n# clf =RandomForestClassifier()\n\n# X_train, X_valid, y_train, y_valid = train_test_split(X,y, train_size=0.8)\n# clf.fit(X_train, y_train)\n# preds = clf.predict(X_valid)\n# print(clf.score(X_valid, y_valid))\n\n","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:56.065099Z","iopub.execute_input":"2024-05-27T02:31:56.065737Z","iopub.status.idle":"2024-05-27T02:31:56.073614Z","shell.execute_reply.started":"2024-05-27T02:31:56.065692Z","shell.execute_reply":"2024-05-27T02:31:56.072960Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"# filepath = './{epoch:02d}-{valid_loss:.4f}-{valid_acc:.4f}.h5'\n# if os.path.exists(filepath):\n#     model.load_weights(filepath) \n#     # 若成功加载前面保存的参数，输出下列信息\n#     print(\"checkpoint_loaded\")\ntrainer.fit(lit_model, train_dataloaders=train_loader, val_dataloaders=valid_loader)","metadata":{"execution":{"iopub.status.busy":"2024-05-27T02:31:56.074469Z","iopub.execute_input":"2024-05-27T02:31:56.074684Z","iopub.status.idle":"2024-05-27T02:32:15.701312Z","shell.execute_reply.started":"2024-05-27T02:31:56.074658Z","shell.execute_reply":"2024-05-27T02:32:15.700225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Result","metadata":{}},{"cell_type":"code","source":"metrics = pd.read_csv(f'{trainer.logger.log_dir}/metrics.csv')\n\ntrain_acc = metrics['train_acc'].dropna().reset_index(drop=True)\nvalid_acc = metrics['valid_acc'].dropna().reset_index(drop=True)\n    \nfig = plt.figure(figsize=(7, 6))\nplt.grid(True)\nplt.plot(train_acc, color=\"r\", marker=\"o\", label='train/acc')\nplt.plot(valid_acc, color=\"b\", marker=\"x\", label='valid/acc')\nplt.ylabel('Accuracy', fontsize=24)\nplt.xlabel('Epoch', fontsize=24)\nplt.legend(loc='lower right', fontsize=18)\nplt.savefig(f'{trainer.logger.log_dir}/acc.png')\n\ntrain_loss = metrics['train_loss'].dropna().reset_index(drop=True)\nvalid_loss = metrics['valid_loss'].dropna().reset_index(drop=True)\n\nfig = plt.figure(figsize=(7, 6))\nplt.grid(True)\nplt.plot(train_loss, color=\"r\", marker=\"o\", label='train/loss')\nplt.plot(valid_loss, color=\"b\", marker=\"x\", label='valid/loss')\nplt.ylabel('Loss', fontsize=24)\nplt.xlabel('Epoch', fontsize=24)\nplt.legend(loc='upper right', fontsize=18)\nplt.savefig(f'{trainer.logger.log_dir}/loss.png')\\\n\nlr = metrics['lr'].dropna().reset_index(drop=True)\n\nfig = plt.figure(figsize=(7, 6))\nplt.grid(True)\nplt.plot(lr, color=\"g\", marker=\"o\", label='learning rate')\nplt.ylabel('LR', fontsize=24)\nplt.xlabel('Epoch', fontsize=24)\nplt.legend(loc='upper right', fontsize=18)\nplt.savefig(f'{trainer.logger.log_dir}/lr.png')","metadata":{"execution":{"iopub.status.busy":"2024-05-26T06:14:53.356469Z","iopub.execute_input":"2024-05-26T06:14:53.356844Z","iopub.status.idle":"2024-05-26T06:14:54.419166Z","shell.execute_reply.started":"2024-05-26T06:14:53.356796Z","shell.execute_reply":"2024-05-26T06:14:54.418426Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Inference","metadata":{}},{"cell_type":"code","source":"!ls \"./logs/tf_efficientnet_b3_ns/version_0/checkpoints/\"","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:40:59.870301Z","iopub.execute_input":"2024-05-23T12:40:59.871089Z","iopub.status.idle":"2024-05-23T12:41:00.895051Z","shell.execute_reply.started":"2024-05-23T12:40:59.871046Z","shell.execute_reply":"2024-05-23T12:41:00.894073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1 = CustomEffNet(model_name=CFG.model_name, pretrained=False)\n\nfor i in inblock_list:\n    block_temp = in_InvertedResidual(model1.model.blocks[i[0]][i[1]])\n    model1.model.blocks[i[0]][i[1]] = block_temp  \n\n\nmodel1.model.bn1 = head_in_InvertedResidual(32)\n\n# checkpoint1 = \"/kaggle/input/effnetb0-512-30epoch-arcface/epoch29-valid_loss34.4232-valid_acc0.9097.ckpt\"\ncheckpoint1 = \"./last.ckpt\"\n# checkpoint1 = \"/kaggle/working/epoch=02-valid_loss=34.6081-valid_acc=0.6310.ckpt\"\nmodel1.load_state_dict(torch.load(checkpoint1,map_location='cuda')['state_dict'])","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:41:01.403298Z","iopub.execute_input":"2024-05-23T12:41:01.403661Z","iopub.status.idle":"2024-05-23T12:41:01.733544Z","shell.execute_reply.started":"2024-05-23T12:41:01.403619Z","shell.execute_reply":"2024-05-23T12:41:01.732827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.read_csv(PATH + \"sample_submission.csv\")\nsub.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:44:40.670330Z","iopub.execute_input":"2024-05-23T12:44:40.671088Z","iopub.status.idle":"2024-05-23T12:44:40.712365Z","shell.execute_reply.started":"2024-05-23T12:44:40.671051Z","shell.execute_reply":"2024-05-23T12:44:40.711609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub[\"file_path\"] = sub[\"filename\"].apply(lambda image: TEST_DIR + image)\nsub[\"cultivar_index\"] = 0\nsub.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:44:40.974872Z","iopub.execute_input":"2024-05-23T12:44:40.975534Z","iopub.status.idle":"2024-05-23T12:44:40.997623Z","shell.execute_reply.started":"2024-05-23T12:44:40.975495Z","shell.execute_reply":"2024-05-23T12:44:40.996736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = SorghumDataset(sub, get_transform('valid_true'))\ntest_loader = DataLoader(test_dataset, batch_size=CFG.batch_size, shuffle=False, num_workers=4)\n\n# # TTA\n# test_dataset_part1 = SorghumDataset(sub, get_transform('train'))\n# test_dataset_part2 = SorghumDataset(sub, get_transform('valid'))\n\n# test_loader_part1 = DataLoader(test_dataset_part1, batch_size=CFG.batch_size, shuffle=False, num_workers=4)\n# test_loader_part2 = DataLoader(test_dataset_part2, batch_size=CFG.batch_size, shuffle=False, num_workers=4)\n\n# from tqdm import tqdm\n\n# model1.cuda() \n# model1.eval()\n# predictions1 = []  \n# predictions2 = []  \n# predictions = []\n# for batch in tqdm(test_loader_part1):\n#     image = batch['image'].cuda()\n#     with torch.no_grad(): \n#         outputs = model1(image)\n#         preds = outputs.detach().cuda()\n#         predictions1.append(preds)\n\n# for batch in tqdm(test_loader_part2):\n#     image = batch['image'].cuda()\n#     with torch.no_grad(): \n#         outputs = model1(image)\n#         preds = outputs.detach().cuda()\n#         predictions2.append(preds)\n# for i1,i2 in predictions1,predictions2:\n#     p = []\n#     for i,j in i1,i2:\n#         t = (i+j)/2\n#         p.append(t)\n#     predictions.append(p.argmax(1))","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:44:41.297580Z","iopub.execute_input":"2024-05-23T12:44:41.297856Z","iopub.status.idle":"2024-05-23T12:44:41.304656Z","shell.execute_reply.started":"2024-05-23T12:44:41.297826Z","shell.execute_reply":"2024-05-23T12:44:41.303828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\n\nmodel1.cuda() \n# model1.cpu() \nmodel1.eval()\npredictions = []  \nfor batch in tqdm(test_loader):\n    image = batch['image'].cuda()\n#     image = batch['image'].cpu()\n    with torch.no_grad(): \n        outputs = model1(image)\n        preds = outputs.detach().cuda()\n#         preds = outputs.detach().cpu()\n        predictions.append(preds.argmax(1))","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:44:41.964597Z","iopub.execute_input":"2024-05-23T12:44:41.964896Z","iopub.status.idle":"2024-05-23T12:54:25.021624Z","shell.execute_reply.started":"2024-05-23T12:44:41.964859Z","shell.execute_reply":"2024-05-23T12:54:25.020710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tmp = predictions[0]\nfor i in range(len(predictions) - 1):\n    tmp = torch.cat((tmp, predictions[i+1]))","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:54:25.025821Z","iopub.execute_input":"2024-05-23T12:54:25.026094Z","iopub.status.idle":"2024-05-23T12:54:25.037694Z","shell.execute_reply.started":"2024-05-23T12:54:25.026058Z","shell.execute_reply":"2024-05-23T12:54:25.036944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = [unique_cultivars[pred] for pred in tmp]","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:54:25.038784Z","iopub.execute_input":"2024-05-23T12:54:25.039026Z","iopub.status.idle":"2024-05-23T12:54:25.342131Z","shell.execute_reply.started":"2024-05-23T12:54:25.038998Z","shell.execute_reply":"2024-05-23T12:54:25.341235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.read_csv(PATH + \"sample_submission.csv\")\nsub[\"cultivar\"] = predictions\nsub.to_csv('submission.csv', index=False)\nsub.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-23T12:54:25.344177Z","iopub.execute_input":"2024-05-23T12:54:25.344401Z","iopub.status.idle":"2024-05-23T12:54:25.454748Z","shell.execute_reply.started":"2024-05-23T12:54:25.344371Z","shell.execute_reply":"2024-05-23T12:54:25.453919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **模型结果融合**","metadata":{}},{"cell_type":"code","source":"# from tqdm import tqdm\n\n# model.cuda()\n# model.eval()\n# predictions3 = []\n# relist = []\n# m1_predictions,m2_predictions,m3_predictions = [],[],[]\n# for batch in tqdm(test_loader):\n#     image = batch['image'].cuda()\n#     with torch.no_grad():\n#         outputs = model(image)\n#         preds = outputs.detach().cpu()\n#         predictions3.append(preds)\n# # print(predictions3)\n# for i in range(0,len(predictions3)):\n#     for j in range(0,len(predictions3[i])):\n#         m1_predictions.append(np.array(predictions3[i][j]))\n# print(len(m1_predictions))\n# #predictions4、predictions5.....各个模型的output   size is testnumber*100\n# # predictions5 = predictions4\n# for i in range(0,len(m1_predictions)):\n#     re = []\n#     for j in range(0,100):\n#         #进行加权平均 得出最终预测结果\n# #         re.append(0.1*predictions4[i][j] + 0.3*predictions5[i][j]) \n#         re.append(m1_predictions[i][j])\n#     relist.append(re.index(max(re)))\n# print(relist)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predictions = [unique_cultivars[pred] for pred in relist]\n# sub = pd.read_csv(PATH + \"sample_submission.csv\")\n# sub[\"cultivar\"] = predictions\n# sub.to_csv('submission.csv', index=False)\n# sub.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predictions = [unique_cultivars[pred] for pred in relist]\n# sub = pd.read_csv(PATH + \"sample_submission.csv\")\n# sub[\"cultivar\"] = m1_predictions\n# sub.to_csv('m1_output.csv', index=False)\n# sub.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}