多层感知机
前言:本章分为8小章
1.多层感知机
具有单调性:即W增大 output增大,W减小 output减小,而现实中存在许多违反单调性的例子:
①体温预测死亡率 ②收入变化与还款可能性
将前 L-1层看作表示,把最后一层看作线性预测器,这种架构 常称为多层感知机 (此处线性存疑)

缺点: 具有全连接层的多层感知机的参数开销过大
多层感知机公式
(H:Hidden O:output),经化简可发现 所谓多层感知机仍可蜕变为:O=XW+b ,摆脱不了其单调性
因此:
我们引入激活函数,增强网络的非线性表征能力,公式如下:

为了构建更通用的多层感知机, 我们可以继续堆叠这样的隐藏层 :例如

通过不断堆叠,从而产生更有表达能力的模型
①ReLU函数(Rectified linear unit) 中文名:修正线性单元
优点:求导表现好,参数只能消失或者通过,便于优化
公式如下:

示例:
x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
y = torch.relu(x)
d2l.plot(x.detach(), y.detach(), 'x', 'relu(x)', figsize=(5, 2.5))
可以由函数曲线图看出,ReLU是分段线性的

接下来我们观察ReLU函数的导数图
实现代码:
y.backward(torch.ones_like(x), retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of relu', figsize=(5, 2.5))
#此处我们规定当输入值精确为0时,默认使用左侧导数‘0’

**此外,ReLU函数 有许多变体,包括参数化ReLU(Parameterized ReLU,pReLU) 函数 该变体为ReLU添加了一个线性项,因此即使参数是负的,某些信息仍然可以通过: **

②sigmoid函数 又称挤压函数(squashing function)
公式如下:

该激活函数强制将范围**(-∞,+∞)的任意输入压缩为(0,1)**的某一值
示例:
y = torch.sigmoid(x)
d2l.plot(x.detach(), y.detach(), 'x', 'sigmoid(x)', figsize=(5, 2.5))

sigmoid函数的导数公式如下:

示例:
# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x),retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of sigmoid', figsize=(5, 2.5))

③tanh函数 又称挤压函数(squashing function)
公式:

该激活函数强制将范围**(-∞,+∞)的任意输入压缩为(0,1)**的某一值
示例:
y = torch.tanh(x)
d2l.plot(x.detach(), y.detach(), 'x', 'tanh(x)', figsize=(5, 2.5))

导数公式:

# 清除以前的梯度
x.grad.data.zero_()
y.backward(torch.ones_like(x),retain_graph=True)
d2l.plot(x.detach(), x.grad, 'x', 'grad of tanh', figsize=(5, 2.5))

2.多层感知机的从零开始实现
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)
1一般选择2的幂作为层宽度。 因为内存在硬件中的分配和寻址方式,这么做使计算上更高效
2.该数据集中每个图像包含784个灰度像素值,所有图像共分为10类
3.构建单隐藏层的多层感知机(具有256个隐藏单元)
#构建单隐藏层的多层感知机
num_inputs, num_outputs, num_hiddens = 784, 10, 256
# 每个图像包含784个特征 所有图像共有10个类别 而MLP包含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]
此处我们手动实现
def relu(X):
a = torch.zeros_like(X)
return torch.max(X, a)
#torch,max(X,a) 将两tensor按元素比较,将最大值作为新元素,最终返回每个元素均最大的tensor
#此处构建忽略了图像的空间结构,直接reshape为向量
def net(X):
X = X.reshape((-1, num_inputs))
H = relu(X@W1 + b1) # 这里“@”代表矩阵乘法
return (H@W2 + b2)
loss = nn.CrossEntropyLoss(reduction='none')
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)

d2l.predict_ch3(net, test_iter)

3.多层感知机的简洁实现
高级API简化过程
net = nn.Sequential(nn.Flatten(),#将矩阵按需求自动展平为向量
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10))
def init_weights(m):

本文详细介绍了多层感知机(MLP)的原理与实现,包括线性模型的局限性、非线性激活函数如ReLU、Sigmoid和Tanh的作用,以及权重衰减(L2正则化)在防止过拟合中的应用。同时,讨论了暂退法(Dropout)作为提升模型泛化能力的策略,以及前向传播、反向传播和计算图的数学原理。此外,还探讨了数值稳定性和模型初始化的重要性,特别是Xavier初始化在打破神经网络对称性方面的贡献。
最低0.47元/天 解锁文章
1884

被折叠的 条评论
为什么被折叠?



