下载数据集

//由于markdown语法限制,本章中注释改为//
%matplotlib inline
%matplotlib inline

import torch

import torchvision

from torch.utils import data

from torchvision import transforms

from d2l import torch as d2l

import torch.nn as nn

import torch.optim as optim

d2l.use_svg_display()

// 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,

// 并除以255使得所有像素的数值均在0~1之间

trans = transforms.ToTensor()

mnist_train = torchvision.datasets.FashionMNIST(

root="../data", train=True, transform=trans, download=True)

mnist_test = torchvision.datasets.FashionMNIST(

root="../data", train=False, transform=trans, download=True)

自定义模型

class BlackMLP(nn.Module):

def init(self, input_size, hidden_size, output_size):

super().__init__()

self.fc1 = nn.Linear(input_size, hidden_size)

self.fc2 = nn.Linear(hidden_size, output_size)

self.activation = nn.ReLU()

def forward(self,x):

x = self.activation(self.fc1(x))

x = self.activation(self.fc2(x))

return x

在这一步中,我选择了一个激活层与两个全连接层自定义了一个多层感应机,大家可以根据自己的感觉再添加一些层,但是其中的输入和输出大小由于数据集的限制是固定的,只有中间的隐藏层参数可以改动。

##创建训练集与测试集
import torch

from torch.utils.data import DataLoader

// 创建训练集 DataLoader

train_loader = DataLoader(dataset=mnist_train, batch_size=64, shuffle=True)

// 创建测试集 DataLoader

test_loader = DataLoader(dataset=mnist_test, batch_size=64, shuffle=False)

其中的batch_size=64 指定了每个批次加载的样本数量,这里设置为 64,表示每次从数据集中加载 64 个样本。shuffle=True 表示在每个 epoch 开始的时候是否对数据进行随机打乱。这里设置为 True,表示在每个 epoch 开始时都会重新对数据进行随机打乱,以增加模型的泛化能力。

对数据处理好之后,我们可以定义损失函数与优化器来为下面的模型训练做准备

criterion = nn.CrossEntropyLoss()#定义损失函数与优化器

optimizer = optim.SGD(net.parameters(), lr=0.1)

模型训练

num_epochs = 10

for epoch in range(num_epochs):

for i, (images, labels) in enumerate(train_loader):

    // 将图像展平为一维张量

    images = images.view(images.size(0), -1)



    // 正向传播

    outputs = net(images)

    loss = criterion(outputs, labels)



    // 反向传播和优化

    optimizer.zero_grad()

    loss.backward()

    optimizer.step()



    if (i+1) % 100 == 0:

        print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'

              .format(epoch+1, num_epochs, i+1, len(train_loader), loss.item()))

//训练前我们需要将我们的图像数据转变成一维张量以便数据能够传入模型,该训练大家也可以自己尝试选择不同的损失函数与优化器,以便达到更优的效果。

模型预测

// 初始化变量来跟踪正确预测的样本数量和总样本数量

correct = 0

total = 0

// 设置模型为评估模式

net.eval()

// 使用torch.no_grad()关闭梯度更新

with torch.no_grad():

for images, labels in test_loader:

    #images = images.to(device)

    #labels = labels.to(device)

    images = images.view(images.size(0), -1)



    // 前向传播

    outputs = net(images)



    // 获取预测的类别

    _, predicted = torch.max(outputs, 1)



    // 更新总样本数量

    total += labels.size(0)



    // 更新正确预测的样本数量

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

// 计算测试准确率

accuracy = correct / total * 100

print(‘Test Accuracy: {:.2f}%’.format(accuracy))
预测前我们需要将我们的模型状态变为评估模式,同时也要注意,预测时输入的测试集也要先转化为一维张量,否则矩阵运算无法完成。