卷积神经网络(基于pytorch的代码实现)
【代码】卷积神经网络(基于pytorch的代码实现)
·
# 导入必要的库
import torch # PyTorch深度学习框架
import torch.nn as nn # 神经网络模块
import torch.optim as optim # 优化器
import torchvision # 计算机视觉工具包
import torchvision.transforms as transforms # 数据预处理工具
# 定义卷积神经网络(CNN)类
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# 第一个卷积层
# 输入通道=1(灰度图像), 输出通道=16, 卷积核大小=3x3, padding=1保持输入输出尺寸相同
self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
self.relu1 = nn.ReLU() # ReLU激活函数
self.pool1 = nn.MaxPool2d(kernel_size=2) # 最大池化层,将图像尺寸减半
# 第二个卷积层
# 输入通道=16, 输出通道=32, 卷积核大小=3x3, padding=1
self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
self.relu2 = nn.ReLU()
self.pool2 = nn.MaxPool2d(kernel_size=2)
# 全连接层
# 32个通道 * 7 * 7的特征图 -> 10个类别(数字0-9)
self.fc = nn.Linear(32 * 7 * 7, 10)
# 定义前向传播过程
def forward(self, x):
x = self.pool1(self.relu1(self.conv1(x))) # 第一层:卷积->激活->池化
x = self.pool2(self.relu2(self.conv2(x))) # 第二层:卷积->激活->池化
x = x.view(-1, 32 * 7 * 7) # 展平特征图,准备进入全连接层
x = self.fc(x) # 全连接层分类
return x
# 设置计算设备(GPU如果可用,否则使用CPU)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f'使用设备: {device}')
# 数据预处理设置
transform = transforms.Compose([
transforms.ToTensor(), # 将图像转换为PyTorch张量
transforms.Normalize((0.1307,), (0.3081,)) # 标准化:(像素值-均值)/标准差
])
# 加载MNIST训练数据集
train_dataset = torchvision.datasets.MNIST(
root='./data', # 数据保存路径
train=True, # 指定为训练集
download=True, # 如果数据不存在则下载
transform=transform # 应用上面定义的预处理
)
# 加载MNIST测试数据集
test_dataset = torchvision.datasets.MNIST(
root='./data',
train=False, # 指定为测试集
download=True,
transform=transform
)
# 创建数据加载器
train_loader = torch.utils.data.DataLoader(
train_dataset,
batch_size=64, # 每批处理64张图片
shuffle=True # 随机打乱数据
)
test_loader = torch.utils.data.DataLoader(
test_dataset,
batch_size=1000, # 测试时可以使用更大的batch_size
shuffle=False # 测试时不需要打乱数据
)
# 创建模型实例并移至指定设备
model = SimpleCNN().to(device)
# 定义损失函数(交叉熵损失,适用于分类问题)
criterion = nn.CrossEntropyLoss()
# 定义优化器(Adam优化器,学习率=0.001)
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 定义评估函数
def evaluate():
model.eval() # 设置为评估模式
correct = 0 # 正确预测的样本数
total = 0 # 总样本数
with torch.no_grad(): # 测试时不需要计算梯度
for data, target in test_loader:
data, target = data.to(device), target.to(device)
outputs = model(data) # 前向传播
_, predicted = torch.max(outputs.data, 1) # 获取最大概率的预测结果
total += target.size(0) # 累加总样本数
correct += (predicted == target).sum().item() # 累加正确预测数
accuracy = 100 * correct / total
print(f'测试集准确率: {accuracy:.2f}%')
return accuracy
# 定义训练函数
def train(epochs):
best_accuracy = 0 # 记录最佳准确率
for epoch in range(epochs): # 训练轮次循环
model.train() # 设置为训练模式
running_loss = 0.0
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad() # 清空梯度
outputs = model(data) # 前向传播
loss = criterion(outputs, target) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数
running_loss += loss.item()
if batch_idx % 100 == 99: # 每100批次打印一次训练状态
print(f'轮次: {epoch + 1}, 批次: {batch_idx + 1}, 损失: {running_loss / 100:.3f}')
running_loss = 0.0
# 每轮结束后评估模型
print(f'\n=== 第 {epoch + 1} 轮评估 ===')
accuracy = evaluate()
# 如果当前模型更好,就保存它
if accuracy > best_accuracy:
best_accuracy = accuracy
torch.save(model.state_dict(), 'best_model.pth')
print(f'保存新的最佳模型,准确率: {best_accuracy:.2f}%\n')
# 主程序
if __name__ == '__main__':
print("开始训练...")
train(epochs=5) # 训练5轮
print("\n训练完成!加载最佳模型进行最终评估...")
model.load_state_dict(torch.load('best_model.pth'))
final_accuracy = evaluate()
print(f'最终最佳准确率: {final_accuracy:.2f}%')
更多推荐
所有评论(0)