首先导入所需包和模块
import torch
from torch import nn
from torch.nn import init
import numpy as np
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l
一.获取和读取数据
batch_size = 256#设置批量大小
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)#和上节一样,获取数据集
二.定义和初始化模型
num_inputs = 784#输入
num_outputs = 10#输出
#softmax回归的输出层是一个全连接层,所以我们用一个线性模块即可
class LinearNet(nn.Module):
#super调用nn.Module同名方法
def __init__(self, num_inputs, num_outputs):
super(LinearNet, self).__init__()
self.linear = nn.Linear(num_inputs, num_outputs)
#forward定义前向传播
def forward(self, x): # x的形状:(batch, 1, 28, 28),批量大小,维道数为1(数据集中是灰度图像,维道数为1),图像的高28和宽28
y = self.linear(x.view(x.shape[0], -1))#将返回值转换成batch_size*784的形状送入全连接层
return y
net = LinearNet(num_inputs, num_outputs)
PS:我们将对x的形状转换的这个功能自定义一个FlattenLayer并记录在d2lzh_pytorch中方便后面使用。
# 本函数已保存在d2lzh_pytorch包中方便以后使用
class FlattenLayer(nn.Module):
def __init__(self):
super(FlattenLayer, self).__init__()
def forward(self, x): # x shape: (batch, *, *, ...)
return x.view(x.shape[0], -1)
这样我们就可以更方便地定义我们的模型:
from collections import OrderedDict
net = nn.Sequential(
# FlattenLayer(),
# nn.Linear(num_inputs, num_outputs)#两种写法都可
OrderedDict([
('flatten', FlattenLayer()),
('linear', nn.Linear(num_inputs, num_outputs))
])
)
然后,我们使用均值为0、标准差为0.01的正态分布随机初始化模型的权重参数。
init.normal_(net.linear.weight, mean=0, std=0.01)#正态分布初始化
init.constant_(net.linear.bias, val=0) #初始化整个矩阵为常数val
推荐博客: pytorch nn.init 中实现的初始化函数
三.softmax和交叉熵损失函数
loss = nn.CrossEntropyLoss()#pytorch包内置交叉熵损失函数,数值稳定性很好
四.定义优化算法
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)#SGD小批量随机梯度下降,学习率为0.1
五.训练模型
num_epochs = 5#迭代次数
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None, None, optimizer)#上节已定义
输出:
epoch 1, loss 0.0031, train acc 0.745, test acc 0.790
epoch 2, loss 0.0022, train acc 0.812, test acc 0.807
epoch 3, loss 0.0021, train acc 0.825, test acc 0.806
epoch 4, loss 0.0020, train acc 0.832, test acc 0.810
epoch 5, loss 0.0019, train acc 0.838, test acc 0.823
六.小结
原书地址:原书