pytorch读书报告

代码:(可复制进pychar直接运行)

import torch

import torch.nn as nn

import torch.optim as optim

import torchvision

import torchvision.transforms as transforms

import matplotlib.pyplot as plt

import numpy as np

# ===================== 1. 设备设置与数据预处理 =====================

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 数据增强与预处理:训练集用增强(翻转、裁剪),测试集仅归一化

train_transform = transforms.Compose([

transforms.RandomHorizontalFlip(),

transforms.RandomCrop(32, padding=4),

transforms.ToTensor(),

transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))

])

test_transform = transforms.Compose([

transforms.ToTensor(),

transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))

])

# 加载数据集

trainset = torchvision.datasets.CIFAR10(

root='./data', train=True, download=True, transform=train_transform

)

trainloader = torch.utils.data.DataLoader(

trainset, batch_size=128, shuffle=True, num_workers=2

)

testset = torchvision.datasets.CIFAR10(

root='./data', train=False, download=True, transform=test_transform

)

testloader = torch.utils.data.DataLoader(

testset, batch_size=128, shuffle=False, num_workers=2

)

classes = ('飞机', '汽车', '鸟', '猫', '鹿',

'狗', '青蛙', '马', '船', '卡车')

# ===================== 2. 定义CNN模型(LeNet改进版) =====================

class Net(nn.Module):

def __init__(self):

super(Net, self).__init__()

self.conv1 = nn.Conv2d(3, 64, 3, padding=1)

self.bn1 = nn.BatchNorm2d(64)

self.conv2 = nn.Conv2d(64, 64, 3, padding=1)

self.bn2 = nn.BatchNorm2d(64)

self.pool1 = nn.MaxPool2d(2, 2)

self.conv3 = nn.Conv2d(64, 128, 3, padding=1)

self.bn3 = nn.BatchNorm2d(128)

self.conv4 = nn.Conv2d(128, 128, 3, padding=1)

self.bn4 = nn.BatchNorm2d(128)

self.pool2 = nn.MaxPool2d(2, 2)

self.conv5 = nn.Conv2d(128, 256, 3, padding=1)

self.bn5 = nn.BatchNorm2d(256)

self.conv6 = nn.Conv2d(256, 256, 3, padding=1)

self.bn6 = nn.BatchNorm2d(256)

self.pool3 = nn.MaxPool2d(2, 2)

self.fc1 = nn.Linear(256 * 4 * 4, 512)

self.dropout1 = nn.Dropout(0.5)

self.fc2 = nn.Linear(512, 10)

def forward(self, x):

x = self.pool1(torch.relu(self.bn2(self.conv2(torch.relu(self.bn1(self.conv1(x)))))))

x = self.pool2(torch.relu(self.bn4(self.conv4(torch.relu(self.bn3(self.conv3(x)))))))

x = self.pool3(torch.relu(self.bn6(self.conv6(torch.relu(self.bn5(self.conv5(x)))))))

x = x.view(-1, 256 * 4 * 4)

x = torch.relu(self.fc1(x))

x = self.dropout1(x)

x = self.fc2(x)

return x

net = Net().to(device)

criterion = nn.CrossEntropyLoss()

optimizer = optim.Adam(net.parameters(), lr=0.001)

scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=3, factor=0.5)

# ===================== 3. 训练模型 =====================

epochs = 50

train_losses = []

train_accs = []

test_accs = []

for epoch in range(epochs):

running_loss = 0.0

correct = 0

total = 0

# 训练阶段

net.train()

for inputs, labels in trainloader:

inputs, labels = inputs.to(device), labels.to(device)

optimizer.zero_grad()

outputs = net(inputs)

loss = criterion(outputs, labels)

loss.backward()

optimizer.step()

running_loss += loss.item()

_, predicted = outputs.max(1)

total += labels.size(0)

correct += predicted.eq(labels).sum().item()

train_loss = running_loss / len(trainloader)

train_acc = 100. * correct / total

train_losses.append(train_loss)

train_accs.append(train_acc)

# 测试阶段

net.eval()

correct = 0

total = 0

with torch.no_grad():

for inputs, labels in testloader:

inputs, labels = inputs.to(device), labels.to(device)

outputs = net(inputs)

_, predicted = outputs.max(1)

total += labels.size(0)

correct += predicted.eq(labels).sum().item()

test_acc = 100. * correct / total

test_accs.append(test_acc)

# 学习率调整

scheduler.step(train_loss)

print(f'Epoch {epoch+1:02d} | 训练损失: {train_loss:.3f} | 训练准确率: {train_acc:.2f}% | 测试准确率: {test_acc:.2f}%')

print('训练完成!')

# ===================== 4. 模型评估与可视化 =====================

# 绘制准确率曲线

plt.figure(figsize=(10, 5))

plt.plot(train_accs, label='训练准确率')

plt.plot(test_accs, label='测试准确率')

plt.xlabel('Epoch')

plt.ylabel('准确率 (%)')

plt.legend()

plt.title('训练与测试准确率曲线')

plt.savefig('accuracy_curve.png')

plt.show()

# 绘制损失曲线

plt.figure(figsize=(10, 5))

plt.plot(train_losses, label='训练损失')

plt.xlabel('Epoch')

plt.ylabel('损失')

plt.legend()

plt.title('训练损失曲线')

plt.savefig('loss_curve.png')

plt.show()

# 各类别准确率评估

class_correct = [0.] * 10

class_total = [0.] * 10

net.eval()

with torch.no_grad():

for inputs, labels in testloader:

inputs, labels = inputs.to(device), labels.to(device)

outputs = net(inputs)

_, predicted = outputs.max(1)

c = (predicted == labels).squeeze()

for i in range(len(labels)):

label = labels[i]

class_correct[label] += c[i].item()

class_total[label] += 1

for i in range(10):

print(f'类别 {classes[i]} 的准确率: {100 * class_correct[i] / class_total[i]:.2f}%')

# 保存模型

torch.save(net.state_dict(), 'cifar10_cnn.pth')

print('模型已保存为 cifar10_cnn.pth')

////运行结果:

posted @ 2025-10-23 22:41  hxzzzzz  阅读(1)  评论(0)    收藏  举报