一.引言
Dropout 层用于解决过拟合的问题,当原始样本偏少而深度模型参数偏多时,模型偏向于学习一些极端的特征从而导致过拟合,在训练样本上达到很高的精度但在测试集的表现却很糟糕,这时候可以引入 Dropout 按适当的比例舍弃掉一些神经元的激活,从而减少模型的过拟合情况,增加模型泛化能力。
二.Dropout 理论
1. Dropout 层基本参数
(1) rate : 在0和1之间的浮点数。输入将按照 rate 的比例舍弃掉,注意是舍弃,有些同学将rate理解为保留的比例,需要区分。
(2) noise_shape : 这个直接看函数的解释吧
1维的张量类型,其目的是控制输入的某一个维度按相同的丢弃掩码,例如最经典的时序特征,其三维向量为 (batch_size, timesteps, features),如果想要 timesteps 的drop掩码相同,就将 noise_shape 设置为 (batch_size, 1, features),即对应位置设为1其他不动。我的理解是 noise 可以理解为噪声,丢弃操作相当于在某一维度引入了随机扰动,而 shape 就是控制你的 noise 即你的随机扰动想添加到哪个维度,添加哪个维度就将哪个维度置为1。
noise_shape: 1D integer tensor representing the shape of the
binary dropout mask that will be multiplied with the input.
For instance, if your inputs have shape
`(batch_size, timesteps, features)` and
you want the dropout mask to be the same for all timesteps,
you can use `noise_shape=(batch_size, 1, features)`.
(3) seed : python random 的随机seed。
2. Dropout 训练
(1) Dropout 只在训练时生效
Dropout 和 BN 层在训练和预测时都是不同的逻辑。训练时 Dropout 随机丢弃一些神经元,但是预测时不可以随机丢弃,预测时随机丢弃将导致同一样本多次预测预估 CTR 不一致,这在应用场景是不允许的,所以 Dropout 操作只在训练时生效。
(2) 训练时数据的缩放
Inputs not set to 0 are scaled up by 1/(1 - rate) such that the sum over
all inputs is unchanged.
源码中提到 Dropout 时未设置为0的神经元的输入将通过 1/ (1 - rate) 缩放,这样保持了训练和测试时的输入总和相同。假设输入 inputs 总和为 1000,Dropout 比例为 0.3,参数默认均为1的情况下,当前层的输入总和为 700,但是预测时由于没有 Dropout,所以预测时输入总和为 1000,这就导致了训练和测试的不一致。现在 scale = 1/ (1 -rate) ,原始数据 dropout 掉数据后还剩 (1-rate) * 1000,则缩放后的总和 (1-rate) * 1000 * scale = 1000,这就保证了输出总和的一致。
3. Dropout 预测
(This is in contrast to setting `trainable=False` for a Dropout layer.
`trainable` does not affect the layer's behavior, as Dropout does
not have any variables/weights that can be frozen during training.)
预测时 trainable=False,Dropout 层不会生效,其层内也没有在训练时可以冻结的参数与权重。按正常预测计算逻辑调用模型即可。
三.Dropout 实践
1.试验设置
实验数据采用 mnist 手写识别数据,这里 Baseline 模型与 BN 实验时采用相同的结构设计。
Dropout 超参主要是 rate,所以这里只调整了 rate 一个超参,其次其放置位置的不同代表了对原始信息还是抽象信息的舍弃,也可以作为一个实验点,所以还调整了添加的位置。由于 Dropout 多用于小数据量训练下的过拟合,所以只对 mnist 数据取了 1000 份和 200 份样本训练,模拟小样本的情况。
A | Baseline | 数据 (N=1000) |
B | Dropout 添加至 dense 后 , rate=0.5 | 数据 (N=1000) |
C | Dropout 添加至 dense 后 , rate=0.3 | 数据 (N=1000) |
D | Dropout 添加至 dense1 后 , rate=0.3 | 数据 (N=1000) |
E | Dropout 添加至 dense2 后, rate=0.3 | 数据 (N=1000) |
F | Baseline | 数据 (N=200) |
G | Dropout 添加至 dense1 后 , rate=0.3 | 数据 (N=200) |
2.数据获取
get_train_test_data 分别获取归一化和未归一化的训练测试数据以及对应 label,limit 控制获取样本的数量,也可以自己调大limit尝试大样本下的 Dropout 实验。
def get_train_test_data(limit=10000):
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28 * 28))[0: limit]
ori_train_images = train_images
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))[0: limit]
ori_test_images = test_images
test_images = test_images.astype('float32') / 255
train_labels = to_categorical(train_labels[0: limit])
test_labels = to_categorical(test_labels[0: limit])
print("原始训练集维度: ", ori_train_images.shape, " 训练集维度: ", train_images.shape, " 训练标签维度: ", train_labels.shape)
print("原始测试集维度: ", ori_test_images.shape, " 测试集维度: ", test_images.shape, " 测试标签维度: ", test_labels.shape)
return ori_train_images, train_images, train_labels, ori_test_images, test_images, test_labels
3.实验数据
下述实验数据是少量实验得到的结果,需要更高的置信度可以多做实验求平均指标。
实验组 | 实验设置 | 数据量 | Test Acc | Test Loss |
A | Baseline | 数据 (N=1000) | 0.8840 | 73.9328 |
B | Dropout 添加至 dense 后 , rate=0.5 | 数据 (N=1000) | 0.8169 | 145.9166 |
C | Dropout 添加至 dense 后 , rate=0.3 | 数据 (N=1000) | 0.8830 | 81.8222 |
D | Dropout 添加至 dense1 后 , rate=0.3 | 数据 (N=1000) | 0.8339 | 147.9275 |
E | Dropout 添加至 dense2 后, rate=0.3 | 数据 (N=1000) | 0.8759 | 84.5205 |
F | Baseline | 数据 (N=200) | 0.7099 | 146.3481 |
G | Dropout 添加至 dense1 后 , rate=0.3 | 数据 (N=200) | 0.7400 | 105.0997 |
4.实验分析
B-C : 将 Dropout 添加在靠前的层且设置较大的 drop rate 容易丢失原始信息,对模型训练不够友好 0.88 -> 0.81
C-D-E : 单 Dense 层下,位置的不同对模型的影响较大,浮动区间在 [83-88]
AC-FG : 数据量很小时,Dropout 解决过拟合的效果优于大数据量,N=1000 时,Acc 浮动不大, N=200 时,添加 Dropout 的层在 Acc 和 Loss 上都优于无 Dropout。
5.效果可视化
由于 Dense 层下的 weights 特别多,所以这里采用 Bias 简单看一下 Dropout 添加有否的区别。
以实验 F,G 为例 :
未添加 Dropout 的实验 F 截距项的区间较大 [-0.005, 0.015],过拟合的原因是个别特征过大或过小从而主导模型;而 G 实验添加了 Dropout,截距项的区间则相对紧凑 [-0.0075, 0.0100] ,可以观察二者在0区间附近的分布,G 实验相对平均分散而 F实验则趋于两极分化。weights 的体现需要 3Dplot ,有兴趣的同学可以尝试。


四.总结
Dropout 在小数据量试验下可以缓解模型过拟合的情况发生,其对后续层的参数起到了一定的约束作用,类似正则化参数,其次 rate 的选择和 Dropout 层的摆放位置也对实验效果有较大影响。
更多推荐算法相关深度学习:深度学习导读专栏