花卉识别数据集-102种 使用 PyTorch 框架,并结合 torchvision、scipy 等工具训练并建立深度学习花卉图像分类系统
花卉识别数据集-102种 使用 PyTorch 框架,并结合 torchvision、scipy 等工具训练并建立深度学习花卉图像分类系统
示例代码仅供参考。
文章目录
数据集描述:
花卉识别数据集-102种
102 个种类的花卉图像,其目录结构中,jpg 文件夹存放所有格式为.jpg 的花卉图像
imagelabels.mat 包含图像的标签信息以标记花卉种类
setid.mat 包含训练集、验证集和测试集的图像 ID 划分
train_extra_list.txt 列出训练的额外图像文件及其标签
train_list.txt 和 val_list.txt 分别列出训练集和验证集的图像文件及其标签。
图像文件在 jpg 文件夹中,标签文件有 imagelabels.mat 和 setid.mat
文本列表文件有 train_extra_list.txt、train_list.txt 和 val_list.txt
102 种花卉,图像数量依列表文件记录而定,每个图像有对应标签用于分类。使用时,可通过 train_list.txt 和 val_list.txt 加载训练集和验证集图像及其标签,利用 imagelabels.mat 获取图像标签信息,花卉分类任务,辅助训练和评估图像分类模型性能。
1
深度学习花卉图像分类系统(102种) 的训练流程,适用于你提到的 “花卉识别数据集-102种”。使用 PyTorch 框架,并结合 torchvision、scipy 等工具来加载和处理数据。
🌸 花卉识别数据集 - 102 类深度学习分类系统实现
✅ 数据结构说明
dataset/
├── jpg/ # 所有 .jpg 图像文件
├── imagelabels.mat # 图像标签 (1~102)
├── setid.mat # 划分 ID(训练、验证、测试)
├── train_list.txt # 训练集列表
├── val_list.txt # 验证集列表
└── train_extra_list.txt # 额外训练图像列表(可选)
🔧 第一步:安装依赖
pip install torch torchvision scipy matplotlib scikit-learn tqdm
📁 第二步:自定义 Dataset 加载器
根据 train_list.txt 和 val_list.txt 文件读取图像路径和对应标签:
import os
from PIL import Image
from torch.utils.data import Dataset
class Flowers102Dataset(Dataset):
def __init__(self, root_dir, list_file, transform=None):
self.root_dir = root_dir
self.transform = transform
self.image_paths, self.labels = self._load_list(os.path.join(root_dir, list_file))
def _load_list(self, file_path):
image_paths = []
labels = []
with open(file_path, 'r') as f:
for line in f:
img_name, label = line.strip().split()
image_paths.append(os.path.join(self.root_dir, 'jpg', img_name))
labels.append(int(label) - 1) # 标签从0开始
return image_paths, labels
def __len__(self):
return len(self.image_paths)
def __getitem__(self, idx):
image_path = self.image_paths[idx]
image = Image.open(image_path).convert('RGB')
label = self.labels[idx]
if self.transform:
image = self.transform(image)
return image, label
🎨 第三步:数据增强与预处理
from torchvision import transforms
transform_train = transforms.Compose([
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
transform_val = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
🏗️ 第四步:模型定义(推荐 ResNet50)
from torchvision import models
import torch.nn as nn
def get_model(num_classes=102, pretrained=True):
model = models.resnet50(pretrained=pretrained)
model.fc = nn.Linear(model.fc.in_features, num_classes)
return model
🚀 第五步:训练与验证代码
import torch
from torch.utils.data import DataLoader
from torch import optim
from tqdm import tqdm
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 初始化数据集
root_dir = 'dataset' # 替换为你的数据集路径
train_dataset = Flowers102Dataset(root_dir=root_dir, list_file='train_list.txt', transform=transform_train)
val_dataset = Flowers102Dataset(root_dir=root_dir, list_file='val_list.txt', transform=transform_val)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=4)
# 初始化模型
model = get_model()
model.to(device)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)
# 训练循环
num_epochs = 30
for epoch in range(num_epochs):
model.train()
running_loss = 0.0
progress_bar = tqdm(train_loader, desc=f"Epoch {epoch+1}/{num_epochs}")
for images, labels in progress_bar:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item() * images.size(0)
progress_bar.set_postfix(loss=loss.item())
scheduler.step()
print(f"Epoch {epoch+1} Loss: {running_loss / len(train_dataset)}")
# 验证
model.eval()
correct = 0
total = 0
with torch.no_grad():
for images, labels in val_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f"Validation Accuracy: {100 * correct / total:.2f}%")
💾 第六步:保存模型
torch.save(model.state_dict(), 'flowers102_resnet50.pth')
print("Model saved.")
📈 可选:可视化训练过程(Matplotlib)
可将每个 epoch 的 loss 和 accuracy 存储在一个列表中,并在训练结束后绘制图表。
好的,下面是扩展后的完整代码示例,包括使用 imagelabels.mat 和 setid.mat 文件构建数据集、多GPU训练支持、TensorBoard可视化、混淆矩阵分析以及测试集预测与提交文件生成。
1. 加载 .mat 文件
首先,我们需要加载 .mat 文件以获取图像标签和数据集划分信息。这可以通过 scipy.io.loadmat 实现:
import scipy.io as sio
def load_mat_data(mat_file_path):
mat_data = sio.loadmat(mat_file_path)
return mat_data
2. 更新 Dataset 类以利用 .mat 文件
在 Flowers102Dataset 中添加对 .mat 文件的支持:
class Flowers102Dataset(Dataset):
def __init__(self, root_dir, list_file=None, transform=None, label_file='imagelabels.mat', set_file='setid.mat'):
self.root_dir = root_dir
self.transform = transform
labels_mat = load_mat_data(os.path.join(root_dir, label_file))
setid_mat = load_mat_data(os.path.join(root_dir, set_file))
if list_file is None:
# 根据 setid.mat 分割数据集
self.image_paths, self.labels = self._load_from_setid(setid_mat, labels_mat)
else:
self.image_paths, self.labels = self._load_list(os.path.join(root_dir, list_file), labels_mat)
def _load_list(self, file_path, labels_mat):
image_paths = []
labels = []
with open(file_path, 'r') as f:
for line in f:
img_name, label = line.strip().split()
image_paths.append(os.path.join(self.root_dir, 'jpg', img_name))
labels.append(int(label) - 1) # 标签从0开始
return image_paths, labels
def _load_from_setid(self, setid_mat, labels_mat):
ids = {'train': setid_mat['trnid'][0], 'val': setid_mat['valid'][0], 'test': setid_mat['tstid'][0]}
image_paths = []
labels = []
for idx in ids['train']:
image_paths.append(os.path.join(self.root_dir, 'jpg', f'image_{idx:05}.jpg'))
labels.append(labels_mat['labels'][0][idx-1] - 1)
return image_paths, labels
# ... 其他方法保持不变
3. 多GPU训练支持
确保模型可以在多个GPU上运行:
if torch.cuda.device_count() > 1:
print(f"Let's use {torch.cuda.device_count()} GPUs!")
model = nn.DataParallel(model)
4. TensorBoard 可视化
集成 TensorBoard 进行可视化:
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('runs/flowers102_experiment')
# 在训练循环中添加以下代码:
for epoch in range(num_epochs):
# ...
writer.add_scalar('training loss', running_loss / len(train_dataset), epoch)
writer.add_scalar('validation accuracy', 100 * correct / total, epoch)
5. 混淆矩阵分析
在验证阶段计算并绘制混淆矩阵:
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
def plot_confusion_matrix(cm, classes, normalize=False, title='Confusion matrix', cmap=plt.cm.Blues):
plt.figure(figsize=(10,10))
sns.heatmap(cm, annot=True, fmt='d' if not normalize else '.2f', cmap=cmap)
plt.title(title)
plt.ylabel('True label')
plt.xlabel('Predicted label')
plt.xticks(range(len(classes)), classes, rotation=90)
plt.yticks(range(len(classes)), classes, rotation=0)
plt.show()
# 在验证后:
model.eval()
all_labels = []
all_preds = []
with torch.no_grad():
for images, labels in val_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
all_labels.extend(labels.cpu().numpy())
all_preds.extend(predicted.cpu().numpy())
cm = confusion_matrix(all_labels, all_preds)
plot_confusion_matrix(cm, classes=[str(i) for i in range(102)])
6. 测试集预测与提交文件生成
根据 setid.mat 中的测试集ID进行预测,并保存结果:
def generate_submission(model, test_ids, output_path='submission.csv'):
model.eval()
results = []
for idx in test_ids:
image_path = os.path.join(root_dir, 'jpg', f'image_{idx:05}.jpg')
image = Image.open(image_path).convert('RGB')
if transform_val:
image = transform_val(image).unsqueeze(0).to(device)
with torch.no_grad():
output = model(image)
_, predicted = torch.max(output.data, 1)
results.append((idx, predicted.item() + 1)) # 调整回原始标签编号
with open(output_path, 'w') as f:
for idx, label in results:
f.write(f'{idx},{label}\n')
# 使用时:
test_ids = setid_mat['tstid'][0]
generate_submission(model, test_ids)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)