{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":29193,"databundleVersionId":2318453,"sourceType":"competition"}],"dockerImageVersionId":31012,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport pandas as pd\nimport torch\nimport torchvision\nfrom torchvision import datasets, transforms, models\nfrom torch.utils.data import DataLoader, Dataset,random_split\nfrom PIL import Image\nimport torch.nn as nn\nimport torch.optim as optim\nfrom sklearn.metrics import accuracy_score\nfrom torchvision.models import ResNet34_Weights, ResNet50_Weights\nfrom tqdm import tqdm\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts,ExponentialLR\n\ntrain_csv = '/kaggle/input/classify-leaves/train.csv'\ntrain_df = pd.read_csv(train_csv)\nprint(train_df.head())  # 打印前几行数据\n\n\n\n# def augment_images(image_folder, train_csv, augmented_csv):\n#     transform = transforms.Compose([\n#         transforms.RandomResizedCrop(224),\n#         transforms.RandomHorizontalFlip(),\n#         transforms.RandomRotation(30),\n#         transforms.ToTensor(),\n#         transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n#     ])\n    \n#     train_df = pd.read_csv(train_csv)\n#     image_paths = train_df['image'].values  # 获取图片路径\n#     augmented_images = []  \n#     for image_path in image_paths:\n#         full_image_path = os.path.join(image_folder, image_path)\n#         image = Image.open(full_image_path)\n#         # 对每张图片进行多次数据增强\n#         for i in range(5):  # 假设每张图片增强5次\n#             augmented_image = transform(image)\n#             augmented_image_name = f\"{os.path.basename(image_path)}_augmented_{i}.jpg\"\n#             augmented_images.append([augmented_image_name, train_df[train_df['image'] == image_path]['label'].values[0]])\n            \n#             # 保存增强后的图片\n#             augmented_image_path = os.path.join('/kaggle/working', augmented_image_name)\n#             torchvision.utils.save_image(augmented_image, augmented_image_path)\n    \n#     # 将增强后的图片信息保存到新的CSV文件\n#     augmented_df = pd.DataFrame(augmented_images, columns=['image', 'label'])\n#     augmented_df.to_csv(augmented_csv, index=False)\n#     #print(augmented_df.head())  # 打印增强后数据的前几行\n\ntrain_df = pd.read_csv(\"/kaggle/input/classify-leaves/train.csv\")\nunique_labels = sorted(train_df['label'].unique())\nlabel_to_int = {label: idx + 1 for idx, label in enumerate(unique_labels)}\nmax_label_value = max(label_to_int.values())\nprint(f\"最大标签值: {max_label_value}\")\n\nclass LeafDataset(Dataset):\n    def __init__(self, csv_file, root_dir, transform=None):\n        self.data = pd.read_csv(csv_file)\n        self.root_dir = root_dir\n        self.transform = transform\n        self.label_to_int = label_to_int  # 使用标签映射字典\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, idx):\n        #print(f\"Row {idx}: {self.data.iloc[idx]}\")  # 打印当前行的内容\n        img_path = os.path.join(self.root_dir, self.data.iloc[idx, 0])\n        image = Image.open(img_path)\n        label = self.data.iloc[idx, 1]  # 确保第二列是标签\n        label = self.label_to_int[label]\n        if self.transform:\n           image = self.transform(image)\n        return image, label\n\ndef main():\n    image_folder = '/kaggle/input/classify-leaves'\n    train_csv = '/kaggle/input/classify-leaves/train.csv'\n    test_csv = '/kaggle/input/classify-leaves/test.csv'\n    sample_submission_csv = '/kaggle/input/classify-leaves/sample_submission.csv'\n    augmented_csv = '/kaggle/working/augmented_train.csv'\n\n    train_df = pd.read_csv(train_csv)\n    unique_labels = sorted(train_df['label'].unique())\n    label_to_int = {label: idx + 1 for idx, label in enumerate(unique_labels)}\n    \n    # 数据增强并保存到新的CSV文件\n    # augment_images(image_folder, train_csv, augmented_csv)\n    \n    data_transforms = {\n        'train': transforms.Compose([\n            transforms.RandomResizedCrop(224),\n            transforms.RandomHorizontalFlip(),\n            transforms.ToTensor(),\n            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n        ]),\n        'val': transforms.Compose([\n            transforms.Resize(256),\n            transforms.CenterCrop(224),\n            transforms.ToTensor(),\n            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n        ]),\n    }\n    \n\n\n    \n    \n\n   \n    # train_dataset = LeafDataset(csv_file=augmented_csv, root_dir='/home/bhy/test/classify-leaves/working', transform=data_transforms['train'])\n    train_dataset = LeafDataset(csv_file=train_csv, root_dir='/kaggle/input/classify-leaves', transform=data_transforms['train'])\n    total_size = len(train_dataset)\n    test_size = int(0.2 * total_size)  # 20% 作为测试集\n    train_size = total_size - test_size  # 剩下的作为训练集\n    train_subset, test_subset = random_split(train_dataset, [train_size, test_size])\n    \n    # test_dataset = LeafDataset(csv_file=test_csv, root_dir=image_folder, transform=data_transforms['val'])\n    # test_dataset = LeafDataset(csv_file=sample_submission_csv, root_dir=image_folder, transform=data_transforms['val'])\n   \n    train_loader = DataLoader(train_subset, batch_size=64, shuffle=True)\n    test_loader = DataLoader(test_subset, batch_size=64, shuffle=False)\n\n    model = models.resnet50(weights=ResNet50_Weights.IMAGENET1K_V1)\n    # model = models.resnet34(weights=ResNet34_Weights.IMAGENET1K_V1)\n    train_df = pd.read_csv(\"/kaggle/input/classify-leaves/train.csv\")\n\n    unique_labels = sorted(train_df['label'].unique())\n    label_to_int = {label: idx + 1 for idx, label in enumerate(unique_labels)}\n    max_label_value = max(label_to_int.values())\n    num_classes = max_label_value\n    model.fc = nn.Linear(model.fc.in_features, num_classes+1)\n    \n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    model = model.to(device)\n    \n    criterion = nn.CrossEntropyLoss()\n    optimizer = optim.Adam(model.parameters(), lr=0.0001,weight_decay=1e-5)\n    scheduler = ExponentialLR(optimizer, gamma=0.9,verbose=True)\n    \n    num_epochs = 30\n    # num_epochs = 2\n    for epoch in range(num_epochs):\n        model.train()\n        running_loss = 0.0\n        # for inputs, labels in train_loader:\n        for inputs, labels in tqdm(train_loader, desc=f\"Epoch {epoch+1}/{num_epochs}\"):\n            inputs = inputs.to('cuda' if torch.cuda.is_available() else 'cpu')\n    \n            if isinstance(labels, str):\n               labels = torch.tensor(int(labels))  # 假设标签是字符串形式的整数，将其转换为张量\n    \n            labels = labels.to('cuda' if torch.cuda.is_available() else 'cpu')\n            optimizer.zero_grad()\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n            running_loss += loss.item() * inputs.size(0)\n        scheduler.step()\n        epoch_loss = running_loss / len(train_loader.dataset)\n        print(f'Epoch {epoch+1}/{num_epochs}, Loss: {epoch_loss:.4f}')\n    \n    model.eval()\n    all_preds = []\n    all_labels = []\n    with torch.no_grad():\n       for inputs, labels in tqdm(test_loader, desc=f\"testing\"):\n            inputs = inputs.to('cuda' if torch.cuda.is_available() else 'cpu')\n            if isinstance(labels, tuple):\n               labels = labels[0]  # 假设标签是元组的第一个元素\n            labels = labels.to('cuda' if torch.cuda.is_available() else 'cpu')\n            outputs = model(inputs)\n            _, preds = torch.max(outputs, 1)\n            all_preds.extend(preds.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n    \n    accuracy = accuracy_score(all_labels, all_preds)\n    print(f'Test Accuracy: {accuracy:.4f}')\n\nif __name__ == '__main__':\n    main()","metadata":{"_uuid":"d08bd8e6-000a-414f-a287-f30342983423","_cell_guid":"8aba277d-d20b-458f-a851-9c8056fff8e0","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2025-04-12T05:55:54.341978Z","iopub.execute_input":"2025-04-12T05:55:54.342244Z"}},"outputs":[],"execution_count":null}]}