前言:本篇文章的服务对象是没有武力值也想和pytorch沾沾边的小白朋友们,主要的内容是对于经典代码的逐行解读,解读内容以注释的形式展示。
本篇文章的代码来源为(李沐 动手学深度学习pytorch版)
本篇文章是运用多层感知机对于mnist数据集进行识别。相对于softmax函数而言多层感知机加入了隐藏层、激活函数等概念。
import torch
from torch import nn
from d2l import torch as d2l
# 这里和前文都是一样的,设定批量大小和导入数据集
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
以下是本篇文章主要的不通同点
输入是28*28点图片,输出为10,隐藏层(超参数)设置为256(选取的是784和10之间的一个数)
W1第一层,初始为一个随机的行数为784列数为256的tensor,b1偏差设定为0,且要计算梯度
第二层输出层,行256,列10的随机tensor,b2偏差也设置为0
函数Parameter加不加没关系,只是说明其是一个torch的参数,
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = nn.Parameter(torch.randn(
num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(
num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
params = [W1, b1, W2, b2]
实现ReLu函数,这里选取ReLu函数作为激活函数,主要是因为简单。ReLu函数也有其自身的优点,它在x>0时取x,其余时候取0。因此其不用进行指数运算速度较快。
# 实现ReLu函数
def relu(X):
a = torch.zeros_like(X)
return torch.max(X, a)
实现我们的模型,先将其reshape为一个1*784的二维矩阵,
@是进行的矩阵乘法,其中乘法时要不要转置就取决于在设定时两个矩阵是不是可以做乘法。
加上激活函数(ReLu函数)作为第一层的输出,并将第一层的输出作为第二层的输入,作为最后的输出
def net(X):
X = X.reshape((-1, num_inputs))
H = relu(X@W1 + b1) # 这里“@”代表矩阵乘法
return (H@W2 + b2)
训练部分和前文中就表现一致了主要调用了CrossEntropyLoss、SGD和train_ch3(都是在之前的文章中定义过的函数)。
# 损失和前面的几篇文章是一样的,直接调用损失函数了
loss = nn.CrossEntropyLoss(reduction='none')
# 训练也和前面的几篇文章一样,运行后也可以看到图片。
# 与softmax回归进行对比的话损失更低了,精度没有太多变化
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)