Geeks_Z の Blog Geeks_Z の Blog
首页
  • 学习笔记

    • 《HTML》
    • 《CSS》
    • 《JavaWeb》
    • 《Vue》
  • 后端文章

    • Linux
    • Maven
    • 汇编语言
    • 软件工程
    • 计算机网络概述
    • Conda
    • Pip
    • Shell
    • SSH
    • Mac快捷键
    • Zotero
  • 学习笔记

    • 《数据结构与算法》
    • 《算法设计与分析》
    • 《Spring》
    • 《SpringMVC》
    • 《SpringBoot》
    • 《SpringCloud》
    • 《Nginx》
  • 深度学习文章
  • 学习笔记

    • 《PyTorch》
    • 《ReinforementLearning》
    • 《MetaLearning》
  • 学习笔记

    • 《高等数学》
    • 《线性代数》
    • 《概率论与数理统计》
  • 增量学习
  • 哈希学习
GitHub (opens new window)

Geeks_Z

AI小学生
首页
  • 学习笔记

    • 《HTML》
    • 《CSS》
    • 《JavaWeb》
    • 《Vue》
  • 后端文章

    • Linux
    • Maven
    • 汇编语言
    • 软件工程
    • 计算机网络概述
    • Conda
    • Pip
    • Shell
    • SSH
    • Mac快捷键
    • Zotero
  • 学习笔记

    • 《数据结构与算法》
    • 《算法设计与分析》
    • 《Spring》
    • 《SpringMVC》
    • 《SpringBoot》
    • 《SpringCloud》
    • 《Nginx》
  • 深度学习文章
  • 学习笔记

    • 《PyTorch》
    • 《ReinforementLearning》
    • 《MetaLearning》
  • 学习笔记

    • 《高等数学》
    • 《线性代数》
    • 《概率论与数理统计》
  • 增量学习
  • 哈希学习
GitHub (opens new window)
  • Python

  • MLTutorials

    • 机器学习基础

      • 机器学习术语
      • 单变量线性回归
      • 归一化、标准化和正则化
      • 经典网络
      • 多变量线性回归
      • 逻辑回归
      • 调试策略
      • 激活函数
      • Embedding
      • GCN
      • GAT
      • BayesClassifier
      • 距离函数
      • 损失函数
      • 强化学习
      • 线性判别分析LDA
      • Sequence2sequence
      • Network Compression
      • 机器学习算法集锦从贝叶斯到深度学习及各自优缺点
      • 各种机器学习算法的应用场景
      • 数据集
      • HashLearning
      • 正则化
        • 拟合问题
        • Cost Function
        • Regularized Linear Regression
        • Regularized Logistic Regression
        • Why regularization reduces overfitting?
        • Dropout Regularization
        • Understanding Dropout
        • Other regularization methods
      • 感知机
    • 模型与算法

    • 模型优化

  • 卷积神经网络

  • 循环神经网络

  • Transformer

  • VisionTransformer

  • 扩散模型

  • 计算机视觉

  • PTM

  • MoE

  • LoRAMoE

  • LongTailed

  • 多模态

  • 知识蒸馏

  • PEFT

  • 对比学习

  • 小样本学习

  • 迁移学习

  • 零样本学习

  • 集成学习

  • Mamba

  • PyTorch

  • CL

  • CIL

  • 小样本类增量学习FSCIL

  • UCIL

  • 多模态增量学习MMCL

  • LTCIL

  • DIL

  • 论文阅读与写作

  • 分布外检测

  • GPU

  • 深度学习调参指南

  • AINotes
  • MLTutorials
  • 机器学习基础
Geeks_Z
2022-08-16
目录

正则化

Regularization

拟合问题

对于拟合的表现,可以分为三类情况:

  • 欠拟合(Underfitting)

    无法很好的拟合训练集中的数据,预测值和实际值的误差很大,这类情况被称为欠拟合。拟合模型比较简单(特征选少了)时易出现这类情况。类似于,你上课不好好听,啥都不会,下课也差不多啥都不会。

  • 优良的拟合(Just right)

    不论是训练集数据还是不在训练集中的预测数据,都能给出较为正确的结果。类似于,学霸学神!

  • 过拟合(Overfitting)

    能很好甚至完美拟合训练集中的数据,即 J(θ)→0,但是对于不在训练集中的新数据,预测值和实际值的误差会很大,泛化能力弱,这类情况被称为过拟合。拟合模型过于复杂(特征选多了)时易出现这类情况。类似于,你上课跟着老师做题都会都听懂了,下课遇到新题就懵了不会拓展。

线性模型中的拟合情况(左图欠拟合,右图过拟合):

逻辑分类模型中的拟合情况:

为了度量拟合表现,引入:

  • 偏差(bias)

    指模型的预测值与真实值的偏离程度。偏差越大,预测值偏离真实值越厉害。偏差低意味着能较好地反应训练集中的数据情况。

  • 方差(Variance)

    指模型预测值的离散程度或者变化范围。方差越大,数据的分布越分散,函数波动越大,泛化能力越差。方差低意味着拟合曲线的稳定性高,波动小。

据此,我们有对同一数据的各类拟合情况如下图:

据上图,高偏差意味着欠拟合,高方差意味着过拟合。

我们应尽量使得拟合模型处于低方差(较好地拟合数据)状态且同时处于低偏差(较好地预测新值)的状态。

我们沿用猫咪图片分类这个例子,左边一张是猫咪图片,右边一张不是。理解偏差和方差的两个关键数据是训练集误差(Train set error)和验证集误差(Dev set error),为了方便论证,假设我们可以辨别图片中的小猫,我们用肉眼识别几乎是不会出错的。

假定训练集误差是 1%,为了方便论证,假定验证集误差是 11%,可以看出训练集设置得非常好,而验证集设置相对较差,我们可能过度拟合了训练集,在某种程度上,验证集并没有充分利用交叉验证集的作用,像这种情况,我们称之为“==高方差==”。

通过查看训练集误差和验证集误差,我们便可以诊断算法是否具有高方差。也就是说衡量训练集和验证集误差就可以得出不同结论。

假设训练集误差是 15%,我们把训练集误差写在首行,验证集误差是 16%,假设该案例中人的错误率几乎为 0%,人们浏览这些图片,分辨出是不是猫。算法并没有在训练集中得到很好训练,如果训练数据的拟合度不高,就是数据欠拟合,就可以说这种算法偏差比较高。相反,它对于验证集产生的结果却是合理的,验证集中的错误率只比训练集的多了 1%,所以这种算法偏差高,因为它甚至不能拟合训练集,这与上一张幻灯片最左边的图片相似。

再举一个例子,训练集误差是 15%,偏差相当高,但是,验证集的评估结果更糟糕,错误率达到 30%,在这种情况下,我会认为这种算法偏差高,因为它在训练集上结果不理想,而且方差也很高,这是方差偏差都很糟糕的情况。

再看最后一个例子,训练集误差是 0.5%,验证集误差是 1%,用户看到这样的结果会很开心,猫咪分类器只有 1%的错误率,偏差和方差都很低。

有一点我先在这个简单提一下,具体的留在后面课程里讲,这些分析都是基于假设预测的,假设人眼辨别的错误率接近 0%,一般来说,最优误差也被称为贝叶斯误差,所以,最优误差接近 0%,我就不在这里细讲了,如果最优误差或贝叶斯误差非常高,比如 15%。我们再看看这个分类器(训练误差 15%,验证误差 16%),15%的错误率对训练集来说也是非常合理的,偏差不高,方差也非常低。

当所有分类器都不适用时,如何分析偏差和方差呢?比如,图片很模糊,即使是人眼,或者没有系统可以准确无误地识别图片,在这种情况下,最优误差会更高,那么分析过程就要做些改变了,我们暂时先不讨论这些细微差别,重点是通过查看训练集误差,我们可以判断数据拟合情况,至少对于训练数据是这样,可以判断是否有偏差问题,然后查看错误率有多高。当完成训练集训练,开始使用验证集验证时,我们可以判断方差是否过高,从训练集到验证集的这个过程中,我们可以判断方差是否过高。

以上分析的前提都是假设基本误差很小,训练集和验证集数据来自相同分布,如果没有这些假设作为前提,分析过程更加复杂,我们将会在稍后课程里讨论。

上一张幻灯片,我们讲了高偏差和高方差的情况,大家应该对优质分类器有了一定的认识,偏差和方差都高是什么样子呢?这种情况对于两个衡量标准来说都是非常糟糕的。

我们之前讲过,这样的分类器,会产生高偏差,因为它的数据拟合度低,像这种接近线性的分类器,数据拟合度低。

但是如果我们稍微改变一下分类器,我用紫色笔画出,它会过度拟合部分数据,用紫色线画出的分类器具有高偏差和高方差,偏差高是因为它几乎是一条线性分类器,并未拟合数据。

这种二次曲线能够很好地拟合数据。

这条曲线中间部分灵活性非常高,却过度拟合了这两个样本,这类分类器偏差很高,因为它几乎是线性的。

而采用曲线函数或二次元函数会产生高方差,因为它曲线灵活性太高以致拟合了这两个错误样本和中间这些活跃数据。

这看起来有些不自然,从两个维度上看都不太自然,但对于高维数据,有些数据区域偏差高,有些数据区域方差高,所以在高维数据中采用这种分类器看起来就不会那么牵强了。

避免过拟合的方法有:

  • 减少特征的数量
    • 手动选取需保留的特征
    • 使用模型选择算法来选取合适的特征(如 PCA 算法)
    • 减少特征的方式易丢失有用的特征信息
  • 正则化(Regularization)
    • 可保留所有参数(许多有用的特征都能轻微影响结果)
    • 减少/惩罚各参数大小(magnitude),以减轻各参数对模型的影响程度
    • 当有很多参数对于模型只有轻微影响时,正则化方法的表现很好

Cost Function

很多时候由于特征数量过多,过拟合时我们很难选出要保留的特征,这时候应用正则化方法则是很好的选择。

上文中,θ0+θ1x+θ2x2+θ3x3+θ4x4 这样一个复杂的多项式较易过拟合,在不减少特征的情况下,如果能消除类似于 θ3x3、θ4x4 等复杂部分,那复杂函数就变得简单了。

为了保留各个参数的信息,不修改假设函数,改而修改代价函数:

minθ12m∑i=1m(hθ(x(i))−y(i))2+1000⋅θ32+1000⋅θ42

上式中,我们在代价函数中增加了 θ3、θ4 的惩罚项(penalty term) 1000⋅θ32+1000⋅θ42,如果要最小化代价函数,那么势必需要极大地减小 θ3、θ4,从而使得假设函数中的 θ3x3、θ4x4 这两项的参数非常小,就相当于没有了,假设函数也就**“变得”简单**了,从而在保留各参数的情况下避免了过拟合问题。

根据上面的讨论,有时也无法决定要减少哪个参数,故统一惩罚除了 θ0 外的所有参数。

代价函数:

J(θ)=12m[∑i=1m(hθ(x(i))−y(i))2+λ∑j=1nθj2]

λ: 正则化参数(Regularization Parameter),λ>0

∑j=1n: 不惩罚基础参数 θ0

λ∑j=1nθj2: 正则化项

λ 正则化参数类似于学习速率,也需要我们自行对其选择一个合适的值。

  • 过大
    • 导致模型欠拟合(假设可能会变成近乎 x=θ0 的直线 )
    • 无法正常去过拟问题
    • 梯度下降可能无法收敛
  • 过小
    • 无法避免过拟合(等于没有)

正则化符合奥卡姆剃刀(Occam's razor)原理。在所有可能选择的模型中,能够很好地解释已知数据并且十分简单才是最好的模型,也就是应该选择的模型。从贝叶斯估计的角度来看,正则化项对应于模型的先验概率。可以假设复杂的模型有较大的先验概率,简单的模型有较小的先验概率。

正则化是结构风险最小化策略的实现,是去过拟合问题的典型方法,虽然看起来多了个一参数多了一重麻烦,后文会介绍自动选取正则化参数的方法。模型越复杂,正则化参数值就越大。比如,正则化项可以是模型参数向量的范数。

Regularized Linear Regression

应用正则化的线性回归梯度下降算法:

Repeat{θ0:=θ0−α1m∑i=1m(hθ(x(i))−y(i))x0(i)θj:=θj−α[(1m∑i=1m(hθ(x(i))−y(i))xj(i))+λmθj],j∈{1,2...n}}

也可以移项得到更新表达式的另一种表示形式

θj:=θj(1−αλm)−α1m∑i=1m(hθ(x(i))−y(i))xj(i)

λmθj: 正则化项

应用正则化的正规方程法[^2]:

θ=(XTX+λ⋅L)−1XTywhereL=[011⋱1]

λ⋅L: 正则化项

L: 第一行第一列为 0 的 n+1 维单位矩阵

Matlab/Octave 代码:

>> L = eye(5)
>> L(1,1) = 0

L =

     0     0     0     0     0
     0     1     0     0     0
     0     0     1     0     0
     0     0     0     1     0
     0     0     0     0     1
1
2
3
4
5
6
7
8
9
10

前文提到正则化可以解决正规方程法中不可逆的问题,即增加了 λ⋅L 正则化项后,可以保证 XTX+λ⋅L 可逆(invertible),即便 XTX 不可逆(non-invertible)。

Regularized Logistic Regression

为逻辑回归的代价函数添加正则化项:

J(θ)=−1m∑i=1m[y(i)log⁡(hθ(x(i)))+(1−y(i))log⁡(1−hθ(x(i)))]+λ2m∑j=1nθj2

前文已经证明过逻辑回归和线性回归的代价函数的求导结果是一样的,此处通过给正则化项添加常数 12,则其求导结果也就一样了。

从而有应用正则化的逻辑回归梯度下降算法:

Repeat{θ0:=θ0−α1m∑i=1m(hθ(x(i))−y(i))x0(i)θj:=θj−α[(1m∑i=1m(hθ(x(i))−y(i))xj(i))+λmθj],j∈{1,2...n}}

我们用逻辑回归来实现这些设想,求成本函数J 最小值,它是我们定义的成本函数,参数包含一些训练数据和不同数据中个体预测的损失,w b 逻辑回归的两个参数,w 一个多维度参数矢量,b 一个实数。在逻辑回归函数中加入正则化,只需添加参数 λ,也就是正则化参数,一会儿再详细讲。

λ2m 以w 数的平方,其中‖w‖22 w 欧几里德范数的平方,等于wj(j 值从 1 到nx)平方的和,也可表示为wTw,也就是向量参数w 的欧几里德范数(2 范数)的平方,此方法称为L2 则化,因为这里用了欧几里德范数,被称为向量参数w L2 数。

为什么只正则化参数w?为什么不再加上参数 b 呢?你可以这么做,只是我习惯省略不写,因为w 常是一个高维参数矢量,已经可以表达高偏差问题,w 能包含有很多参数,我们不可能拟合所有参数,而b 是单个数字,所以w 乎涵盖所有参数,而不是b,如果加了参数b,其实也没太大影响,因为b 是众多参数中的一个,所以我通常省略不计,如果你想加上这个参数,完全没问题。

L2 则化是最常见的正则化类型,你们可能听说过L1 则化,L1 则化,加的不是L2 数,而是正则项λm 以∑j=1nx|w|,∑j=1nx|w| 被称为参数w 量的L1 数,无论分母是m 是2m,它都是一个比例常量。

如果用的是L1 则化,w 终会是稀疏的,也就是说w 量中有很多 0,有人说这样有利于压缩模型,因为集合中参数均为 0,存储模型所占用的内存更少。实际上,虽然L1 则化使模型变得稀疏,却没有降低太多存储内存,所以我认为这并不是L1 则化的目的,至少不是为了压缩模型,人们在训练网络时,越来越倾向于使用L2 则化。

我们来看最后一个细节,λ 正则化参数,我们通常使用验证集或交叉验证集来配置这个参数,尝试各种各样的数据,寻找最好的参数,我们要考虑训练集之间的权衡,把参数设置为较小值,这样可以避免过拟合,所以 λ 是另外一个需要调整的超级参数,顺便说一下,为了方便写代码,在Python编程语言中,λ 一个保留字段,编写代码时,我们删掉a,写成lambd,以免与Python中的保留字段冲突,这就是在逻辑回归函数中实现L2 则化的过程,如何在神经网络中实现L2 则化呢?

神经网络含有一个成本函数,该函数包含W[1],b[1] W[l],b[l] 有参数,字母L 神经网络所含的层数,因此成本函数等于m 训练样本损失函数的总和乘以1m,正则项为λ2m∑1L|W[l]|2,我们称||W[l]||2 范数平方,这个矩阵范数||W[l]||2(即平方范数),被定义为矩阵中所有元素的平方求和,

我们看下求和公式的具体参数,第一个求和符号其值i 1 到n[l−1],第二个其J 从 1 到n[l],因为W 一个n[l]×n[l−1] 多维矩阵,n[l] 示l 层单元的数量,n[l−1] 示第l−1 隐藏单元的数量。

该矩阵范数被称作“弗罗贝尼乌斯范数”,用下标F 注”,鉴于线性代数中一些神秘晦涩的原因,我们不称之为“矩阵L2 数”,而称它为“弗罗贝尼乌斯范数”,矩阵L2 数听起来更自然,但鉴于一些大家无须知道的特殊原因,按照惯例,我们称之为“弗罗贝尼乌斯范数”,它表示一个矩阵中所有元素的平方和。

该如何使用该范数实现梯度下降呢?

用backprop计算出dW 值,backprop会给出J W 偏导数,实际上是$ W^{[l]},把,把W^{[l]}$ 换为W[l] 去学习率乘以dW。

这就是之前我们额外增加的正则化项,既然已经增加了这个正则项,现在我们要做的就是给dW 上这一项λmW[l],然后计算这个更新项,使用新定义的dW[l],它的定义含有相关参数代价函数导数和,以及最后添加的额外正则项,这也是L2 则化有时被称为“权重衰减”的原因。

我们用$ dW^{[l]}$ 定义替换此处的dW[l],可以看到,W[l] 定义被更新为W[l] 去学习率α 乘以backprop 再加上λmW[l]。

该正则项说明,不论W[l] 什么,我们都试图让它变得更小,实际上,相当于我们给矩阵 W 乘以(1−αλm) 的权重,矩阵W 去αλm 的它,也就是用这个系数(1−αλm) 以矩阵W,该系数小于 1,因此L2 数正则化也被称为“权重衰减”,因为它就像一般的梯度下降,W 更新为少了α 以backprop输出的最初梯度值,同时W 乘以了这个系数,这个系数小于 1,因此L2 则化也被称为“权重衰减”。

我不打算这么叫它,之所以叫它“权重衰减”是因为这两项相等,权重指标乘以了一个小于 1 的系数。

Why regularization reduces overfitting?

为什么正则化有利于预防过拟合呢?为什么它可以减少方差问题?我们通过两个例子来直观体会一下。

左图是高偏差,右图是高方差,中间是Just Right,这几张图我们在前面课程中看到过。

现在我们来看下这个庞大的深度拟合神经网络。我知道这张图不够大,深度也不够,但你可以想象这是一个过拟合的神经网络。这是我们的代价函数J,含有参数W,b。我们添加正则项,它可以避免数据权值矩阵过大,这就是弗罗贝尼乌斯范数,为什么压缩L2 数,或者弗罗贝尼乌斯范数或者参数可以减少过拟合?

直观上理解就是如果正则化λ 置得足够大,权重矩阵W 设置为接近于 0 的值,直观理解就是把多隐藏单元的权重设为 0,于是基本上消除了这些隐藏单元的许多影响。如果是这种情况,这个被大大简化了的神经网络会变成一个很小的网络,小到如同一个逻辑回归单元,可是深度却很大,它会使这个网络从过度拟合的状态更接近左图的高偏差状态。

但是λ 存在一个中间值,于是会有一个接近“Just Right”的中间状态。

直观理解就是λ 加到足够大,W 接近于 0,实际上是不会发生这种情况的,我们尝试消除或至少减少许多隐藏单元的影响,最终这个网络会变得更简单,这个神经网络越来越接近逻辑回归,我们直觉上认为大量隐藏单元被完全消除了,其实不然,实际上是该神经网络的所有隐藏单元依然存在,但是它们的影响变得更小了。神经网络变得更简单了,貌似这样更不容易发生过拟合,因此我不确定这个直觉经验是否有用,不过在编程中执行正则化时,你实际看到一些方差减少的结果。

我们再来直观感受一下,正则化为什么可以预防过拟合,假设我们用的是这样的双曲线激活函数。

用g(z) 示tanh(z),我们发现如果 z 非常小,比如 z 只涉及很小范围的参数(图中原点附近的红色区域),这里我们利用了双曲正切函数的线性状态,只要z 以扩展为这样的更大值或者更小值,激活函数开始变得非线性。

现在你应该摒弃这个直觉,如果正则化参数 λ 很大,激活函数的参数会相对较小,因为代价函数中的参数变大了,如果W 小,

如果W 小,相对来说,z 会很小。

特别是,如果z 值最终在这个范围内,都是相对较小的值,g(z) 致呈线性,每层几乎都是线性的,和线性回归函数一样。

第一节课我们讲过,如果每层都是线性的,那么整个网络就是一个线性网络,即使是一个非常深的深层网络,因具有线性激活函数的特征,最终我们只能计算线性函数,因此,它不适用于非常复杂的决策,以及过度拟合数据集的非线性决策边界,如同我们在幻灯片中看到的过度拟合高方差的情况。

总结一下,如果正则化参数变得很大,参数W 小,z 会相对变小,此时忽略b 影响,z 相对变小,实际上,z 取值范围很小,这个激活函数,也就是曲线函数tanh 相对呈线性,整个神经网络会计算离线性函数近的值,这个线性函数非常简单,并不是一个极复杂的高度非线性函数,不会发生过拟合。

大家在编程作业里实现正则化的时候,会亲眼看到这些结果,总结正则化之前,我给大家一个执行方面的小建议,在增加正则化项时,应用之前定义的代价函数J,我们做过修改,增加了一项,目的是预防权重过大。

如果你使用的是梯度下降函数,在调试梯度下降时,其中一步就是把代价函数J 计成这样一个函数,在调试梯度下降时,它代表梯度下降的调幅数量。可以看到,代价函数对于梯度下降的每个调幅都单调递减。如果你实施的是正则化函数,请牢记,J 经有一个全新的定义。如果你用的是原函数J,也就是这第一个项正则化项,你可能看不到单调递减现象,为了调试梯度下降,请务必使用新定义的J 数,它包含第二个正则化项,否则函数J 能不会在所有调幅范围内都单调递减。

这就是L2 则化,它是我在训练深度学习模型时最常用的一种方法。在深度学习中,还有一种方法也用到了正则化,就是dropout正则化,我们下节课再讲。

Dropout Regularization

除了L2 则化,还有一个非常实用的正则化方法——“Dropout(随机失活)”,我们来看看它的工作原理。

假设你在训练上图这样的神经网络,它存在过拟合,这就是dropout所要处理的,我们复制这个神经网络,dropout会遍历网络的每一层,并设置消除神经网络中节点的概率。假设网络中的每一层,每个节点都以抛硬币的方式设置概率,每个节点得以保留和消除的概率都是 0.5,设置完节点概率,我们会消除一些节点,然后删除掉从该节点进出的连线,最后得到一个节点更少,规模更小的网络,然后用backprop方法进行训练。

这是网络节点精简后的一个样本,对于其它样本,我们照旧以抛硬币的方式设置概率,保留一类节点集合,删除其它类型的节点集合。对于每个训练样本,我们都将采用一个精简后神经网络来训练它,这种方法似乎有点怪,单纯遍历节点,编码也是随机的,可它真的有效。不过可想而知,我们针对每个训练样本训练规模小得多的网络,最后你可能会认识到为什么要正则化网络,因为我们在训练规模小得多的网络。

如何实施dropout呢?方法有几种,接下来我要讲的是最常用的方法,即inverted dropout(反向随机失活),出于完整性考虑,我们用一个三层(l=3)网络来举例说明。编码中会有很多涉及到 3 的地方。我只举例说明如何在某一层中实施dropout。

首先要定义向量d,d[3] 示网络第三层的dropout向量:

d3 = np.random.rand(a3.shape[0],a3.shape[1])

然后看它是否小于某数,我们称之为keep-prob,keep-prob是一个具体数字,上个示例中它是 0.5,而本例中它是 0.8,它表示保留某个隐藏单元的概率,此处keep-prob等于 0.8,它意味着消除任意一个隐藏单元的概率是 0.2,它的作用就是生成随机矩阵,如果对a[3] 行因子分解,效果也是一样的。d[3] 一个矩阵,每个样本和每个隐藏单元,其中d[3] 的对应值为 1 的概率都是 0.8,对应为 0 的概率是 0.2,随机数字小于 0.8。它等于 1 的概率是 0.8,等于 0 的概率是 0.2。

接下来要做的就是从第三层中获取激活函数,这里我们叫它a[3],a[3] 有要计算的激活函数,a[3] 于上面的a[3] 以d[3],a3 =np.multiply(a3,d3),这里是元素相乘,也可写为a3∗=d3,它的作用就是让d[3] 所有等于 0 的元素(输出),而各个元素等于 0 的概率只有 20%,乘法运算最终把d[3] 相应元素输出,即让d[3] 0 元素与a[3] 相对元素归零。

如果用python实现该算法的话,d[3] 是一个布尔型数组,值为true和false,而不是 1 和 0,乘法运算依然有效,python会把true和false翻译为 1 和 0,大家可以用python尝试一下。

最后,我们向外扩展a[3],用它除以 0.8,或者除以keep-prob参数。

下面我解释一下为什么要这么做,为方便起见,我们假设第三隐藏层上有 50 个单元或 50 个神经元,在一维上a[3] 50,我们通过因子分解将它拆分成50×m 的,保留和删除它们的概率分别为 80%和 20%,这意味着最后被删除或归零的单元平均有 10(50×20%=10)个,现在我们看下z[4],z[4]=w[4]a[3]+b[4],我们的预期是,a[3] 少 20%,也就是说a[3] 有 20%的元素被归零,为了不影响z[4] 期望值,我们需要用w[4]a[3]/0.8,它将会修正或弥补我们所需的那 20%,a[3] 期望值不会变,划线部分就是所谓的dropout方法。

它的功能是,不论keep-prop的值是多少 0.8,0.9 甚至是 1,如果keep-prop设置为 1,那么就不存在dropout,因为它会保留所有节点。反向随机失活(inverted dropout)方法通过除以keep-prob,确保a[3] 期望值不变。

事实证明,在测试阶段,当我们评估一个神经网络时,也就是用绿线框标注的反向随机失活方法,使测试阶段变得更容易,因为它的数据扩展问题变少,我们将在下节课讨论。

据我了解,目前实施dropout最常用的方法就是Inverted dropout,建议大家动手实践一下。Dropout早期的迭代版本都没有除以keep-prob,所以在测试阶段,平均值会变得越来越复杂,不过那些版本已经不再使用了。

现在你使用的是d 量,你会发现,不同的训练样本,清除不同的隐藏单元也不同。实际上,如果你通过相同训练集多次传递数据,每次训练数据的梯度不同,则随机对不同隐藏单元归零,有时却并非如此。比如,需要将相同隐藏单元归零,第一次迭代梯度下降时,把一些隐藏单元归零,第二次迭代梯度下降时,也就是第二次遍历训练集时,对不同类型的隐藏层单元归零。向量d d[3] 来决定第三层中哪些单元归零,无论用foreprop还是backprop,这里我们只介绍了foreprob。

如何在测试阶段训练算法,在测试阶段,我们已经给出了x,或是想预测的变量,用的是标准计数法。我用a[0],第 0 层的激活函数标注为测试样本x,我们在测试阶段不使用dropout函数,尤其是像下列情况:

z[1]=w[1]a[0]+b[1]

a[1]=g[1](z[1])

z[2]=w[2]a[1]+b[2]

a[2]=…

以此类推直到最后一层,预测值为y^。

显然在测试阶段,我们并未使用dropout,自然也就不用抛硬币来决定失活概率,以及要消除哪些隐藏单元了,因为在测试阶段进行预测时,我们不期望输出结果是随机的,如果测试阶段应用dropout函数,预测会受到干扰。理论上,你只需要多次运行预测处理过程,每一次,不同的隐藏单元会被随机归零,预测处理遍历它们,但计算效率低,得出的结果也几乎相同,与这个不同程序产生的结果极为相似。

Inverted dropout函数在除以keep-prob时可以记住上一步的操作,目的是确保即使在测试阶段不执行dropout来调整数值范围,激活函数的预期结果也不会发生变化,所以没必要在测试阶段额外添加尺度参数,这与训练阶段不同。

l=keep−prob

这就是dropout,大家可以通过本周的编程练习来执行这个函数,亲身实践一下。

为什么dropout会起作用呢?下节课我们将更加直观地了解dropout的具体功能。

Understanding Dropout

Dropout可以随机删除网络中的神经单元,他为什么可以通过正则化发挥如此大的作用呢?

直观上理解:不要依赖于任何一个特征,因为该单元的输入可能随时被清除,因此该单元通过这种方式传播下去,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和之前讲的L2 则化类似;实施dropout的结果使它会压缩权重,并完成一些预防过拟合的外层正则化;L2 不同权重的衰减是不同的,它取决于激活函数倍增的大小。

总结一下,dropout的功能类似于L2 则化,与L2 则化不同的是应用方式不同会带来一点点小变化,甚至更适用于不同的输入范围。

第二个直观认识是,我们从单个神经元入手,如图,这个单元的工作就是输入并生成一些有意义的输出。通过dropout,该单元的输入几乎被消除,有时这两个单元会被删除,有时会删除其它单元,就是说,我用紫色圈起来的这个单元,它不能依靠任何特征,因为特征都有可能被随机清除,或者说该单元的输入也都可能被随机清除。我不愿意把所有赌注都放在一个节点上,不愿意给任何一个输入加上太多权重,因为它可能会被删除,因此该单元将通过这种方式积极地传播开,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和我们之前讲过的L2 则化类似,实施dropout的结果是它会压缩权重,并完成一些预防过拟合的外层正则化。

事实证明,dropout被正式地作为一种正则化的替代形式,L2 不同权重的衰减是不同的,它取决于倍增的激活函数的大小。

总结一下,dropout的功能类似于L2 则化,与L2 则化不同的是,被应用的方式不同,dropout也会有所不同,甚至更适用于不同的输入范围。

实施dropout的另一个细节是,这是一个拥有三个输入特征的网络,其中一个要选择的参数是keep-prob,它代表每一层上保留单元的概率。所以不同层的keep-prob也可以变化。第一层,矩阵W[1] 7×3,第二个权重矩阵W[2] 7×7,第三个权重矩阵W[3] 3×7,以此类推,W[2] 最大的权重矩阵,因为W[2] 有最大参数集,即 7×7,为了预防矩阵的过拟合,对于这一层,我认为这是第二层,它的keep-prob值应该相对较低,假设是 0.5。对于其它层,过拟合的程度可能没那么严重,它们的keep-prob值可能高一些,可能是 0.7,这里是 0.7。如果在某一层,我们不必担心其过拟合的问题,那么keep-prob可以为 1,为了表达清除,我用紫色线笔把它们圈出来,每层keep-prob的值可能不同。

注意keep-prob的值是 1,意味着保留所有单元,并且不在这一层使用dropout,对于有可能出现过拟合,且含有诸多参数的层,我们可以把keep-prob设置成比较小的值,以便应用更强大的dropout,有点像在处理L2 则化的正则化参数λ,我们尝试对某些层施行更多正则化,从技术上讲,我们也可以对输入层应用dropout,我们有机会删除一个或多个输入特征,虽然现实中我们通常不这么做,keep-prob的值为 1,是非常常用的输入值,也可以用更大的值,或许是 0.9。但是消除一半的输入特征是不太可能的,如果我们遵守这个准则,keep-prob会接近于 1,即使你对输入层应用dropout。

总结一下,如果你担心某些层比其它层更容易发生过拟合,可以把某些层的keep-prob值设置得比其它层更低,缺点是为了使用交叉验证,你要搜索更多的超级参数,另一种方案是在一些层上应用dropout,而有些层不用dropout,应用dropout的层只含有一个超级参数,就是keep-prob。

结束前分享两个实施过程中的技巧,实施dropout,在计算机视觉领域有很多成功的第一次。计算视觉中的输入量非常大,输入太多像素,以至于没有足够的数据,所以dropout在计算机视觉中应用得比较频繁,有些计算机视觉研究人员非常喜欢用它,几乎成了默认的选择,但要牢记一点,dropout是一种正则化方法,它有助于预防过拟合,因此除非算法过拟合,不然我是不会使用dropout的,所以它在其它领域应用得比较少,主要存在于计算机视觉领域,因为我们通常没有足够的数据,所以一直存在过拟合,这就是有些计算机视觉研究人员如此钟情于dropout函数的原因。直观上我认为不能概括其它学科。

dropout一大缺点就是代价函数J 再被明确定义,每次迭代,都会随机移除一些节点,如果再三检查梯度下降的性能,实际上是很难进行复查的。定义明确的代价函数J 次迭代后都会下降,因为我们所优化的代价函数J 际上并没有明确定义,或者说在某种程度上很难计算,所以我们失去了调试工具来绘制这样的图片。我通常会关闭dropout函数,将keep-prob的值设为 1,运行代码,确保 J 函数单调递减。然后打开dropout函数,希望在dropout过程中,代码并未引入bug。我觉得你也可以尝试其它方法,虽然我们并没有关于这些方法性能的数据统计,但你可以把它们与dropout方法一起使用。

Other regularization methods

除了L2 则化和随机失活(dropout)正则化,还有几种方法可以减少神经网络中的过拟合:

一.数据扩增

假设你正在拟合猫咪图片分类器,如果你想通过扩增训练数据来解决过拟合,但扩增数据代价高,而且有时候我们无法扩增数据,但我们可以通过添加这类图片来增加训练集。例如,水平翻转图片,并把它添加到训练集。所以现在训练集中有原图,还有翻转后的这张图片,所以通过水平翻转图片,训练集则可以增大一倍,因为训练集有冗余,这虽然不如我们额外收集一组新图片那么好,但这样做节省了获取更多猫咪图片的花费。

除了水平翻转图片,你也可以随意裁剪图片,这张图是把原图旋转并随意放大后裁剪的,仍能辨别出图片中的猫咪。

通过随意翻转和裁剪图片,我们可以增大数据集,额外生成假训练数据。和全新的,独立的猫咪图片数据相比,这些额外的假的数据无法包含像全新数据那么多的信息,但我们这么做基本没有花费,代价几乎为零,除了一些对抗性代价。以这种方式扩增算法数据,进而正则化数据集,减少过拟合比较廉价。

像这样人工合成数据的话,我们要通过算法验证,图片中的猫经过水平翻转之后依然是猫。大家注意,我并没有垂直翻转,因为我们不想上下颠倒图片,也可以随机选取放大后的部分图片,猫可能还在上面。

对于光学字符识别,我们还可以通过添加数字,随意旋转或扭曲数字来扩增数据,把这些数字添加到训练集,它们仍然是数字。为了方便说明,我对字符做了强变形处理,所以数字 4 看起来是波形的,其实不用对数字 4 做这么夸张的扭曲,只要轻微的变形就好,我做成这样是为了让大家看的更清楚。实际操作的时候,我们通常对字符做更轻微的变形处理。因为这几个 4 看起来有点扭曲。所以,数据扩增可作为正则化方法使用,实际功能上也与正则化相似。

二.early stopping

还有另外一种常用的方法叫作early stopping,运行梯度下降时,我们可以绘制训练误差,或只绘制代价函数J 优化过程,在训练集上用 0-1 记录分类误差次数。呈单调下降趋势,如图。

因为在训练过程中,我们希望训练误差,代价函数J 在下降,通过early stopping,我们不但可以绘制上面这些内容,还可以绘制验证集误差,它可以是验证集上的分类误差,或验证集上的代价函数,逻辑损失和对数损失等,你会发现,验证集误差通常会先呈下降趋势,然后在某个节点处开始上升,early stopping的作用是,你会说,神经网络已经在这个迭代过程中表现得很好了,我们在此停止训练吧,得到验证集误差,它是怎么发挥作用的?

当你还未在神经网络上运行太多迭代过程的时候,参数w 近 0,因为随机初始化w 时,它的值可能都是较小的随机值,所以在你长期训练神经网络之前w 然很小,在迭代过程和训练过程中w 值会变得越来越大,比如在这儿,神经网络中参数w 值已经非常大了,所以early stopping要做就是在中间点停止迭代过程,我们得到一个w 中等大小的弗罗贝尼乌斯范数,与L2 则化相似,选择参数 w 范数较小的神经网络,但愿你的神经网络过度拟合不严重。

术语early stopping代表提早停止训练神经网络,训练神经网络时,我有时会用到early stopping,但是它也有一个缺点,我们来了解一下。

我认为机器学习过程包括几个步骤,其中一步是选择一个算法来优化代价函数J,我们有很多种工具来解决这个问题,如梯度下降,后面我会介绍其它算法,例如Momentum,RMSprop和Adam等等,但是优化代价函数J 后,我也不想发生过拟合,也有一些工具可以解决该问题,比如正则化,扩增数据等等。

在机器学习中,超级参数激增,选出可行的算法也变得越来越复杂。我发现,如果我们用一组工具优化代价函数J,机器学习就会变得更简单,在重点优化代价函数J ,你只需要留意w b,J(w,b) 值越小越好,你只需要想办法减小这个值,其它的不用关注。然后,预防过拟合还有其他任务,换句话说就是减少方差,这一步我们用另外一套工具来实现,这个原理有时被称为“正交化”。思路就是在一个时间做一个任务,后面课上我会具体介绍正交化,如果你还不了解这个概念,不用担心。

但对我来说early stopping的主要缺点就是你不能独立地处理这两个问题,因为提早停止梯度下降,也就是停止了优化代价函数J,因为现在你不再尝试降低代价函数J,所以代价函数J 值可能不够小,同时你又希望不出现过拟合,你没有采取不同的方式来解决这两个问题,而是用一种方法同时解决两个问题,这样做的结果是我要考虑的东西变得更复杂。

如果不用early stopping,另一种方法就是L2 则化,训练神经网络的时间就可能很长。我发现,这导致超级参数搜索空间更容易分解,也更容易搜索,但是缺点在于,你必须尝试很多正则化参数λ 值,这也导致搜索大量λ 的计算代价太高。

Early stopping的优点是,只运行一次梯度下降,你可以找出w 较小值,中间值和较大值,而无需尝试L2 则化超级参数λ 很多值。

如果你还不能完全理解这个概念,没关系,下节课我们会详细讲解正交化,这样会更好理解。

虽然L2 则化有缺点,可还是有很多人愿意用它。吴恩达老师个人更倾向于使用L2 则化,尝试许多不同的λ ,假设你可以负担大量计算的代价。而使用early stopping也能得到相似结果,还不用尝试这么多λ 。

这节课我们讲了如何使用数据扩增,以及如何使用early stopping降低神经网络中的方差或预防过拟合。

[^2]: week2 - 4.6

#机器学习教程
上次更新: 2025/06/25, 11:25:50
HashLearning
感知机

← HashLearning 感知机→

最近更新
01
帮助信息查看
06-08
02
常用命令
06-08
03
学习资源
06-07
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Geeks_Z | MIT License
京公网安备 11010802040735号 | 京ICP备2022029989号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式