深度学习中的正则化(Regularization)
一、Bias(偏差) & Variance(方差)
在机器学习中,这两个名词经常让我们傻傻分不清。
我们不妨用案例来看看怎么区分。
假设我们正在做一个分类器,分别在训练集和验证集上测试,以下为四种可能的情况:
四种情况
可见①、④两种情况的训练集误差都很小,接近optimal error,这种就称为low bias。说明训练的很到位了。
相反,②、③两者的训练集误差很大,这就称为high bias。因此我们知道,bias就是衡量训练集和我们的最小误差的差距。
再来看看variance是怎么判断。①情况下,验证集相比训练集误差上升了很多,这就是high variance。而②呢,虽然它的验证集误差更大,但是相比它的训练集误差,基本没太大变化,因此它不能叫low variance。所以,说白了,variance是指你的验证集和你训练集的效果的差别,而不是某个绝对的值。
用这样一个图可以更加清晰地理解两者的意思:
bias和variance的关系
最后不妨总结一下,我直接总结在一张图里:
这么好的图,还不随手保存?
高bias往往意味着模型根本没训练到位,也就是欠拟合。而高variance往往意味着模型训练过头了,过拟合了。但注意,过拟合一般是对于训练集误差很小而验证集/测试集误差很大而言。如果两者都高的话,只能说模型太烂了,不知道怎么评价了。
二、如何解决bias和variance的问题
如果你的模型训练结果是high bias,我们一般用以下几种方法来改进:
尝试使用更复杂更大的网络结构(增加单元数、增加层数,或者更改结构)
训练更长的时间(增加迭代次)数
因为high bias意味着我们训练的还不够,连训练集的内容都无法很好的识别。所以这种情况下不用去想增加数据量,因为这个没关系,是模型太差了。
当bias问题解决好了之后,如果还有high variance问题,那我们可以这样改进:
收集更多的训练样本去训练
使用 正则化手段
为什么这个时候可以尝试收集更多的数据来解决呢?因为,high variance意味着你的训练集和验证集的效果有很大差别,很可能是因为你的训练集里面的数据并不能很好地反映验证集里面的特征,或者说验证集中有一些需要学习到的东西在你的训练集中却没有,所以模型无论如何学习你的训练集,也无法很好地预测验证集的数据,因此我们应该收集更多的数据,学习更多的特征。
如果你增加了数据量去训练之后,variance还是很大,那说明我们遇到了典型的 over fitting,我们就需要考虑用 正则化手段了。
三、正则化(Regularization)
很多人一听到“正则化”这个词,就觉得高深莫测,比如我,一直以来都觉得这个词很奇怪,然后老师们讲课也都是说“正则化,就是给损失函数加一个正则化项,相当于给它一个惩罚…”云云,更加让人觉得高神莫测。
现在终于明白了,大家可以这样理解,我现场想了 一个例子:
假设我们的模型就是一只 蚊子,我们要训练它去模拟空中的一些点的整体路径:
我们空中的点也分为训练集和测试集,蚊子去学习训练集的路径,然后闭上眼睛,按照自己学习到的那个路径去预测测试集的点是否在路径上。
蚊子飞行游戏
首先,蚊子自以为聪明灵活,自由自在地飞翔,它轻轻松松地经过了所有训练集的点:
蚊子自由自在地飞翔,经过所有训练点
很明显,训练集满分!每个点都完美经过了!
接下来给它蒙上眼睛,看看它能否经过预测集的点:
很可惜,自以为聪明的蚊子按照自己学习到的复杂的路径上上下下,却几乎一个点都没预测对。。。这就是over fitting!因为每个数据都带有随机性,你不能学的太认真,正所谓“你认真,就输了”。
但是蚊子也没办法,它也不知道怎么“不认真”,于是我们来想办法,强迫它别那么较真。
我们想了个什么办法呢?请看:
我们设计了一个 挂坠,给蚊子挂上,这样蚊子飞起来就有些费劲了,没办法自由自在上蹿下跳地飞行了,这也就是大家常常听说的“惩罚项”,因为身上有个挂坠,你蚊子上下飞就很费力,于是限制了蚊子的乱动。
给蚊子挂一个挂坠
再次起飞:
带重飞行
果真,蚊子的飞行没有那么“皮”了,它怎么省力怎么飞,每次看到新的点,它只是忘那个方向偏一点,不能偏太多,因为下一个点可能方向又变了,那得累死它,所以它在挂坠的限制下,会努力找一个中间的位置,让它不费力,又能尽可能拟合训练点。
接着,捂上眼睛进入预测区:
负重飞行就是不一样
这次的成绩就好多了。蚊子很惊喜,感叹这挂坠好神奇。
这个 挂挂坠,就是“正则化”。
当然,举例子是为了容易理解,具体的原理可能会有差别。
具体的正则化,就是在前面所说的“给损失函数加一个正则化项(挂坠)”,挂坠怎么设计,是很复杂的,不能太重也不能太轻,而且说不定还要随时变动,这里的细节就不深究了,我们直接看看常见的正则化方法:
假设我们的损失函数 J(w,b)=avg(L(y,y’))
这里由于不方便打公式,所以我用avg来表示求所有训练样本损失的平均值,
正则化项一般采用L2正则化,也就是给J加上一个 (λ/2m) * sum(w^2),也就是所有w的平方和,再乘以λ/2m,m是样本量。
综合起来就是:J(w,b)=avg(L(y,y’)) + (λ/2m) * sum(w^2)
这样一来,我们在用梯度下降的时候,求J对w的偏导,你会发现dw变大了,而我们的更新法则为w–>w-α·dw,因此最终选择的 参数w会变得更小。参数更小,对于模型来说,就意味着更加简单,于是我们的目的就达到了。
其他的正则化方法:
除了加一个惩罚项,其实正则化还有多种多样的方法,但是总体的思想史一样的,就是想办法使得我们的模型不要那么复杂。下面简单介绍两种方法:
(1)dropout 丢弃法
这个dropout是神经网络中常用的正则化方法,就是在训练过程中,随机地“丢弃”一些神经元,强行简化模型!
具体的操作方法通常是:在一层神经网络之后,随机按照一定概率“敲掉”一部分神经元,然后再将激活值传给下一层,下一层如果有必要,再敲掉一些,再传给下一层… …
dropout
为什么这种方法可以起到正则化作用呢?
我们训练模型实际上就是学习参数,参数就是每个神经元的权重。
现在 每个神经元都有可能被丢掉,因此模型训练的时候,模型不敢给任何神经元过大的参数,因此这样风险太大,万一给某个神经元的权重很大,结果下一回这个神经元就被敲掉了,那这个模型肯定会表现很差。因此,在dropout机制下,每个神经元最后的参数都会比较小。
这里注意,我们在训练的时候,采用dropout敲掉神经元,但是并不是真的把它敲没了,而是暂时“失活”,等训练完毕,在预测的时候,我们又会使用它们。dropout只是让我们在训练的时候让参数变小。
当然了,这里就有了一个 超参数(hyperparameter)需要我们去设置了,一般如果该层神经网络的神经元很多,我们可以设置drop掉0.5甚至更多比例的神经元,对于神经元不多的,一般设置为0.25左右。
(2)early-stopping
这个很简单,说白了就是不要训练那么久了,见好就收。这里就不多赘述了。
作者:Stack_empty
链接:https://www.jianshu.com/p/db86e9330fff
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。