权重衰减、Dropout、数值稳定性、Xavier初始化

权重衰减

使用均方范数作为硬性限制

image-20211108225215146

但我们最小化 loss 的时候,需要限制权重 w 的大小,越小的\(\theta\) 意味着更强的正则项。

但实际上,我们不会这么做的,我们只是在做损失函数时候,加入了 \(\parallel w \parallel ^2\) ,就像下面做的那样。

image-20211108225603258

其中\(\lambda\) = 0时候,就没有作用,而\(\lambda \rightarrow \infty\) ,w就会趋于0。

这个\(\lambda\) 是一个超参数,需要自己定义。

形象的显示:

image-20211108225950835

加入了 权重衰减后,w 会被拉到 \(w^*\)

参数更新:

image-20211108230113789

Dropout

dropout和正则化的作用差不多,也是降低模型的过拟合性。

image-20211108230409970

dropout 相当于在层之间加入噪音。但是加入噪音也不要改变其期望。

image-20211108230515861

手写一个二层感知机代码:

import torch
import torch.nn as nn
import torch.nn.functional as F

class MLP(nn.Module):
    def __init__(self, indim, hiddim, outdim, dropout):
        super(MLP, self).__init__()
        self.Lay1 = nn.Linear(indim, hiddim)
        self.Lay2 = nn.Linear(hiddim, outdim)
        self.dropout = dropout
    
    def forward(self, x):
        x = F.ReLU(self.Lay1(x))
        x = F.dropout(x, self.dropout, training = self.training)
        return self.Lay2(x)
    
net = MLP(indim, hiddim, outdim, dropout)

需要注意的是,当我需要训练时候,dropout才会发挥作用,而我预测时应该关掉dropout, dropout本质是作用在权重参数上的正则项。

net.train()# 开启训练
train(net)

net.eval()# 关掉训练
test(net)

image-20211108231649796

注意dropout一般用在MLP上,CNN很少用,而且它只作用在隐藏层上。

数值稳定性

如果神经网络很深的话,就会有一系列问题,包括梯度爆炸和梯度消失。

梯度爆炸

image-20211108231902224

可以看到,梯度反向传播会计算很多次矩阵乘法。

image-20211108232027415

关于下面这个公式的推导:

\[\frac{\partial h^{t}}{\partial h^{t-1}} = diag(\sigma\prime(W^th^{t-1}) )(W^t)^T \]

它实际上来源于:

\[\frac{\partial(Wh)}{\partial h} = W^T \]

但是因为引入了激活函数,所以需要做一个对角矩阵。

image-20211109095655328

可以看到就是多了一个激活函数,基本求导思路没有变。

重新来看梯度爆炸:

image-20211109095832823

梯度爆炸产生的原因就是我们累乘了多个W。

  • 学习率太大了,可能导致大参数,大梯度
  • 学习率低,训练也没有进展。
  • 这就需要在学习中动态调整学习率。
梯度消失

image-20211109100312679

可以看到当数值大的时候,SIGMOD函数对应的导数就很小,还记得先前的那个公式吗?

image-20211109100436895

可以看到\(\prod_{i=t}^{d-1}diag(\sigma\prime(W^ih^(i-1)))\),这玩意就会快速接近0,最终导致梯度消失。

可以看到,梯度爆炸和梯度消失,实际上都和激活函数有点关系,但产生的原因还是不一样的。

当数值太大或者太小都会导致数值问题

模型初始化和激活函数

因为数值太大或者太小都会导致数值问题,所有需要让梯度值在合理的范围内。

image-20211109101105684

梯度归一化

基本思路:

  • 将每层的输出和梯度都看做随机变量。

  • 让每一层的均值和方差都保持一致。

    image-20211109101246991

权重初始化

权重初始化和随机数种子实际上也可以视为是一种超参数。

image-20211109101546390

因为训练刚开始越容易数值不稳定,所以需要找到一个好的权重初始化方式,刚才提到了我们要让梯度每一层的方差和期望都一致。

以 MLP 为例:

正向输出

image-20211109101822594

这个思路有点像数学归纳法,\(E(h^{t-1}) =0 \rightarrow E(h^t) = 0\),再来看方差,证明思路还是一样。

image-20211109102058053

反向梯度

image-20211109102315827

Xavier初始化

image-20211109102415033

Xavier之前在GCN里见到过,当时还奇怪为什么用这种Xavier初始化方式,原来理由是为了数值稳定性。

各种激活函数
线性激活函数

image-20211109102658177

这意味着激活函数需要是\(f(x) = x\)

其他常用激活函数

image-20211109102932915

在零点是,可以认为是\(f(x) = x\),对sigmoid需要进行调整。

总结

权重衰减和dropout实现的都是正则化的效果,使用它们的目的就是降低模型的复杂性,防止过拟合。

在数值稳定性一节里,讲到了为什么会出现梯度爆炸和梯度消失两个问题,维持数值稳定性的两个很重要的点——初始化和激活函数。

posted @ 2021-11-09 10:35  kalice  阅读(410)  评论(0)    收藏  举报