使用Fashion MNIST 对LeNet进行训练和测试。优化算法采用 torchoptimSGD 或 torchoptimAdam。可复用多层感知器的相关代码分别绘制训练和测试的损失函数曲线和分类正确率曲线
首先,需要加载Fashion MNIST数据集和必要的Python库:
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
# 加载Fashion MNIST数据集并进行数据预处理
train_dataset = datasets.FashionMNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = datasets.FashionMNIST(root='./data', train=False, transform=transforms.ToTensor(), download=True)
# 定义批量大小
batch_size = 32
# 创建数据加载器
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
# 定义标签列表
labels = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
定义LeNet模型:
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
self.pool1 = nn.MaxPool2d(kernel_size=2)
self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5)
self.pool2 = nn.MaxPool2d(kernel_size=2)
self.fc1 = nn.Linear(in_features=16*4*4, out_features=120)
self.fc2 = nn.Linear(in_features=120, out_features=84)
self.fc3 = nn.Linear(in_features=84, out_features=10)
def forward(self, x):
x = self.pool1(torch.relu(self.conv1(x)))
x = self.pool2(torch.relu(self.conv2(x)))
x = x.view(-1, 16*4*4)
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x
定义训练函数:
def train(model, optimizer, criterion, train_loader):
model.train() # 设置模型为训练模式
losses = []
correct = 0
total = 0
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad() # 清空梯度
output = model(data) # 前向传播
loss = criterion(output, target) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数
# 统计损失和准确率
losses.append(loss.item())
predicted = output.argmax(dim=1)
correct += predicted.eq(target).sum().item()
total += target.size(0)
accuracy = 100. * correct / total
return losses, accuracy
定义测试函数:
def test(model, criterion, test_loader):
model.eval() # 设置模型为评估模式
losses = []
correct = 0
total = 0
with torch.no_grad(): # 禁用梯度计算
for batch_idx, (data, target) in enumerate(test_loader):
output = model(data) # 前向传播
loss = criterion(output, target) # 计算损失
# 统计损失和准确率
losses.append(loss.item())
predicted = output.argmax(dim=1)
correct += predicted.eq(target).sum().item()
total += target.size(0)
accuracy = 100. * correct / total
return losses, accuracy
定义训练和测试过程:
# 定义模型、损失函数和优化器
model = LeNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 训练和测试
train_losses = []
train_accuracies = []
test_losses = []
test_accuracies = []
num_epochs = 10
for epoch in range(num_epochs):
train_loss, train_accuracy = train(model, optimizer, criterion, train_loader)
test_loss, test_accuracy = test(model, criterion, test_loader)
train_losses.extend(train_loss)
train_accuracies.append(train_accuracy)
test_losses.extend(test_loss)
test_accuracies.append(test_accuracy)
print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.2f}%, Test Loss: {:.4f}, Test Acc: {:.2f}%'
.format(epoch+1, num_epochs, train_loss[-1], train_accuracy, test_loss[-1], test_accuracy))
# 绘制损失函数曲线
plt.plot(train_losses, label='Train')
plt.plot(test_losses, label='Test')
plt.xlabel('Iteration')
plt.ylabel('Loss')
plt.legend()
plt.show()
# 绘制分类正确率曲线
plt.plot(train_accuracies, label='Train')
plt.plot(test_accuracies, label='Test')
plt.xlabel('Epoch')
plt.ylabel('Accuracy (%)')
plt.legend()
plt.show()
# 绘制部分测试集样本和预测结果
num_samples = 10
samples, labels = iter(test_loader).next()
outputs = model(samples)
predicted = outputs.argmax(dim=1)
fig, axs = plt.subplots(1, num_samples, figsize=(20, 5))
for i in range(num_samples):
axs[i].imshow(samples[i][0], cmap='gray')
axs[i].set_title('Predicted: {}\nActual: {}'.format(labels[predicted[i]], labels[i]))
plt.show()
可以更改优化器为Adam:
# 定义模型、损失函数和优化器
model = LeNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练和测试
train_losses = []
train_accuracies = []
test_losses = []
test_accuracies = []
num_epochs = 10
for epoch in range(num_epochs):
train_loss, train_accuracy = train(model, optimizer, criterion, train_loader)
test_loss, test_accuracy = test(model, criterion, test_loader)
train_losses.extend(train_loss)
train_accuracies.append(train_accuracy)
test_losses.extend(test_loss)
test_accuracies.append(test_accuracy)
print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.2f}%, Test Loss: {:.4f}, Test Acc: {:.2f}%'
.format(epoch+1, num_epochs, train_loss[-1], train_accuracy, test_loss[-1], test_accuracy))
# 绘制损失函数曲线
plt.plot(train_losses, label='Train')
plt.plot(test_losses, label='Test')
plt.xlabel('Iteration')
plt.ylabel('Loss')
plt.legend()
plt.show()
# 绘制分类正确率曲线
plt.plot(train_accuracies, label='Train')
plt.plot(test_accuracies, label='Test')
plt.xlabel('Epoch')
plt.ylabel('Accuracy (%)')
plt.legend()
plt.show()
# 绘制部分测试集样本和预测结果
num_samples = 10
samples, labels = iter(test_loader).next()
outputs = model(samples)
predicted = outputs.argmax(dim=1)
fig, axs = plt.subplots(1, num_samples, figsize=(20, 5))
for i in range(num_samples):
axs[i].imshow(samples[i][0], cmap='gray')
axs[i].set_title('Predicted: {}\nActual: {}'.format(labels[predicted[i]], labels[i]))
plt.show()
``
原文地址: https://www.cveoy.top/t/topic/eE7F 著作权归作者所有。请勿转载和采集!