本篇文章讲解如何缓解over-fitting。首先看下面三张图,under-fitted表明预测的函数模型所包含的参数量、复杂度低于实际模型,但这种情况已经越来越少见了,因为现在的网络都足够深
而over-fitted表明预测的函数模型的参数量、复杂度远高于实际模型
在此背景下,有人提出了“Occam’s Razor”,即more things should not be used than are necessary,不是必要的东西不要使用,在神经网络中,不是必要的网络参数,要尽量选择最小的、最有可能的参数量
目前对于防止over-fitting,有以下几种主流的做法
这里我们利用的是Regularization,对于一个二分类问题,它的Cross Entropy公式为
$$ J_1(\theta)=-\frac{1}{m}\sum_{i=1}^m[y_iln\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()