过拟合、正则化(Regularization)

1.过拟合问题

过拟合问题描述

常用的机器学习优化算法,包括线性回归和逻辑回归,它们能够有效地解决许多问题,但是当将它们应用到某些特定的机器学习应用时,会遇到过拟合(over-fitting)的问题,可能会导致它们效果很差。使用正则化技术可以减少过拟合问题。
如果我们有非常多的特征,我们通过学习得到的假设可能能够非常好地适应训练集(代价函数可能几乎为0),但是可能会不能推广到新的数据。
下图是一个回归问题的例子:

1541172957837

第一个模型是一个线性模型,欠拟合,不能很好地适应我们的训练集;第三个模型是一个四次方的模型,过于强调拟合原始数据,而丢失了算法的本质:预测新数据。我们可以看出,若给出一个新的值使之预测,它将表现的很差,是过拟合,虽然能非常好地适应我们的训练集但在新输入变量进行预测时可能会效果不好;而中间的模型似乎最合适。
分类问题中也存在这样的问题:

1541173045662

就以多项式理解, 的次数越高,拟合的越好,但相应的预测的能力就可能变差。

如果我们发现了过拟合问题,应该如何处理?

  1. 丢弃一些不能帮助我们正确预测的特征。可以是手工选择保留哪些特征,或者使用一些模型选择的算法来帮忙(例如PCA)
  2. 正则化。 保留所有的特征,但是减少参数的大小(magnitude)。

2.代价函数

上面的回归问题中如果我们的模型是:$h_θ(x) = θ_0 + θ_1x_1 + θ_2x_2^2 + θ_3x_3^3 + θ_4x_4^4$ 我们可以从之前的事例中看出,正是那些高次项导致了过拟合的产生,所以如果我们能让这些高次项的系数接近于0的话,我们就能很好的拟合了。 所以我们要做的就是在一定程度上减小这些参数 θ 的值,这就是正则化的基本方法。

我们决定要减少θ3和 θ4的大小,我们要做的便是修改代价函数,在其中 θ3和 θ4 设置一点惩罚。这样做的话,我们在尝试最小化代价时也需要将这个惩罚纳入考虑中,并最终导致选择较小一些的 θ3和θ4。 修改后的代价函数如下:

$min_θ {1\over 2m}[h_θ(x^{(i)} - y^{(i)})^2 + 1000θ_3^2 + 10000θ_4^2]$

通过这样的代价函数选择出的 θ3和 θ4 对预测结果的影响就比之前要小许多, 因为为了θ3和θ4的系数很大,为了优化代价函数, 其值一定会特别的小。

假如我们有非常多的特征,我们并不知道其中哪些特征我们要惩罚,我们将对所有的特征进行惩罚,并且让代价函数最优化的软件来选择这些惩罚的程度。这样的结果是得到了一个较为简单的能防止过拟合问题的假设:

$J_θ = {1\over 2m}[\sum_{i=1}^m(h_θ(x^{(i)}) - y^{(i)}) + λ\sum_{j=1}^nθ_j^2]$
其中又称为正则化参数(Regularization Parameter)。 注:根据惯例,我们不对 θ0 进行惩罚。

经过正则化处理的模型与原模型的可能对比如下图所示:

1541174343216

如果选择的正则化参数λ过大,则会把所有的参数都最小化了,导致模型变成 $h_θ(x) = θ_0$,也就是上图中红色直线所示的情况,造成欠拟合。

那为什么增加的一项 $λ\sum_{j=1}^nθ_j^2$ 可以使的值减小呢?

因为如果我们令 λ的值很大的话,为了使Cost Function 尽可能的小,所有的 θ 的值(不包括θ0) 都会在一定程度上减小。 但若λ的值太大了,那么不包括θ0)都会趋近于0,这样我们所得到的只能是一条平行于轴的直线。 所以对于正则化,我们要取一个合理的 λ 的值,这样才能更好的应用正则化。 回顾一下代价函数,为了使用正则化,让我们把这些概念应用到到线性回归和逻辑回归中去,那么我们就可以让他们避免过度拟合了。

3.正则化线性回归

对于线性回归的求解,我们之前推导了两种学习算法:一种基于梯度下降,一种基于正规方程。
正则化线性回归的代价函数为:

$J_{(θ)} = {1\over 2m} \sum_{i=1}^m[(h_θ(x^{(i)})-y^{(i)})^2 + λ\sum_{j=1}^nθ_j^2]$

如果我们要使用梯度下降法令这个代价函数最小化,因为我们未对θ进行正则化,所以梯度下降算法将分两种情形:

1541174923066

4.正规方程逻辑回归

针对逻辑回归问题,我们在之前的课程已经学习过两种优化算法:我们首先学习了使用梯度下降法来优化代价函数J(θ),接下来学习了更高级的优化算法,这些高级优化算法需要你自己设计代价函数J(θ)。

1541175045035

用Python实现

1
2
3
4
5
6
7
8
9
import numpy as np
def costReg(theta, X, y, learningRate):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(‐y, np.log(sigmoid(X*theta.T)))
second = np.multiply((1 ‐ y), np.log(1 ‐ sigmoid(X*theta.T)))
reg = (learningRate / (2 * len(X))* np.sum(np.power(theta[:,1:theta.shape[1]],2))
return np.sum(first ‐ second) / (len(X)) + reg

要最小化该代价函数,通过求导,得出梯度下降算法为:

1541175163753

注:看上去同线性回归一样,但是知道 $h_θ(x) = g(θ^TX)$ ,所以与线性回归不同。 Octave 中,我们依旧可以用fminuc 函数来求解代价函数最小化的参数,值得注意的是θ0参数的更新规则与其他情况不同。

注意:

  1. 虽然正则化的逻辑回归中的梯度下降和正则化的线性回归中的表达式看起来一样,但由于两者hθ(x)的不同所以还是有很大差别。
  2. θ不参与其中的任何一个正则化。

5.其他防止过拟合的方法

Dropout

Dropout是在深度学习中降低过拟合风险的常见方法,它是由大牛Hinton老爷子提出的。老爷子认为在神经网络产生过拟合主要是因为神经元之间的协同作用产生的。因此老爷子在神经网络进行训练的时候,让部分神经元失活,这样就阻断了部分神经元之间的协同作用,从而强制要求一个神经元和随机挑选出的神经元共同进行工作,减轻了部分神经元之间的联合适应性。
Dropout的具体流程如下:

1.对 l 层第 j 个神经元产生一个随机数 $r^{(l)}_j∼Bernouli(p)$

2.将 l 层第 j 个神经元的输入乘上产生的随机数作为这个神经元新的输入:$x^{(l)∗}_j=x^{(l)}_j∗r^{(l)}_j$

3.此时第 l 层第 j 个神经元的输出为:
$y{(l+1)}j=f(∑^k{j=1}(w^{(l+1)}_j ∗ x^{(l)∗}_j + b^{(l+1)}))$
其中,k为第l层神经元的个数,f为该神经元的激活函数,b为偏置,w为权重向量。
注意:当我们采用了Dropout之后再训练结束之后,应当将网络的权重乘上概率p得到测试网络的权重,或者可以在训练时,将样本乘上 1/P。

提前终止

在对模型进行训练时,我们可以将我们的数据集分为三个部分,训练集、验证集、测试集。我们在训练的过程中,可以每隔一定量的step,使用验证集对训练的模型进行预测,一般来说,模型在训练集和验证集的损失变化如下图所示:

1541249965141

可以看出,模型在验证集上的误差在一开始是随着训练集的误差的下降而下降的。当超过一定训练步数后,模型在训练集上的误差虽然还在下降,但是在验证集上的误差却不在下降了。此时我们的模型就过拟合了。因此我们可以观察我们训练模型在验证集上的误差,一旦当验证集的误差不再下降时,我们就可以提前终止我们训练的模型。

增加样本量

在实际的项目中,你会发现,上面讲述的那些技巧虽然都可以减轻过拟合的风险,但是却都比不上增加样本量来的更实在。

为什么增加样本可以减轻过拟合的风险呢?这个要从过拟合是啥来说。过拟合可以理解为我们的模型对样本量学习的太好了,把一些样本的特殊的特征当做是所有样本都具有的特征。举个简单的例子,当我们模型去训练如何判断一个东西是不是叶子时,我们样本中叶子如果都是锯齿状的话,如果模型产生过拟合了,会认为叶子都是锯齿状的,而不是锯齿状的就不是叶子了。如果此时我们把不是锯齿状的叶子数据增加进来,此时我们的模型就不会再过拟合了。因此其实上述的那些技巧虽然有用,但是在实际项目中,你会发现,其实大多数情况都比不上增加样本数据来的实在。

刘小恺(Kyle) wechat
如有疑问可联系博主