过拟合和欠拟合
- 过拟合(overfitting)
-
模型的训练误差远小于它在测试数据集上的误差。
- 欠拟合(underfitting)
-
模型无法得到较低的训练误差。
造成上述问题的原因主要取决于模型的复杂度和训练集数据集大小1。
权重衰减
在使用SGD
优化算法时,权重衰减(weight decay)等价于L2范数正则化(L2 norm regularization)23。
L2正则化
: 通过在模型损失函数后添加惩罚项对模型的权重参数惊醒调整,使学习到的模型参数减小。通常是应对过拟合的常用手段。
L2范数惩罚项指的是模型权重参数每个元素的平方和与正常数的乘积。即 $$ l = l_0 + \frac{\lambda}{2n}\sum_{\omega}\omega^2 $$ 其中第一项$l_0$表示原来的**损失函数**,第二项表示**L2正则化项**,系数$\frac{1}{2}$是为了求导时方便。
对式(1)进行求导可得
关于$\omega$的求导 $$ \frac{\partial{l}}{\partial{\omega}} = \frac{\partial{l_0}}{\partial{\omega}} + \frac{\lambda}{n}\omega $$ 关于$b$的求导 $$ \frac{\partial{l}}{\partial{b}} = \frac{\partial{l_0}}{\partial{b}} $$ 由上述推导结果可以看出,权重衰减仅对$\omega$的更新有影响,对$b$没有影响。
$\omega$的更新方式为:
$$ \omega := \omega - \eta\frac{\partial{l_0}}{\partial{\omega}} - \frac{\eta\lambda}{n}\omega \ := (1-\frac{\eta\lambda}{n})\omega - \eta\frac{\partial{l_0}}{\partial{\omega}} $$ 其中$\eta$表示学习率,$n$表示样本数。
对于小批量随机梯度下降而言,$\omega$和$b$的更新方式如下:
$$ \omega := (1-\frac{\eta{\lambda}}{m})\omega - \frac{\eta}{m}\sum_x\frac{\partial{l_x}}{\partial\omega} $$
$$ b := b - \frac{\eta}{m}\sum_x\frac{\partial{l_x}}{\partial{b}} $$
其中,$\eta$表示学习率,$\lambda$表示衰减系数,$m$表示批量大小(mini-hatch)。上述参数更新的后一项均变为:所有样本的导数和乘$\eta$除$m$。
关于L2正则化能够减小$\omega$,而$\omega$的减小能够防止过拟合的解释4:
**奥卡姆剃刀原理解释:**更小的权重$\omega$,从某种意义上来说,意味着网络复杂度更低,对数据的拟合刚好。
过拟合情况下,模型的权重系数要尽量在每一个点都具有最小误差,那么梯度的变化就必然出现波动,梯度波动会导致梯度大小差异更大,而L2正则化的权重衰减,降低了梯度差异,从而降低了过拟合问题。
L1正则化
: L1正则化是在原始损失函数的基础上,添加所有权重$\omega$的绝对值之和与$\frac{\lambda}{n}$的乘积5。即 $$ l = l_0 + \frac{\lambda}{n}\sum_{\omega}\omega $$ 求导可得: $$ \frac{\partial{l}}{\partial{\omega}} = \frac{\partial{l_0}}{\partial{\omega}} + \frac{\lambda}{n}sgn(\omega) $$ 其中$sgn$表示 $\omega$ 的符号。权重$\omega$ 的更新规则变为: $$ \omega := \omega - \frac{\eta\lambda}{n}sgn(\omega) - \eta\frac{\partial{l_0}}{\partial\omega} $$ 当$\omega$ 为正时,$sgn(\omega) = 1$,权重$\omega$减小;当$\omega$ 为负时,$sgn(\omega) = -1$,权重增大;当$\omega = 0$时,规定$sgn(\omega) = 0$。
Dropout
L1正则化和L2正则化是通过修改模型的代价函数改善模型过拟合问题。dropout
通过修改模型的网络结构改善模型过拟合问题。即在每一次迭代过程中,随机从每一个隐藏层中临时删除一半的神经元6。
丢弃法不会改变输入的期望值7。
图像增强
torchvision.transforms
模块自带的图像增强方法所要求的输入是PIL
图像。transforms.ToTensor()
会将输入的尺寸为(HxWxC)
且数据范围在[0, 255]
间的PIL图片或数据类型为np.uint8
的Numpy
数组转换为尺寸为(CxHxW)
且数据类型为torch.float32
且位于[0, 1.0]
的Tensor
。
注意: 由于像素值为0到255的整数,所以刚好是uint8所能表示的范围,包括transforms.ToTensor()
在内的一些关于图片的函数就默认输入的是uint8型,若不是,可能不会报错但可能得不到想要的结果。所以,如果用像素值(0-255整数)表示图片数据,那么一律将其类型设置成uint8,避免不必要的bug。
更新记录
2020.02.21 初次更新