pytorch 按比例划分dataset_正则化


问题一:什么是偏差?什么是方差?[1]

pytorch 按比例划分dataset_pytorch设置l2正则_02


由上图可以看出:
①④两种情况的训练误差很小,接近 optimal error(最佳误差),这种情况称之为 low bias,说明训练的效果很不错了。
②③两种情况的训练误差很大,称之为high bias。
因此,可以得出: bias就是衡量训练集和我们的最小误差的差距。

①情况下,验证集相比训练集误差上升了很多,这就是high variance。
②情况下,虽然验证集误差更大,但是相比其训练集误差,基本没太大变化,因此它叫low variance。
因此,可以得出: variance是指你的验证集和你训练集的效果的差别,而不是某个绝对的值。

下图可以更形象的说明两者的意思:


pytorch 按比例划分dataset_损失函数_03


总而言之,用一张图表示,即:


pytorch 按比例划分dataset_过拟合_04


  • 高variance往往意味着模型训练过头了,即过拟合
  • 高bias意味着模型根本没有训练到位,即欠拟合
  • 过拟合一般是对于训练集误差很小而验证集/测试集误差很大而言。如果两者都高的话,只能说模型太烂了。

问题二:怎么解决高bias和高variance问题?

high bias 情况(意味着我们训练的还不够,连训练集的内容都无法很好的识别,无需增加数据量):
尝试使用更复杂更大的网络结构(增加单元数、增加层数,或者更改结构);
训练更长的时间(增加迭代次数); high variance 情况(意味着训练集和验证集的效果差别大,一种可能是因为训练集里面的数据并不能很好地反映验证集里面的特征,一种可能是验证集中有一些需要学习到的东西在你的训练集中却没有):
a) 收集更多的训练样本去训练。
b) 使用 正则化手段(增加训练集不能够解决的时候)。

问题三:怎么理解正则化(Regularization)?

很多人一听到“正则化”这个词,就觉得高深莫测,比如我,一直以来都觉得这个词很奇怪,然后老师们讲课也都是说“正则化,就是给损失函数加一个正则化项,相当于给它一个惩罚... ...”,更加让人觉得高神莫测。

一个例子
假设我们的 模型就是一只 蚊子,我们要训练它去模拟空中的一些点的整体路径:
我们空中的点也分为训练集和测试集,蚊子先去学习训练集的路径,然后闭上眼睛,按照自己学习到的那个路径去预测测试集的点是否在路径上。(如下图)


pytorch 按比例划分dataset_正则化_05


首先,蚊子自以为聪明灵活,自由自在地飞翔,它轻轻松松地经过了所有训练集的点:


pytorch 按比例划分dataset_pytorch设置l2正则_06


很明显,训练集满分!每个点都完美经过了!
接下来给它蒙上眼睛,看看它能否经过预测集的点:


pytorch 按比例划分dataset_正则不能全为某个值_07


很可惜,自以为聪明的蚊子按照自己学习到的复杂的路径上上下下,却几乎一个点都没预测对。。。这就是over fitting(过拟合)!因为每个数据都带有随机性,你不能学的太认真,正所谓“你认真,就输了”。
但是蚊子也没办法,它也不知道怎么“不认真”,于是我们来想办法,强迫它别那么较真。
我们想了个什么办法呢?如下图:


pytorch 按比例划分dataset_正则化_08


挂坠,给蚊子挂上,这样蚊子飞起来就有些费劲了,没办法自由自在上蹿下跳地飞行了,这也就是大家常常听说的“惩罚项”, 因为身上有个挂坠,你蚊子上下飞就很费力,于是限制了蚊子的乱动
再次起飞:


pytorch 按比例划分dataset_正则不能全为某个值_09


果真,蚊子的飞行没有那么“皮”了,它怎么省力怎么飞,每次看到新的点,它只是忘那个方向偏一点,不能偏太多,因为下一个点可能方向又变了,那得累死它,所以它在挂坠的限制下,会努力找一个中间的位置,让它不费力,又能尽可能拟合数据点。
接着,捂上眼睛进入预测区:


pytorch 按比例划分dataset_损失函数_10


这次的成绩就好多了。蚊子很惊喜,感叹这挂坠好神奇。

这个 挂挂坠,就是“正则化”


数学理解正则化(Regularization)

当然,举例子是为了容易理解,具体的原理可能会有差别。
具体的正则化,就是在前面所说的“给损失函数加一个正则化项(挂坠)”,挂坠怎么设计,是很复杂的,不能太重也不能太轻,而且说不定还要随时变动,这里的细节就不深究了,我们直接看看常见的正则化方法:

假设我们的损失函数为平方均值损失函数:


pytorch 按比例划分dataset_正则化_11


m表示每一条样本,J(θ)表示所有训练样本损失的平均值,
正则化项一般采用L2正则化,也就是给J(θ)加上一个


pytorch 按比例划分dataset_损失函数_12


,也就是所有w的平方和,再乘以λ/2m,m是样本量。
综合起来就是:


pytorch 按比例划分dataset_正则不能全为某个值_13


这样一来,我们在用梯度下降的时候,求J对w的偏导,你会发现dw变大了,而我们的更新法则为w-->w-α·dw,因此最终选择的 参数w会变得更小。参数更小,对于模型来说,就意味着更加简单,于是我们的目的就达到了。


其他正则化方法:

除了加一个惩罚项,其实正则化还有多种多样的方法,但是总体的思想是一样的,就是想办法使得我们的模型不要那么复杂。

(1)dropout(丢弃法)

这个dropout是神经网络中常用的正则化方法,就是在训练过程中,随机地“丢弃”一些神经元,强行简化模型!
具体的操作方法通常是:在一层神经网络之后,随机按照一定概率“敲掉”一部分神经元,然后再将激活值传给下一层,下一层如果有必要,再敲掉一些,再传给下一层... ...


pytorch 按比例划分dataset_正则化_14


为什么这种方法可以起到正则化作用呢?
我们训练模型实际上就是学习参数,参数就是每个神经元的权重。
现在 每个神经元都有可能被丢掉,因此模型训练的时候,模型不敢给任何神经元过大的参数,因此这样风险太大,万一给某个神经元的权重很大,结果下一回这个神经元就被敲掉了,那这个模型肯定会表现很差。因此, 在dropout机制下,每个神经元最后的参数都会比较小
这里注意,我们 在训练的时候,采用dropout敲掉神经元,但是并不是真的把它敲没了,而是暂时“失活”,等训练完毕, 在预测的时候,我们又会使用它们。dropout只是让我们在训练的时候让参数变小。
当然了,这里就有了一个 超参数(hyperparameter)需要我们去设置了,一般如果该层神经网络的神经元很多,我们可以设置drop掉0.5甚至更多比例的神经元,对于神经元不多的,一般设置为0.25左右。

(2)early-stopping(提前停止)

提前停止训练,见好就收。

参考

  1. ^参考文章 https://www.jianshu.com/p/db86e9330fff