正则化
Regularization
拟合问题
对于拟合的表现,可以分为三类情况:
欠拟合(Underfitting)
无法很好的拟合训练集中的数据,预测值和实际值的误差很大,这类情况被称为欠拟合。拟合模型比较简单(特征选少了)时易出现这类情况。类似于,你上课不好好听,啥都不会,下课也差不多啥都不会。
优良的拟合(Just right)
不论是训练集数据还是不在训练集中的预测数据,都能给出较为正确的结果。类似于,学霸学神!
过拟合(Overfitting)
能很好甚至完美拟合训练集中的数据,即
,但是对于不在训练集中的新数据,预测值和实际值的误差会很大,泛化能力弱,这类情况被称为过拟合。拟合模型过于复杂(特征选多了)时易出现这类情况。类似于,你上课跟着老师做题都会都听懂了,下课遇到新题就懵了不会拓展。
线性模型中的拟合情况(左图欠拟合,右图过拟合):
逻辑分类模型中的拟合情况:
为了度量拟合表现,引入:
偏差(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
很多时候由于特征数量过多,过拟合时我们很难选出要保留的特征,这时候应用正则化方法则是很好的选择。
上文中,
为了保留各个参数的信息,不修改假设函数,改而修改代价函数:
上式中,我们在代价函数中增加了
根据上面的讨论,有时也无法决定要减少哪个参数,故统一惩罚除了
代价函数:
: 正则化参数(Regularization Parameter),
: 不惩罚基础参数
: 正则化项
- 过大
- 导致模型欠拟合(假设可能会变成近乎
的直线 ) - 无法正常去过拟问题
- 梯度下降可能无法收敛
- 导致模型欠拟合(假设可能会变成近乎
- 过小
- 无法避免过拟合(等于没有)
正则化符合奥卡姆剃刀(Occam's razor)原理。在所有可能选择的模型中,能够很好地解释已知数据并且十分简单才是最好的模型,也就是应该选择的模型。从贝叶斯估计的角度来看,正则化项对应于模型的先验概率。可以假设复杂的模型有较大的先验概率,简单的模型有较小的先验概率。
正则化是结构风险最小化策略的实现,是去过拟合问题的典型方法,虽然看起来多了个一参数多了一重麻烦,后文会介绍自动选取正则化参数的方法。模型越复杂,正则化参数值就越大。比如,正则化项可以是模型参数向量的范数。
Regularized Linear Regression
应用正则化的线性回归梯度下降算法:
也可以移项得到更新表达式的另一种表示形式
: 正则化项
应用正则化的正规方程法[^2]:
: 正则化项
: 第一行第一列为 的 维单位矩阵
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
2
3
4
5
6
7
8
9
10
前文提到正则化可以解决正规方程法中不可逆的问题,即增加了
Regularized Logistic Regression
为逻辑回归的代价函数添加正则化项:
前文已经证明过逻辑回归和线性回归的代价函数的求导结果是一样的,此处通过给正则化项添加常数
从而有应用正则化的逻辑回归梯度下降算法:
我们用逻辑回归来实现这些设想,求成本函数
为什么只正则化参数
如果用的是
我们来看最后一个细节,
神经网络含有一个成本函数,该函数包含
我们看下求和公式的具体参数,第一个求和符号其值
该矩阵范数被称作“弗罗贝尼乌斯范数”,用下标
该如何使用该范数实现梯度下降呢?
用backprop计算出
这就是之前我们额外增加的正则化项,既然已经增加了这个正则项,现在我们要做的就是给
我们用$ dW^{[l]}
该正则项说明,不论
我不打算这么叫它,之所以叫它“权重衰减”是因为这两项相等,权重指标乘以了一个小于 1 的系数。
Why regularization reduces overfitting?
为什么正则化有利于预防过拟合呢?为什么它可以减少方差问题?我们通过两个例子来直观体会一下。
左图是高偏差,右图是高方差,中间是Just Right,这几张图我们在前面课程中看到过。
现在我们来看下这个庞大的深度拟合神经网络。我知道这张图不够大,深度也不够,但你可以想象这是一个过拟合的神经网络。这是我们的代价函数
直观上理解就是如果正则化
但是
直观理解就是
我们再来直观感受一下,正则化为什么可以预防过拟合,假设我们用的是这样的双曲线激活函数。
用
现在你应该摒弃这个直觉,如果正则化参数 λ 很大,激活函数的参数会相对较小,因为代价函数中的参数变大了,如果
如果
特别是,如果
第一节课我们讲过,如果每层都是线性的,那么整个网络就是一个线性网络,即使是一个非常深的深层网络,因具有线性激活函数的特征,最终我们只能计算线性函数,因此,它不适用于非常复杂的决策,以及过度拟合数据集的非线性决策边界,如同我们在幻灯片中看到的过度拟合高方差的情况。
总结一下,如果正则化参数变得很大,参数
大家在编程作业里实现正则化的时候,会亲眼看到这些结果,总结正则化之前,我给大家一个执行方面的小建议,在增加正则化项时,应用之前定义的代价函数
如果你使用的是梯度下降函数,在调试梯度下降时,其中一步就是把代价函数
这就是
Dropout Regularization
除了
假设你在训练上图这样的神经网络,它存在过拟合,这就是dropout所要处理的,我们复制这个神经网络,dropout会遍历网络的每一层,并设置消除神经网络中节点的概率。假设网络中的每一层,每个节点都以抛硬币的方式设置概率,每个节点得以保留和消除的概率都是 0.5,设置完节点概率,我们会消除一些节点,然后删除掉从该节点进出的连线,最后得到一个节点更少,规模更小的网络,然后用backprop方法进行训练。
这是网络节点精简后的一个样本,对于其它样本,我们照旧以抛硬币的方式设置概率,保留一类节点集合,删除其它类型的节点集合。对于每个训练样本,我们都将采用一个精简后神经网络来训练它,这种方法似乎有点怪,单纯遍历节点,编码也是随机的,可它真的有效。不过可想而知,我们针对每个训练样本训练规模小得多的网络,最后你可能会认识到为什么要正则化网络,因为我们在训练规模小得多的网络。
如何实施dropout呢?方法有几种,接下来我要讲的是最常用的方法,即inverted 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,它的作用就是生成随机矩阵,如果对
接下来要做的就是从第三层中获取激活函数,这里我们叫它a3 =np.multiply(a3,d3)
,这里是元素相乘,也可写为
如果用python实现该算法的话,
最后,我们向外扩展
下面我解释一下为什么要这么做,为方便起见,我们假设第三隐藏层上有 50 个单元或 50 个神经元,在一维上
它的功能是,不论keep-prop的值是多少 0.8,0.9 甚至是 1,如果keep-prop设置为 1,那么就不存在dropout,因为它会保留所有节点。反向随机失活(inverted dropout)方法通过除以keep-prob,确保
事实证明,在测试阶段,当我们评估一个神经网络时,也就是用绿线框标注的反向随机失活方法,使测试阶段变得更容易,因为它的数据扩展问题变少,我们将在下节课讨论。
据我了解,目前实施dropout最常用的方法就是Inverted dropout,建议大家动手实践一下。Dropout早期的迭代版本都没有除以keep-prob,所以在测试阶段,平均值会变得越来越复杂,不过那些版本已经不再使用了。
现在你使用的是
如何在测试阶段训练算法,在测试阶段,我们已经给出了
以此类推直到最后一层,预测值为
显然在测试阶段,我们并未使用dropout,自然也就不用抛硬币来决定失活概率,以及要消除哪些隐藏单元了,因为在测试阶段进行预测时,我们不期望输出结果是随机的,如果测试阶段应用dropout函数,预测会受到干扰。理论上,你只需要多次运行预测处理过程,每一次,不同的隐藏单元会被随机归零,预测处理遍历它们,但计算效率低,得出的结果也几乎相同,与这个不同程序产生的结果极为相似。
Inverted dropout函数在除以keep-prob时可以记住上一步的操作,目的是确保即使在测试阶段不执行dropout来调整数值范围,激活函数的预期结果也不会发生变化,所以没必要在测试阶段额外添加尺度参数,这与训练阶段不同。
这就是dropout,大家可以通过本周的编程练习来执行这个函数,亲身实践一下。
为什么dropout会起作用呢?下节课我们将更加直观地了解dropout的具体功能。
Understanding Dropout
Dropout可以随机删除网络中的神经单元,他为什么可以通过正则化发挥如此大的作用呢?
直观上理解:不要依赖于任何一个特征,因为该单元的输入可能随时被清除,因此该单元通过这种方式传播下去,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和之前讲的
总结一下,dropout的功能类似于
第二个直观认识是,我们从单个神经元入手,如图,这个单元的工作就是输入并生成一些有意义的输出。通过dropout,该单元的输入几乎被消除,有时这两个单元会被删除,有时会删除其它单元,就是说,我用紫色圈起来的这个单元,它不能依靠任何特征,因为特征都有可能被随机清除,或者说该单元的输入也都可能被随机清除。我不愿意把所有赌注都放在一个节点上,不愿意给任何一个输入加上太多权重,因为它可能会被删除,因此该单元将通过这种方式积极地传播开,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和我们之前讲过的
事实证明,dropout被正式地作为一种正则化的替代形式,
总结一下,dropout的功能类似于
实施dropout的另一个细节是,这是一个拥有三个输入特征的网络,其中一个要选择的参数是keep-prob,它代表每一层上保留单元的概率。所以不同层的keep-prob也可以变化。第一层,矩阵
注意keep-prob的值是 1,意味着保留所有单元,并且不在这一层使用dropout,对于有可能出现过拟合,且含有诸多参数的层,我们可以把keep-prob设置成比较小的值,以便应用更强大的dropout,有点像在处理
总结一下,如果你担心某些层比其它层更容易发生过拟合,可以把某些层的keep-prob值设置得比其它层更低,缺点是为了使用交叉验证,你要搜索更多的超级参数,另一种方案是在一些层上应用dropout,而有些层不用dropout,应用dropout的层只含有一个超级参数,就是keep-prob。
结束前分享两个实施过程中的技巧,实施dropout,在计算机视觉领域有很多成功的第一次。计算视觉中的输入量非常大,输入太多像素,以至于没有足够的数据,所以dropout在计算机视觉中应用得比较频繁,有些计算机视觉研究人员非常喜欢用它,几乎成了默认的选择,但要牢记一点,dropout是一种正则化方法,它有助于预防过拟合,因此除非算法过拟合,不然我是不会使用dropout的,所以它在其它领域应用得比较少,主要存在于计算机视觉领域,因为我们通常没有足够的数据,所以一直存在过拟合,这就是有些计算机视觉研究人员如此钟情于dropout函数的原因。直观上我认为不能概括其它学科。
dropout一大缺点就是代价函数
Other regularization methods
除了
一.数据扩增
假设你正在拟合猫咪图片分类器,如果你想通过扩增训练数据来解决过拟合,但扩增数据代价高,而且有时候我们无法扩增数据,但我们可以通过添加这类图片来增加训练集。例如,水平翻转图片,并把它添加到训练集。所以现在训练集中有原图,还有翻转后的这张图片,所以通过水平翻转图片,训练集则可以增大一倍,因为训练集有冗余,这虽然不如我们额外收集一组新图片那么好,但这样做节省了获取更多猫咪图片的花费。
除了水平翻转图片,你也可以随意裁剪图片,这张图是把原图旋转并随意放大后裁剪的,仍能辨别出图片中的猫咪。
通过随意翻转和裁剪图片,我们可以增大数据集,额外生成假训练数据。和全新的,独立的猫咪图片数据相比,这些额外的假的数据无法包含像全新数据那么多的信息,但我们这么做基本没有花费,代价几乎为零,除了一些对抗性代价。以这种方式扩增算法数据,进而正则化数据集,减少过拟合比较廉价。
像这样人工合成数据的话,我们要通过算法验证,图片中的猫经过水平翻转之后依然是猫。大家注意,我并没有垂直翻转,因为我们不想上下颠倒图片,也可以随机选取放大后的部分图片,猫可能还在上面。
对于光学字符识别,我们还可以通过添加数字,随意旋转或扭曲数字来扩增数据,把这些数字添加到训练集,它们仍然是数字。为了方便说明,我对字符做了强变形处理,所以数字 4 看起来是波形的,其实不用对数字 4 做这么夸张的扭曲,只要轻微的变形就好,我做成这样是为了让大家看的更清楚。实际操作的时候,我们通常对字符做更轻微的变形处理。因为这几个 4 看起来有点扭曲。所以,数据扩增可作为正则化方法使用,实际功能上也与正则化相似。
二.early stopping
还有另外一种常用的方法叫作early stopping,运行梯度下降时,我们可以绘制训练误差,或只绘制代价函数
因为在训练过程中,我们希望训练误差,代价函数
当你还未在神经网络上运行太多迭代过程的时候,参数
术语early stopping代表提早停止训练神经网络,训练神经网络时,我有时会用到early stopping,但是它也有一个缺点,我们来了解一下。
我认为机器学习过程包括几个步骤,其中一步是选择一个算法来优化代价函数
在机器学习中,超级参数激增,选出可行的算法也变得越来越复杂。我发现,如果我们用一组工具优化代价函数
但对我来说early stopping的主要缺点就是你不能独立地处理这两个问题,因为提早停止梯度下降,也就是停止了优化代价函数
如果不用early stopping,另一种方法就是
Early stopping的优点是,只运行一次梯度下降,你可以找出
如果你还不能完全理解这个概念,没关系,下节课我们会详细讲解正交化,这样会更好理解。
虽然
这节课我们讲了如何使用数据扩增,以及如何使用early stopping降低神经网络中的方差或预防过拟合。
[^2]: week2 - 4.6