首先,需要加载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 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录