过拟合
过拟合问题在机器学习中是一个经常遇到的问题,所谓过拟合,即模型过度地拟合了训练数据,从而导致模型在训练数据上表现极佳,但在未知数据上表现却较差。举一个极端的例子,如果一个模型中的参数比训练数据的总数还多,那么只要训练数据不冲突,这个模型完全可以记住所有的训练数据结果从而使损失函数为0。
下图展示了过于简单的模型、合理的模型与过拟合的模型在训练时的不同情况。
正则化
为了避免过拟合问题,一个常用的方法就是正则化(regularization),正则化的思想就是在损失函数中加入刻画模型复杂度的指标,即对模型的复杂度进行惩罚,从而避免模型过于复杂。假设模型在训练数据上表现的损失函数为J(θ),则在优化时不是直接优化J(θ),而是优化J(θ)+λR(w),其中R(w)刻画的是模型的复杂程度,而λ表示模型复杂损失在总损失中的比例。
常用的复杂度函数R(w)有两种,一种是L1正则化和L2正则化。
-
L1正则化
计算公式为:
即模型参数的绝对值之和 -
L2正则化
计算公式为:
即模型参数的平方和
还有一种正则化叫L0正则化,相比L1、L2正则化较少使用:
-
L0正则化
计算公式为:
即模型参数中非0参数的个数
无论哪种正则化方式,基本思想都是希望通过限制权重的大小,从而使得模型不能任意拟合训练数据中的随即噪音。
各正则化方式的区别
首先讨论两个问题:
1)实现参数的稀疏有什么好处吗?
所谓参数变稀疏是指由更多的参数变为0。一个好处是可以简化模型,避免过拟合。因为一个模型中真正重要的参数可能并不多,如果考虑所有的参数起作用,那么可以对训练数据可以预测的很好,但是对测试数据就只能呵呵了。另一个好处是参数变少可以使整个模型获得更好的可解释性。
2)参数值越小代表模型越简单吗?
是的。为什么参数越小,说明模型越简单呢,这是因为越复杂的模型,越是会尝试对所有的样本进行拟合,甚至包括一些异常样本点,这就容易造成在较小的区间里预测值产生较大的波动,这种较大的波动也反映了在这个区间里的导数很大,而只有较大的参数值才能产生较大的导数。因此复杂的模型,其参数值会比较大。
L0正则化
根据上面的讨论,稀疏的参数可以防止过拟合,因此用L0范数(非零参数的个数)来做正则化项是可以防止过拟合的。
从直观上看,利用非零参数的个数,可以很好的来选择特征,实现特征稀疏的效果,具体操作时选择参数非零的特征即可。但因为L0正则化很难求解,是个NP难问题,因此一般采用L1正则化。L1正则化是L0正则化的最优凸近似,比L0容易求解,并且也可以实现稀疏的效果。
L1正则化
L1正则化在实际中往往替代L0正则化,来防止过拟合。在江湖中也人称Lasso。
L1正则化之所以可以防止过拟合,是因为L1范数就是各个参数的绝对值相加得到的,我们前面讨论了,参数值大小和模型复杂度是成正比的。因此复杂的模型,其L1范数就大,最终导致损失函数就大,说明这个模型就不够好。
L2正则化
L2正则化可以防止过拟合的原因和L1正则化一样,只是形式不太一样。
L2范数是各参数的平方和再求平方根,我们让L2范数的正则项最小,可以使W的每个元素都很小,都接近于0。但与L1范数不一样的是,它不会是每个元素为0,而只是接近于0。越小的参数说明模型越简单,越简单的模型越不容易产生过拟合现象。
L2正则化江湖人称Ridge,也称“岭回归”。
L1正则化与L2正则化的对比
-
L1正则化会让参数更稀疏,而L2不会
L1正则化和L2正则化可以表示为:
我们考虑两维的情况,在(w1, w2)平面上可以画出目标函数的等高线,而约束条件则成为平面上半径为C的一个 norm ball 。等高线与 norm ball 首次相交的地方就是最优解:
可以看到,L1-ball 与L2-ball 的不同就在于L1在和每个坐标轴相交的地方都有“角”出现,有很大的几率等高线会和L1-ball在四个角,也就是坐标轴上相遇,坐标轴上就可以产生稀疏,因为某一维可以表示为0。而等高线与L2-ball在坐标轴上相遇的概率就比较小了。
因此,L1正则化可以达到类似特征选择的功能。
L1正则化计算公式不可导,而L2正则化公式可导
所以含有L2正则化损失函数的优化要更加简洁。在实践中,也可以将L1正则化和L2正则化同时使用:
tensorflow中的带正则化损失函数的定义
import tensorflow as tf
w= tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))
y = tf.matmul(x,w)
loss = tf.reduce_mean(tf.square(y_-y))+tf.contrib.layers.l2_regularizer(lambda)(w)