本篇文章讲解如何缓解 over-fitting。首先看下面三张图,under-fitted 表明预测的函数模型所包含的参数量、复杂度低于实际模型,但这种情况已经越来越少见了,因为现在的网络都足够深
而 over-fitted 表明预测的函数模型的参数量、复杂度远高于实际模型
在此背景下,有人提出了 “Occam’s Razor”,即 more things should not be used than are necessary,不是必要的东西不要使用,在神经网络中,不是必要的网络参数,要尽量选择最小的、最有可能的参数量
目前对于防止 over-fitting,有以下几种主流的做法
- More data
Constraint model complexity
- shallow
- regularization
- Dropout
- Data argumentation
- Early Stopping
这里我们利用的是 Regularization,对于一个二分类问题,它的 Cross Entropy 公式为
$$ J_1(\theta)=-\frac{1}{m}\sum_{i=1}^m[y_i\ln\hat y_i+(1-y_i)\ln(1-\hat y_i)] $$
此时若增加一个参数 $\theta$,$\theta$ 代表网络参数 $(w1,b1,w2)$ 等,再将 $\theta$ 的某一范数(下面公式用的是 L1-norm)乘以一个因子 $\lambda>0$,则公式变为
$$ J_2(\theta)=J_1(\theta)+\lambda\sum_{i=1}^n|\theta_i| $$
思考一下,我们本来是要优化 Loss,也就是 $J_1 (\theta)$ 的值,使其接近于 0,现在我们优化的是 $J_2 (\theta)$,其实就是在迫使 Loss 接近于 0 的过程中,使得参数的 L1-norm$\sum_i|\theta_i|$ 也接近于 0
那为什么参数的范数值接近于 0,模型的复杂度就会减小呢?我们设想现在有一个模型 $y=\beta_0+\beta_1x+...+\beta_7x^7$,通过正则化以后,参数的范数值优化为很接近于 0 的值,此时可能 $\beta_3,...,\beta_7$ 的值都变得很小,假设都是 $0.01$,那模型近似变为一个二次方程,就不是原来七次那么复杂了
这种方法又称 Weight Decay
注意到上图左侧图的分割面较复杂,不是光滑的曲线,表明函数模型的分割性较好、表达能力强,但有学到了一些噪声样本。右侧图是添加了 regularization 后的图,函数模型没有学习到一些噪声样本,表达能力没有那么强,能进行更好的划分,而这就是我们想要的
Regularization 有两种比较常见的方式,一种是加 L1-norm,另一种是加 L2-norm,最常用的是 L2-regularization,代码如下
- net = MLP()
- optimizer = optim.SGD(net.parameters(), lr=learning_rater, weight_decay=0.01)
- # SGD会得到所有的网络参数,设置weight_decay=0.01以迫使二范数逐渐趋近于0
- # 但要注意的是,若没有overfitting现象仍设置weight_decay参数,会使性能急剧下降
- criteon = nn.CrossEntropyLoss()
pytorch 对 L1-regularization 暂时并没有很好的支持,因此需要人为设定代码
- regularization_loss = 0
- for param in model.parameters():
- regularization_loss += torch.sum(torch.abs(param))
-
- classify_loss = criteon(logits, target)
- loss = classify_loss + 0.01 * regularization_loss
-
- optimizer.zero_grad()
- loss.backward()
- optimizer.step()