目录
五.将训练好的模型进行分类预测,并将图像及其真实类别与预测类别进行对比显示 。
项目背景和目的:
互联网技术的飞速发展和智能硬件性能的不断提高,全球每时每刻都在产生海量的图像数据。这些图像数据作为一种重要的信息载体,包含着丰富的内容,对它们进行分类和分析具有重要的实际应用价值。本项目的在于利用模型对不同花卉进行识别,从而进一步将不同花卉进行分类。
项目准备
一. 导入相关库和相关模块
1.导入PyTorch库及相关模块
用于加载和预处理图像数据集,torch
是PyTorch的核心库,提供了张量操作和神经网络等功能;transforms
模块提供了图像预处理的工具;ImageFolder
是PyTorch提供的一个方便的数据集类,可以根据目录结构自动加载标注好的图像数据;DataLoader
是PyTorch的数据加载器,可以将数据集分批加载并打乱顺序,方便训练神经网络。
2.加载数据集
import torch
from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
# 定义图像转换器
transform = transforms.Compose([
transforms.Resize((224, 224)), # 调整图像大小
transforms.ToTensor(), # 将PIL图像转为Tensor(张量),并归一化至[0,1]
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # 对图像的每个通道(对于RGB图像即红、绿、蓝三个通道)进行标准化处理。
])
# 加载数据集
dataset = ImageFolder('E:/flower7595/flowers', transform=transform)
# 划分训练集和验证集(假设80%训练,20%验证)
train_size = int(0.8 * len(dataset))
val_size = len(dataset) - train_size
train_dataset, val_dataset = torch.utils.data.random_split(dataset, [train_size, val_size])
# 创建DataLoader(数据加载器)
batch_size = 32
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)#训练集数据加载器
val_loader = DataLoader(val_dataset, batch_size=batch_size) #验证集数据加载器
二.加载ResNet-18模型
ResNet-18模型:为了解决图像分类问题而设计,特别是在ImageNet数据集上的大规模图像分类任务。该模型能够学习从图像中提取有区分度的特征,并将这些特征用于分类任务。
- 设置
pretrained
参数为True
,以便加载预训练的权重。 - 修改ResNet-18模型的最后一层全连接层,将其输出维度改为5,以适应特定任务的类别数。
import torch.nn as nn
from torchvision.models import resnet18
# 加载ResNet-18模型
model = resnet18(pretrained=True)
# 修改最后一层全连接层以匹配5个类别
num_features = model.fc.in_features
model.fc = nn.Linear(num_features, 5)
# 使用GPU进行加速(如果GPU不可用,则退回到CPU计算。)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = model.to(device)
三.对模型进行训练
使用PyTorch训练模型
1.定义函数
import torch.optim as optim
import matplotlib.pyplot as plt
import torch
from torch import nn
import os
epoch_losses = [] # 用于存储每个epoch的平均损失
#定义损失函数为交叉熵损失,用于多类分类问题。
def define_loss_function():
return nn.CrossEntropyLoss()
#定义优化器为随机梯度下降(SGD),并设置学习率和动量。
def define_optimizer(model):
return optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
2.开始训练
主要参数:
model: 要训练的模型。
criterion: 损失函数。
optimizer: 优化器。
train_loader: 训练数据加载器。
train_dataset: 训练数据集。
num_epochs: 训练轮数。
返回:
训练后的模型:
def train_model(model, criterion, optimizer, train_loader, train_dataset, num_epochs):
model.train()
for epoch in range(num_epochs):
running_loss = 0.0 # 用于记录当前epoch的训练损失
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad() # 清空梯度
outputs = model(inputs) # 前向传播
loss = criterion(outputs, labels) # 计算损失
# 异常处理:监控梯度并处理梯度爆炸
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1)
loss.backward() # 反向传播
optimizer.step() # 更新参数
running_loss += loss.item() * inputs.size(0) # 累加损失
epoch_loss = running_loss / len(train_dataset) # 计算当前epoch的平均损失
# 将当前epoch的平均损失添加到epoch_losses列表
epoch_losses.append(epoch_loss)