多层感知机
----我们可以通过在网络中加入一个或多个隐藏层来克服线性模型的限制, 使其能处理更普遍的函数关系类型。 要做到这一点,最简单的方法是将许多全连接层堆叠在一起。 每一层都输出到上面的层,直到生成最后的输出。 我们可以把前L−1层看作表示,把最后一层看作线性预测器。 这种架构通常称为多层感知机(multilayer perceptron),通常缩写为MLP。(具体内容可以回看模式识别书)
- 隐藏层,要注意使用非线性的激活函数(activation function)ρ。可以抽象理解为,事物都是由波组成的,线性拟合的信息量肯定会远小于非线性拟合可获得的信息量。
- 常用的有sigmoid,tanhx,RELU等
- 多类分类中,使用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)
# Fashion-MNIST中的每个图像由 28*28=784个灰度像素值组成。 所有图像共分为10个类别。第一层需将图像展平
# 输入层:256*784 权重大小为784*256,因此输入到隐藏层的数据为256*256,隐藏层到输出层的权重为256*10,输出的结果为256*10,
# 即对批次中的每一个样本,都有其相对于可能所属的10个类别的概率
num_inputs, num_outputs, num_hiddens = 784, 10, 256
# 初始设置随机权重,偏差先设置为0,注意各矩阵的形
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函数
def relu(X):
a = torch.zeros_like(X)
return torch.max(X, a)
# 搭建模型
def net(X):
# 第一个-1表示自动求对应位置的维数,此处是根据batch_size
X = X.reshape((-1, num_inputs))
H = relu(X@W1 + b1) # 这里“@”代表矩阵乘法(这个东西之前没看过)
return (H@W2 + b2)
后面就是模型的预测和评估部分了,在此省略。
简洁实现
import torch
from torch import nn
from d2l import torch as d2l
# 展平层,线性层,激活函数,线性层
net = nn.Sequential(nn.Flatten(),
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10))
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, std=0.01)
net.apply(init_weights)
batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss(reduction='none')
trainer = torch.optim.SGD(net.parameters(), lr=lr)
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
确实很简洁,先定义网络架构,再初始化网络权重参数,定义batch_size,学习率和epoch,定义损失函数和优化器,获取训练集和测试集后进行训练与测试,评估模型。