{"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":7312030,"sourceType":"datasetVersion","datasetId":4242957}],"dockerImageVersionId":30302,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Import Package","metadata":{"papermill":{"duration":0.010385,"end_time":"2022-11-15T22:55:44.567825","exception":false,"start_time":"2022-11-15T22:55:44.55744","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## Build Model","metadata":{"papermill":{"duration":0.014054,"end_time":"2022-11-15T22:55:50.078273","exception":false,"start_time":"2022-11-15T22:55:50.064219","status":"completed"},"tags":[]}},{"cell_type":"code","source":"! pip install timm\nimport timm\n\nmodel_names = timm.list_models()\nprint(model_names)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-02T01:59:25.672575Z","iopub.execute_input":"2024-01-02T01:59:25.673359Z","iopub.status.idle":"2024-01-02T01:59:42.899411Z","shell.execute_reply.started":"2024-01-02T01:59:25.673327Z","shell.execute_reply":"2024-01-02T01:59:42.898343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install git+https://github.com/ildoonet/cutmix ","metadata":{"execution":{"iopub.status.busy":"2024-01-02T01:59:42.901145Z","iopub.execute_input":"2024-01-02T01:59:42.901604Z","iopub.status.idle":"2024-01-02T01:59:57.685272Z","shell.execute_reply.started":"2024-01-02T01:59:42.901577Z","shell.execute_reply":"2024-01-02T01:59:57.684003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 安装ResNeSt模型包\n!pip install resnest --pre","metadata":{"execution":{"iopub.status.busy":"2024-01-02T01:59:57.68693Z","iopub.execute_input":"2024-01-02T01:59:57.687328Z","iopub.status.idle":"2024-01-02T02:00:13.99708Z","shell.execute_reply.started":"2024-01-02T01:59:57.687293Z","shell.execute_reply":"2024-01-02T02:00:13.995968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install scikit-learn\n","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:13.999704Z","iopub.execute_input":"2024-01-02T02:00:14.000089Z","iopub.status.idle":"2024-01-02T02:00:25.307339Z","shell.execute_reply.started":"2024-01-02T02:00:14.000056Z","shell.execute_reply":"2024-01-02T02:00:25.306119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! pip install ttach","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:25.308973Z","iopub.execute_input":"2024-01-02T02:00:25.309321Z","iopub.status.idle":"2024-01-02T02:00:37.110595Z","shell.execute_reply.started":"2024-01-02T02:00:25.30929Z","shell.execute_reply":"2024-01-02T02:00:37.109298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 导入各种包\nimport torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\nimport ttach as tta\nfrom resnest.torch import resnest50\n\nfrom cutmix.cutmix import CutMix\nfrom cutmix.utils import CutMixCrossEntropyLoss\n\nimport pandas as pd\nimport numpy as np\nfrom torch.utils.data import Dataset, DataLoader, TensorDataset\nfrom torchvision import transforms\nfrom torch.optim.lr_scheduler import CosineAnnealingLR\nfrom sklearn.model_selection import KFold\nfrom PIL import Image\nimport os\nimport matplotlib.pyplot as plt\nimport torchvision.models as models\n# This is for the progress bar.\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.112311Z","iopub.execute_input":"2024-01-02T02:00:37.112672Z","iopub.status.idle":"2024-01-02T02:00:37.584026Z","shell.execute_reply.started":"2024-01-02T02:00:37.11264Z","shell.execute_reply":"2024-01-02T02:00:37.583147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 看看label文件长啥样\nlabels_dataframe = pd.read_csv('/kaggle/input/classifyleaves/train.csv')\nlabels_dataframe.head(5)","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.585314Z","iopub.execute_input":"2024-01-02T02:00:37.585626Z","iopub.status.idle":"2024-01-02T02:00:37.641276Z","shell.execute_reply.started":"2024-01-02T02:00:37.5856Z","shell.execute_reply":"2024-01-02T02:00:37.640274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 把label文件排个序\nleaves_labels = sorted(list(set(labels_dataframe['label'])))\nn_classes = len(leaves_labels)\nprint(n_classes)\nleaves_labels[:10]","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.642525Z","iopub.execute_input":"2024-01-02T02:00:37.642814Z","iopub.status.idle":"2024-01-02T02:00:37.655768Z","shell.execute_reply.started":"2024-01-02T02:00:37.642788Z","shell.execute_reply":"2024-01-02T02:00:37.654698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 把label转成对应的数字\nclass_to_num = dict(zip(leaves_labels, range(n_classes)))\nclass_to_num","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.657244Z","iopub.execute_input":"2024-01-02T02:00:37.657641Z","iopub.status.idle":"2024-01-02T02:00:37.675439Z","shell.execute_reply.started":"2024-01-02T02:00:37.657601Z","shell.execute_reply":"2024-01-02T02:00:37.674321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 再转换回来，方便最后预测的时候使用\nnum_to_class = {v : k for k, v in class_to_num.items()}\nnum_to_class","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.680357Z","iopub.execute_input":"2024-01-02T02:00:37.680657Z","iopub.status.idle":"2024-01-02T02:00:37.693667Z","shell.execute_reply.started":"2024-01-02T02:00:37.680629Z","shell.execute_reply":"2024-01-02T02:00:37.692716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 继承pytorch的dataset，创建自己的\nclass TrainValidData(Dataset):\n    def __init__(self, csv_path, file_path, resize_height=224, resize_width=224, transform=None):\n        \"\"\"\n        Args:\n            csv_path (string): csv 文件路径\n            img_path (string): 图像文件所在路径\n\n        \"\"\"\n        \n        # 需要调整后的照片尺寸，我这里每张图片的大小尺寸不一致#\n        self.resize_height = resize_height\n        self.resize_width = resize_width\n\n        self.file_path = file_path\n        self.to_tensor = transforms.ToTensor() #将数据转换成tensor形式\n        self.transform = transform\n\n        # 读取 csv 文件\n        # 利用pandas读取csv文件\n        self.data_info = pd.read_csv(csv_path, header=None)  #header=None是去掉表头部分\n        # 文件第一列包含图像文件名称\n        self.image_arr = np.asarray(self.data_info.iloc[1:,0]) #self.data_info.iloc[1:,0]表示读取第一列，从第二行开始一直读取到最后一行\n        # 第二列是图像的 label\n        self.label_arr = np.asarray(self.data_info.iloc[1:,1])\n        # 计算 length\n        self.data_len = len(self.data_info.index) - 1\n    def __getitem__(self, index):\n        # 从 image_arr中得到索引对应的文件名\n        single_image_name = self.image_arr[index]\n\n        # 读取图像文件\n        img_as_img = Image.open(self.file_path + single_image_name)\n        \n        #如果需要将RGB三通道的图片转换成灰度图片可参考下面两行\n        # if img_as_img.mode != 'L':\n        #     img_as_img = img_as_img.convert('L')\n        \n        #设置好需要转换的变量，还可以包括一系列的nomarlize等等操作\n        transform = transforms.Compose([\n            transforms.Resize((224, 224)),\n            transforms.ToTensor()\n        ])\n        img_as_img = transform(img_as_img)\n\n        # 得到图像的 label\n        label = self.label_arr[index]\n        number_label = class_to_num[label]\n\n        return (img_as_img, number_label)  #返回每一个index对应的图片数据和对应的label\n\n    def __len__(self):\n        return self.data_len\n# 继承pytorch的dataset，创建自己的\nclass TestData(Dataset):\n    def __init__(self, csv_path, file_path, resize_height=224, resize_width=224, transform = None):\n        \"\"\"\n        Args:\n            csv_path (string): csv 文件路径\n            img_path (string): 图像文件所在路径\n\n        \"\"\"\n        \n        # 需要调整后的照片尺寸，我这里每张图片的大小尺寸不一致#\n        self.resize_height = resize_height\n        self.resize_width = resize_width\n\n        self.file_path = file_path\n        self.transform = transform\n        self.to_tensor = transforms.ToTensor() #将数据转换成tensor形式\n\n        # 读取 csv 文件\n        # 利用pandas读取csv文件\n        self.data_info = pd.read_csv(csv_path, header=None)  #header=None是去掉表头部分\n        # 文件第一列包含图像文件名称\n        self.image_arr = np.asarray(self.data_info.iloc[1:,0]) #self.data_info.iloc[1:,0]表示读取第一列，从第二行开始一直读取到最后一行\n        # 计算 length\n        self.data_len = len(self.data_info.index) - 1\n        \n    def __getitem__(self, index):\n        # 从 image_arr中得到索引对应的文件名\n        single_image_name = self.image_arr[index]\n\n        # 读取图像文件\n        img_as_img = Image.open(self.file_path + single_image_name)\n        \n        #如果需要将RGB三通道的图片转换成灰度图片可参考下面两行\n        # if img_as_img.mode != 'L':\n        #     img_as_img = img_as_img.convert('L')\n        \n        #设置好需要转换的变量，还可以包括一系列的nomarlize等等操作\n        transform = transforms.Compose([\n            transforms.Resize((224, 224)),\n            transforms.ToTensor()\n        ])\n        img_as_img = transform(img_as_img)\n\n\n        return img_as_img\n\n    def __len__(self):\n        return self.data_len","metadata":{"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-01-02T02:00:37.695031Z","iopub.execute_input":"2024-01-02T02:00:37.695379Z","iopub.status.idle":"2024-01-02T02:00:37.71512Z","shell.execute_reply.started":"2024-01-02T02:00:37.695342Z","shell.execute_reply":"2024-01-02T02:00:37.714011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transform = transforms.Compose([\n    # 随机裁剪图像，所得图像为原始面积的0.08到1之间，高宽比在3/4和4/3之间。\n    # 然后，缩放图像以创建224 x 224的新图像\n    transforms.RandomResizedCrop(224, scale=(0.08, 1.0), ratio=(3.0 / 4.0, 4.0 / 3.0)),\n    transforms.RandomHorizontalFlip(),\n    # 随机更改亮度，对比度和饱和度\n    transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4),\n    # 添加随机噪声\n    transforms.ToTensor(),\n    # 标准化图像的每个通道\n    transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])])\nval_test_transform = transforms.Compose([\n    transforms.Resize(256),\n    # 从图像中心裁切224x224大小的图片\n    transforms.CenterCrop(224),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])])","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.71654Z","iopub.execute_input":"2024-01-02T02:00:37.71685Z","iopub.status.idle":"2024-01-02T02:00:37.728809Z","shell.execute_reply.started":"2024-01-02T02:00:37.716821Z","shell.execute_reply":"2024-01-02T02:00:37.72778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TrainValidData(Dataset):\n    def __init__(self, csv_path, file_path, resize_height=224, resize_width=224, transform=None):\n        \"\"\"\n        Args:\n            csv_path (string): csv 文件路径\n            img_path (string): 图像文件所在路径\n\n        \"\"\"\n        \n        # 需要调整后的照片尺寸，我这里每张图片的大小尺寸不一致#\n        self.resize_height = resize_height\n        self.resize_width = resize_width\n\n        self.file_path = file_path\n        self.to_tensor = transforms.ToTensor() #将数据转换成tensor形式\n        self.transform = transform\n\n        # 读取 csv 文件\n        # 利用pandas读取csv文件\n        self.data_info = pd.read_csv(csv_path, header=None)  #header=None是去掉表头部分\n        # 文件第一列包含图像文件名称\n        self.image_arr = np.asarray(self.data_info.iloc[1:,0]) #self.data_info.iloc[1:,0]表示读取第一列，从第二行开始一直读取到最后一行\n        # 第二列是图像的 label\n        self.label_arr = np.asarray(self.data_info.iloc[1:,1])\n        # 计算 length\n        self.data_len = len(self.data_info.index) - 1\n\n    def __getitem__(self, index):\n        # 从 image_arr中得到索引对应的文件名\n        single_image_name = self.image_arr[index]\n\n        # 读取图像文件\n        img_as_img = Image.open(self.file_path + single_image_name)\n        \n        #如果需要将RGB三通道的图片转换成灰度图片可参考下面两行\n        # if img_as_img.mode != 'L':\n        #     img_as_img = img_as_img.convert('L')\n        \n        #设置好需要转换的变量，还可以包括一系列的nomarlize等等操作\n        transform = transforms.Compose([\n            transforms.Resize((224, 224)),\n            transforms.ToTensor()\n        ])\n        img_as_img = transform(img_as_img)\n\n        # 得到图像的 label\n        label = self.label_arr[index]\n        number_label = class_to_num[label]\n\n        return (img_as_img, number_label)  #返回每一个index对应的图片数据和对应的label\n\n    def __len__(self):\n        return self.data_len\n# 继承pytorch的dataset，创建自己的\nclass TestData(Dataset):\n    def __init__(self, csv_path, file_path, resize_height=224, resize_width=224, transform = None):\n        \"\"\"\n        Args:\n            csv_path (string): csv 文件路径\n            img_path (string): 图像文件所在路径\n\n        \"\"\"\n        \n        # 需要调整后的照片尺寸，我这里每张图片的大小尺寸不一致#\n        self.resize_height = resize_height\n        self.resize_width = resize_width\n\n        self.file_path = file_path\n        self.transform = transform\n        self.to_tensor = transforms.ToTensor() #将数据转换成tensor形式\n\n        # 读取 csv 文件\n        # 利用pandas读取csv文件\n        self.data_info = pd.read_csv(csv_path, header=None)  #header=None是去掉表头部分\n        # 文件第一列包含图像文件名称\n        self.image_arr = np.asarray(self.data_info.iloc[1:,0]) #self.data_info.iloc[1:,0]表示读取第一列，从第二行开始一直读取到最后一行\n        # 计算 length\n        self.data_len = len(self.data_info.index) - 1\n        \n    def __getitem__(self, index):\n        # 从 image_arr中得到索引对应的文件名\n        single_image_name = self.image_arr[index]\n\n        # 读取图像文件\n        img_as_img = Image.open(self.file_path + single_image_name)\n        \n        #如果需要将RGB三通道的图片转换成灰度图片可参考下面两行\n        # if img_as_img.mode != 'L':\n        #     img_as_img = img_as_img.convert('L')\n        \n        #设置好需要转换的变量，还可以包括一系列的nomarlize等等操作\n        transform = transforms.Compose([\n            transforms.Resize((224, 224)),\n            transforms.ToTensor()\n        ])\n        img_as_img = transform(img_as_img)\n\n\n        return img_as_img\n\n    def __len__(self):\n        return self.data_len","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.730446Z","iopub.execute_input":"2024-01-02T02:00:37.73078Z","iopub.status.idle":"2024-01-02T02:00:37.749975Z","shell.execute_reply.started":"2024-01-02T02:00:37.730751Z","shell.execute_reply":"2024-01-02T02:00:37.748925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_val_path = '/kaggle/input/classifyleaves/train.csv'\ntest_path = '/kaggle/input/classifyleaves/test.csv'\nimg_path = '/kaggle/input/classifyleaves/'","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.751405Z","iopub.execute_input":"2024-01-02T02:00:37.75176Z","iopub.status.idle":"2024-01-02T02:00:37.763314Z","shell.execute_reply.started":"2024-01-02T02:00:37.75173Z","shell.execute_reply":"2024-01-02T02:00:37.762371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_val_dataset = TrainValidData(train_val_path, img_path)\ntest_dataset = TestData(test_path, img_path, transform = val_test_transform)\nprint(train_val_dataset.data_info)\nprint(test_dataset.data_info)","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.764338Z","iopub.execute_input":"2024-01-02T02:00:37.764641Z","iopub.status.idle":"2024-01-02T02:00:37.818733Z","shell.execute_reply.started":"2024-01-02T02:00:37.764614Z","shell.execute_reply":"2024-01-02T02:00:37.817611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.819903Z","iopub.execute_input":"2024-01-02T02:00:37.820239Z","iopub.status.idle":"2024-01-02T02:00:37.825228Z","shell.execute_reply.started":"2024-01-02T02:00:37.82021Z","shell.execute_reply":"2024-01-02T02:00:37.823913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device=torch.device('cuda')","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.826564Z","iopub.execute_input":"2024-01-02T02:00:37.826856Z","iopub.status.idle":"2024-01-02T02:00:37.836084Z","shell.execute_reply.started":"2024-01-02T02:00:37.826829Z","shell.execute_reply":"2024-01-02T02:00:37.835137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 是否要冻住模型的前面一些层\ndef set_parameter_requires_grad(model, feature_extracting):\n    if feature_extracting:\n        model = model\n        for param in model.parameters():\n            param.requires_grad = False\nclass ModifiedEfficientNet(nn.Module):\n    def __init__(self):\n        super(ModifiedEfficientNet, self).__init__()\n        model = timm.create_model('tf_efficientnetv2_m', pretrained=True)  # Load pre-trained EfficientNet model\n        \n        # Access the classifier head from the last layer of the model\n        classifier_head = model.classifier\n        \n        # Identify the input features of the classifier head\n        in_features = classifier_head.in_features\n        \n        # Replace the classifier head with a new linear layer with 176 output features\n        linear_layer = nn.Linear(in_features, 176)  # Replace 176 with the desired output size\n        model.classifier = linear_layer\n        \n        self.model = model\n\n        # Freeze layers if needed\n        for param in self.model.parameters():\n            param.requires_grad = False  # Freeze all parameters except the modified head\n\n        # Unfreeze the modified head for fine-tuning\n        for param in self.model.classifier.parameters():\n            param.requires_grad = True\n\n    def forward(self, x):\n        return self.model(x)\n\n# Create an instance of the modified model\nmodel = ModifiedEfficientNet()","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:37.837217Z","iopub.execute_input":"2024-01-02T02:00:37.837525Z","iopub.status.idle":"2024-01-02T02:00:52.491976Z","shell.execute_reply.started":"2024-01-02T02:00:37.837499Z","shell.execute_reply":"2024-01-02T02:00:52.490834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.to(device)\nprint(f\"number of paramaters: {sum([param.numel() for param in model.parameters() if param.requires_grad])}\")","metadata":{"papermill":{"duration":118.283643,"end_time":"2022-11-15T22:57:48.411541","exception":false,"start_time":"2022-11-15T22:55:50.127898","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-01-02T02:00:52.493462Z","iopub.execute_input":"2024-01-02T02:00:52.493845Z","iopub.status.idle":"2024-01-02T02:00:55.568409Z","shell.execute_reply.started":"2024-01-02T02:00:52.493808Z","shell.execute_reply":"2024-01-02T02:00:55.567385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Configuration options\nk_folds = 5","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:00:55.569608Z","iopub.execute_input":"2024-01-02T02:00:55.569908Z","iopub.status.idle":"2024-01-02T02:00:55.575738Z","shell.execute_reply.started":"2024-01-02T02:00:55.569879Z","shell.execute_reply":"2024-01-02T02:00:55.574704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_epochs = 30\nlearning_rate = 1e-1\nweight_decay = 1e-3\ntrain_loss_function = CutMixCrossEntropyLoss(True)\nvalid_loss_function = nn.CrossEntropyLoss()\n# For fold results\nresults = {}\n\n# Set fixed random number seed\ntorch.manual_seed(42)\n\n# Define the K-fold Cross Validator\nkfold = KFold(n_splits=k_folds, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:32:23.267674Z","iopub.execute_input":"2024-01-02T02:32:23.268421Z","iopub.status.idle":"2024-01-02T02:32:23.275141Z","shell.execute_reply.started":"2024-01-02T02:32:23.268384Z","shell.execute_reply":"2024-01-02T02:32:23.273996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_trainloss = pd.DataFrame(np.zeros((30,5)),columns=['一折交叉验证训练损失', '二折交叉验证训练损失', \n                                       '三折交叉验证训练损失', '四折交叉验证训练损失', '五折交叉验证训练损失'])\ndata_trainacc = pd.DataFrame(np.zeros((30,5)),columns=['一折交叉验证训练精确度', '二折交叉验证训练精确度',\n                            '三折交叉验证训练精确度', '四折交叉验证训练精确度', '五折交叉验证训练精确度'])\ndata_lr = pd.DataFrame(np.zeros((30,5)),columns=['一折交叉验证训练学习率', '二折交叉验证训练学习率',\n                            '三折交叉验证训练学习率', '四折交叉验证训练学习率', '五折交叉验证训练学习率'])\ndata_volidloss = pd.DataFrame(np.zeros((30,5)),columns=['一折交叉验证验证损失', '二折交叉验证验证损失', \n                                       '三折交叉验证验证损失', '四折交叉验证验证损失', '五折交叉验证验证损失'])\ndata_volidacc = pd.DataFrame(np.zeros((30,5)),columns=['一折交叉验证验证精确度', '二折交叉验证验证精确度',\n                            '三折交叉验证验证精确度', '四折交叉验证验证精确度', '五折交叉验证验证精确度'])","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:36.343165Z","iopub.execute_input":"2024-01-02T02:03:36.343887Z","iopub.status.idle":"2024-01-02T02:03:36.354785Z","shell.execute_reply.started":"2024-01-02T02:03:36.343851Z","shell.execute_reply":"2024-01-02T02:03:36.353679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Start print\nprint('--------------------------------------')\n# K-fold Cross Validation model evaluation\nfor fold, (train_ids,valid_ids) in enumerate(kfold.split(train_val_dataset)):\n\n  # Print\n  print(f'FOLD {fold}')\n  print('--------------------------------------')\n\n  # Sample elements randomly from a given list of ids, no replacement.\n  train_subsampler = torch.utils.data.SubsetRandomSampler(train_ids)\n  valid_subsampler = torch.utils.data.SubsetRandomSampler(valid_ids)\n\n  # Define data loaders for training and testing data in this fold\n  trainloader = torch.utils.data.DataLoader(\n                      CutMix(TrainValidData(train_val_path, img_path, transform = train_transform), num_class=176, beta=1.0, prob=0.5, num_mix=2), \n                      batch_size=32,pin_memory=True,sampler=train_subsampler, num_workers=4)###\n  validloader = torch.utils.data.DataLoader(\n                      TrainValidData(train_val_path, img_path, transform = val_test_transform),\n                      batch_size=32, pin_memory=True,sampler=valid_subsampler, num_workers=4)###\n  \n  # Initialize a model and put it on the device specified.\n  #print(\"GPU or CPU is available: \", device)\n  #if torch.cuda.device_count() > 1:  # multi-gpu\n            #print('Lets use', torch.cuda.device_count(), 'GPUs!')\n  #model = nn.DataParallel(model)\n  model = model.to(device)\n  #model = nn.DataParallel(model,device_ids=[0,1,2,3,4,5,6])\n  #device = model.device\n  optimizer = torch.optim.AdamW(model.parameters(),lr=learning_rate,weight_decay= weight_decay)\n  scheduler = CosineAnnealingLR(optimizer,T_max=10)\n  # Run the training loop for defined number of epochs\n  for epoch in range(0,num_epochs):\n    model.train()\n    print(f'Starting epoch {epoch+1}')\n    # These are used to record information in training\n    train_losses = []\n    train_accs = []\n    # Iterate the training set by batches\n    for batch in tqdm(trainloader):\n      # Move images and labels to GPU\n      imgs, labels = batch\n      logits = model(imgs.to(device))\n      loss = train_loss_function(logits,labels.to(device))\n      # Clear gradients in previous step\n      optimizer.zero_grad()\n      # Compute gradients for parameters\n      loss.backward()\n      # Update the parameters with computed gradients\n      optimizer.step()\n      # Compute the accuracy for current batch.\n      acc = (logits.argmax(dim=-1) == labels.to(device).argmax(dim=-1)).float().mean()\n      # Record the loss and accuracy.\n      train_losses.append(loss.item())\n      train_accs.append(acc)\n    print(\"第%d个epoch的学习率：%f\" % (epoch+1,optimizer.param_groups[0]['lr']))\n    scheduler.step()\n    # The average loss and accuracy of the training set is the average of the recorded values.\n    train_loss = np.sum(train_losses) / len(train_losses)\n    train_acc = np.sum(torch.tensor(train_accs).cpu().numpy())/len(torch.tensor(train_accs).cpu().numpy())\n    # Print the information.\n    print(f\"[ Train | {epoch + 1:03d}/{num_epochs:03d} ] loss = {train_loss:.5f}, acc = {train_acc:.5f}\")\n    #print(f\"[ Train | {epoch + 1:03d}/{num_epochs:03d} ] loss = {train_loss:.5f}\")\n    data_trainloss.iloc[epoch,fold]=train_loss\n    data_trainacc.iloc[epoch,fold]=train_acc\n    data_lr.iloc[epoch,fold]=optimizer.param_groups[0]['lr']\n  # Train process (all epochs) is complete\n  print('Training process has finished. Saving trained model.')\n  print('Starting validation')\n\n  # Saving the model\n  print('saving model with loss {:.3f}'.format(train_loss))\n  save_path = f'./convnextv2_huge-model-fold-{fold}.pth'\n  torch.save(model.state_dict(),save_path)\n  # Start Validation\n  model.eval()\n  valid_losses = []\n  valid_accs = []\n  with torch.no_grad():\n    for batch in tqdm(validloader):\n          imgs, labels = batch\n          # No gradient in validation\n          logits = model(imgs.to(device))\n          loss = valid_loss_function(logits,labels.to(device))\n          acc = (logits.argmax(dim=-1) == labels.to(device)).float().mean()\n          # Record loss and accuracy\n          valid_losses.append(loss.item())        \n          valid_accs.append(acc)      \n    # The average loss and accuracy\n    valid_loss = np.sum(valid_losses)/len(valid_losses)\n    valid_acc = np.sum(torch.tensor(valid_accs).cpu().numpy())/len(torch.tensor(valid_accs).cpu().numpy())\n    print(f\"[ Valid | {epoch + 1:03d}/{num_epochs:03d} ] loss = {valid_loss:.5f}, acc = {valid_acc:.5f}\")\n    print('Accuracy for fold {}:{}'.format(fold, valid_acc))\n    print('--------------------------------------')\n    results[fold] = valid_acc\n# Print fold results\nprint(f'K-FOLD CROSS VALIDATION RESULTS FOR {k_folds} FOLDS')\nprint('--------------------------------')\ntotal_summation = 0.0\nfor key, value in results.items():\n  print(f'Fold {key}: {value} ')\n  total_summation += value\nprint(f'Average: {total_summation/len(results.items())} ')","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:32:26.152678Z","iopub.execute_input":"2024-01-02T02:32:26.1536Z","iopub.status.idle":"2024-01-02T03:13:49.011475Z","shell.execute_reply.started":"2024-01-02T02:32:26.15356Z","shell.execute_reply":"2024-01-02T03:13:49.010066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"testloader = torch.utils.data.DataLoader(\n                      TestData(test_path, img_path, transform = val_test_transform),\n                      batch_size=32, num_workers=0)","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.433473Z","iopub.status.idle":"2024-01-02T02:03:08.434341Z","shell.execute_reply.started":"2024-01-02T02:03:08.434056Z","shell.execute_reply":"2024-01-02T02:03:08.434082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# create model and load weights from checkpoint\nmodel = model.to(device)\n# load the all folds\nfor test_fold in range(k_folds):\n  model_path = f'./convnextv2_huge-model-fold-{test_fold}.pth'\n  saveFileName = f'./convnextv2_huge-submission-fold-{test_fold}.csv'\n  #model.load_state_dict(torch.load(model_path))\n  model.load_state_dict(torch.load(model_path), False)###\n  # Make sure the model is in eval mode.\n  # Some modules like Dropout or BatchNorm affect if the model is in training mode.\n  model.eval()\n  tta_model = tta.ClassificationTTAWrapper(model, tta.aliases.five_crop_transform(200,200))\n\n  # Initialize a list to store the predictions.\n  predictions = []\n  # Iterate the testing set by batches.\n  for batch in tqdm(testloader):\n      \n      imgs = batch\n      with torch.no_grad():\n          logits = tta_model(imgs.to(device))\n      \n      # Take the class with greatest logit as prediction and record it.\n      predictions.extend(logits.argmax(dim=-1).cpu().numpy().tolist())\n\n  preds = []\n  for i in predictions:\n        preds.append(num_to_class[i])\n\n  test_data = pd.read_csv(test_path)\n  test_data['label'] = pd.Series(preds)\n  submission = pd.concat([test_data['image'], test_data['label']], axis=1)\n  submission.to_csv(saveFileName, index=False)\n  print(\"convnextv2_huge Model Results Done!!!!!!!!!!!!!!!!!!!!!!!!!!!\")","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.436135Z","iopub.status.idle":"2024-01-02T02:03:08.437166Z","shell.execute_reply.started":"2024-01-02T02:03:08.436892Z","shell.execute_reply":"2024-01-02T02:03:08.436918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.DataFrame(torch.tensor(valid_accs).cpu().numpy()).to_csv('convnextv2_huge各批次acc')\npd.DataFrame(valid_losses).to_csv('convnextv2_huge 验证误差')\ndata_trainloss.to_csv('convnextv2_huge交叉验证误差')\ndata_trainacc.to_csv('convnextv2_huge交叉验证准确率')\ndata_lr.to_csv('convnextv2_huge交叉验证学习率')","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.438727Z","iopub.status.idle":"2024-01-02T02:03:08.439668Z","shell.execute_reply.started":"2024-01-02T02:03:08.439401Z","shell.execute_reply":"2024-01-02T02:03:08.439427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\ndf0 = pd.read_csv('./convnextv2_huge-submission-fold-0.csv')\ndf1 = pd.read_csv('./convnextv2_huge-submission-fold-1.csv')\ndf2 = pd.read_csv('./convnextv2_hugesubmission-fold-2.csv')\ndf3 = pd.read_csv('./convnextv2_huge-submission-fold-3.csv')\ndf4 = pd.read_csv('./convnextv2_huge-submission-fold-4.csv')","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.44123Z","iopub.status.idle":"2024-01-02T02:03:08.442528Z","shell.execute_reply.started":"2024-01-02T02:03:08.442248Z","shell.execute_reply":"2024-01-02T02:03:08.442275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list_num_label0 = []\nfor i in df0['label']:\n  list_num_label0.append(class_to_num[i])\ndf0['num_label0']=list_num_label0\nlist_num_label1 = []\nfor i in df1['label']:\n  list_num_label1.append(class_to_num[i])\ndf1['num_label1']=list_num_label1\nlist_num_label2 = []\nfor i in df2['label']:\n  list_num_label2.append(class_to_num[i])\ndf2['num_label2']=list_num_label2\nlist_num_label3 = []\nfor i in df3['label']:\n  list_num_label3.append(class_to_num[i])\ndf3['num_label3']=list_num_label3\nlist_num_label4 = []\nfor i in df4['label']:\n  list_num_label4.append(class_to_num[i])\ndf4['num_label4']=list_num_label4","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.443996Z","iopub.status.idle":"2024-01-02T02:03:08.445154Z","shell.execute_reply.started":"2024-01-02T02:03:08.444861Z","shell.execute_reply":"2024-01-02T02:03:08.444887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all = df0.copy()\ndf_all.drop(['label'],axis=1,inplace=True)\ndf_all.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.446358Z","iopub.status.idle":"2024-01-02T02:03:08.446825Z","shell.execute_reply.started":"2024-01-02T02:03:08.446589Z","shell.execute_reply":"2024-01-02T02:03:08.44661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all['num_label1']=list_num_label1\ndf_all['num_label2']=list_num_label2\ndf_all['num_label3']=list_num_label3\ndf_all['num_label4']=list_num_label4\ndf_all.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.448485Z","iopub.status.idle":"2024-01-02T02:03:08.448953Z","shell.execute_reply.started":"2024-01-02T02:03:08.448707Z","shell.execute_reply":"2024-01-02T02:03:08.448729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all_transpose = df_all.copy().drop(['image'],axis=1).transpose()\ndf_all_transpose.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.45015Z","iopub.status.idle":"2024-01-02T02:03:08.450659Z","shell.execute_reply.started":"2024-01-02T02:03:08.450421Z","shell.execute_reply":"2024-01-02T02:03:08.450445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_mode = df_all_transpose.mode().transpose()","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.452029Z","iopub.status.idle":"2024-01-02T02:03:08.452495Z","shell.execute_reply.started":"2024-01-02T02:03:08.452239Z","shell.execute_reply":"2024-01-02T02:03:08.45227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"voting_class = []\nfor each in df_mode[0]:\n  voting_class.append(num_to_class[each])\nvoting_class","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.453674Z","iopub.status.idle":"2024-01-02T02:03:08.45416Z","shell.execute_reply.started":"2024-01-02T02:03:08.453881Z","shell.execute_reply":"2024-01-02T02:03:08.453902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_all['label'] = voting_class\ndf_all.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.455327Z","iopub.status.idle":"2024-01-02T02:03:08.455761Z","shell.execute_reply.started":"2024-01-02T02:03:08.455541Z","shell.execute_reply":"2024-01-02T02:03:08.455562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission = df_all[['image','label']].copy()\ndf_submission.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.456912Z","iopub.status.idle":"2024-01-02T02:03:08.457412Z","shell.execute_reply.started":"2024-01-02T02:03:08.457177Z","shell.execute_reply":"2024-01-02T02:03:08.457199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission.to_csv('./convxnet.csv', index=False)\nprint('Densenet results successfully saved!')","metadata":{"execution":{"iopub.status.busy":"2024-01-02T02:03:08.459793Z","iopub.status.idle":"2024-01-02T02:03:08.460516Z","shell.execute_reply.started":"2024-01-02T02:03:08.460258Z","shell.execute_reply":"2024-01-02T02:03:08.460281Z"},"trusted":true},"execution_count":null,"outputs":[]}]}