一.过拟合欠拟合及其解决方案
在机器学习模型的训练中,我们需要区分训练误差(training error)和泛化误差(generalization error),这两种误差过大都会导致模型不佳,在训练过程中一般会有两种情况出现:
- 一类是模型无法得到较低的训练误差,我们将这一现象称作欠拟合(underfitting);
- 另一类是模型的训练误差远小于它在测试数据集上的误差,我们称该现象为过拟合(overfitting)。
其中解决过拟合有几种方式:
- 减小模型的复杂度;
- 增加数据量;
- 使用正则项L1, L2。其中L1也可以用来做特征选择,它可以使得模型参数变得更为稀疏;L2会倾向于减小模型中对结果影响较大的参数,而不是直接置为0.
- 使用Dropout。
这里强调一下Dropout的原理和实现方式:
在神经网络的隐藏层中一般会有多个神经元,如果每次训练使用全部的神经元,则很可能某个神经元对整个模型的影响较大,Dropout即为随机地丢弃某些神经元,这样可以使得模型输出值不会过度依赖某个神经元,最终起到添加正则化的效果。
具体来说,设随机变量为0和1的概率分别为和。使用丢弃法时我们计算新的隐藏单元
由于,因此
即丢弃法不改变其输入的期望值。
使用PyTorch实现Dropout:
def dropout(X, drop_prob):
X = X.float()
assert 0 <= drop_prob <= 1
keep_prob = 1 - drop_prob
# 这种情况下把全部元素都丢弃
if keep_prob == 0:
return torch.zeros_like(X)
mask = (torch.rand(X.shape) < keep_prob).float()
return mask * X / keep_prob
X = torch.arange(16).view(2, 8)
dropout(X, 0)
tensor([[ 0., 1., 2., 3., 4., 5., 6., 7.],
[ 8., 9., 10., 11., 12., 13., 14., 15.]])
如果drop掉的比例为0,此时可以看到dropout之后的输出值并没有改变。
dropout(X, 0.5)
tensor([[ 0., 2., 0., 0., 0., 0., 0., 14.],
[16., 0., 20., 0., 0., 0., 0., 30.]])
如果drop掉的比例为0.5,则有一般的神经元会被丢弃。同时剩下的神经元输出值会被拉伸1 / ( 1 - drop_prob)
,以此保证输入的期望不变。
二.模型初始化方式
在神经网络中,如果神经元权重参数都初始为0或者相同的值,则在反向传播之后每个神经元的值依旧相等,在这种情况下,无论隐藏单元有多少,隐藏层本质上只有1个隐藏单元在发挥作用。因此需要将参数随机初始化。
1.随机初始化模型参数
PyTorch的默认随机初始化
随机初始化模型参数的方法有很多。在线性回归的简洁实现中,我们使用torch.nn.init.normal_()
使模型net
的权重参数采用正态分布的随机初始化方式。不过,PyTorch中nn.Module
的模块参数都采取了较为合理的初始化策略(不同类型的layer具体采样的哪一种初始化方法的可参考源代码),因此一般不用我们考虑。
2.Xavier初始化方法:
假设某全连接层的输入个数为,输出个数为,Xavier随机初始化将使该层中权重参数的每个元素都随机采样于均匀分布
它的设计主要考虑到,模型参数初始化后,每层输出的方差不该受该层输入个数影响,且每层梯度的方差也不该受该层输出个数影响。