3 多层感知机

1 多层感知机

线形的假设是很强的, 很多时候也不能拟合所有关系. 为此, 可以在网络中加入更多的层, 来拟合更加复杂的关系.

1.1 隐藏层

Pasted image 20250426122341.png

我们同样假设 XRn×d (n 个样本, d 个特征). 对隐藏层, 假设有 h 个隐藏单元, 则隐藏层输出为 HRn×h, 从而 H=XW(1)+b(1),O=HW(2)+b(2).
但事实上, 这和单层没有任何区别: O=(XW(1)+b(1))W(2)+b(2)=XW(1)W(2)+b(1)W(2)+b(2).
因此只要取 W=W(1)W(2),b=b(1)W(2)+b(2) 即可用单层进行等价替换!
为了实现不平凡的多层效果, 需要添加非线性的激活函数 σ, 例如 softmax 函数: H(1)=σ1(XW(1)+b(1)),H(2)=σ2(H(1)W(2)+b(2)).

1.2 激活函数

1.2.1 ReLU 函数

ReLU(x)=max(x,0).

可以用 y = torch.relu(x) 来计算. 在输入值精确等于 0 时, 导数规定使用左导数 0.
ReLU 有一些变体, 例如 pReLU (参数化 ReLU): pReLU(x)=max(0,x)+αmin(0,x).

1.2.2 Sigmoid 函数

sigmoid(x)=11+exp(x).

它会将值映射到 (0,1). 容易知道: ddxsigmoid(x)=exp(x)(1+exp(x))2=sigmoid(x)(1sigmoid(x)).

1.2.3 tanh 函数

tanh(x)=1exp(2x)1+exp(2x).$$$(1,1)$.$$ddxtanh(x)=1tanh2(x).

2 模型选择 欠拟合 过拟合

3 权重衰减/L2 正则化

在原先的损失函数 L(w,b)=1ni=1n12(wTx(i)+by(i))2 的基础上, 惩罚过大的参数 w, 因此损失函数变为 L(w,b)+λ2||w||2, 此时小批量随机梯度下降的更新变为 w(1ηλ)wη|B|iBx(i)(wTx(i)+by(i)).

3.1 从零实现

3.2 简洁实现

4 暂退法 (Dropout)

4.1 流程

在多层神经网络中, 我们在训练过程中随机丢弃一些神经元(在训练过程的每一次迭代中, 在计算下一层前将当前层的一些节点清零).
对于剩下未被丢弃的节点, 进行规范化(normalization), 来消除偏差, 也即以概率 p 修改中间活性值: h={0,p probability,h1p,else.
例如, 我们在下面的隐藏层删除了 h2,h5, 这样即使在梯度更新的反向传播中他们也消失了.
Pasted image 20250430122015.png

然而在测试时, 所有被 dropout 的值都会参与计算. (测试时 dropout 不参与计算的情形, 仅用于测试网络的稳定性)

4.2 从零实现

import torch
from torch import nn

def dropout_layer(X, dropout):
    assert 0 <= dropout <= 1
    if dropout == 1:
        return torch.zeros_like(X)
    if dropout == 0:
        return X
    mask = (torch.rand(X.shape) > dropout).float()
    return mask * X / (1.0 - dropout)

通常在靠近输入层的地方我们设置较低的 dropout 概率.

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256
dropout1, dropout2 = 0.2, 0.5

class Net(nn.Module):
    def __init__(self, num_inputs, num_outputs, num_hiddens1, num_hiddens2, is_training=True)
        super(Net, self).__init__()
        self.self.num_inputs = num_inputs
        self.training = is_training
        self.lin1 = nn.Linear(num_inputs, num_hiddens1)
        self.lin2 = nn.Linear(num_hiddens1, num_hiddens2)
        self.lin3 = nn.Linear(num_hiddens2, num_outputs)
        self.relu = nn.ReLU()
    
    def forward(self, X):
        H1 = self.relu(self.lin1(X.reshape((-1, self.num_inputs))))
        if self.training == True:
            H1 = dropout_layer(H1, dropout1)
        H2 = self.relu(self.lin2(H1))
        if self.training == True:
            H2 = dropout_layer(H2, dropout2)
        out = self.lin3(H2)
        return out

net = Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)

4.3 简洁实现

net = nn.Sequential(nn.Flatten(),
                    nn.Linear(784, 256),
                    nn.ReLU(),
                    nn.Dropout(dropout1),
                    nn.Linear(256, 256),
                    nn.ReLU(),
                    nn.Dropout(dropout2),
                    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)

5 前向传播 反向传播 计算图

5.1 前向传播

前向传播 (forward propagation/pass), 就是指按顺序计算输出的值. 例如, 我们有一个隐藏层(不包含偏置项), 一个激活层, 一个输出层, 输入为 xRd, 隐藏层权重为 W(1)Rh×d, 输出层为 W(2)Rq×h, 则输出结果为 o=W(2)ϕ(W(1)x)Rq.
我们可以计算带正则项的损失函数 J=l+s=l(o,y)+λ2(||W(1)||F2+||W(2)||F2).
上述流程可以用计算图来表示:
Pasted image 20250430123649.png|400

5.2 反向传播

反向传播是计算参数梯度来更新参数. 需要使用链式法则. 一般地, 给定 Y=f(X),Z=g(Y), ZX=prod(ZY,YX). 这里 prod 表示换位、交换输入位置等必要操作, 对于向量, 它只是矩阵-矩阵乘法.

对于上面的例子, 首先 Jl=1,Js=1. 进而 Jo=prod(Jl,lo)=loRq. 然后正则化项 sW(1)=λW(1),sW(2)=λW(2).
回到输出层 JW(2)=prod(Jo,oW(2))+prod(Js,sW(2))=JohT+λW(2).
进而到隐藏层 Jh=prod(Jo,oh)=W(2)TJo. 由于激活函数 ϕ 是按元素计算的, 需要使用逐元素乘法 : Jz=prod(Jh,hz)=Jhϕ(z).
最后输入层: JW(1)=prod(Jz,zW(1))+prod(Js,sW(1))=JzxT+λW(1).

6 梯度稳定性和模型初始化

6.1 梯度消失与梯度爆炸

6.2 参数初始化: Xavier 初始化

这里不讨论随机正态分布初始化这种做法, 尽管它效果一般来说很有效.
首先考虑没有非线性的全连接层输出: oi=j=1ninwijxj,wiji.i.d(0,σ2),xji.i.d(0,γ2). 此时 E[oi]=j=1ninE[wij]E[xj]=0,Var(oi)=E[oi2](Eoi)2=j=1ninE[wij2]E[xj2]=ninσ2γ2, 因此若要保持输出内容相比 xi 方差不变, ninσ2=1. 而类似的, 在反向传播中我们也需要要求 noutσ2=1, 但我们不能同时满足这两个要求, 因此只需要 12(nin+nout)σ2=1σ=2nin+nout. 现在, 我们从 N(0,σ2=2nin+nout) 中采样权重. 或者, 我们可以从均匀分布 Unif(a,a) 中采样. 为了让两者方差一致, a23=σ2a=6nin+nout, 也即 U(6nin+nout,6nin+nout).

7 环境和分布偏移