上一章:深度篇——神经网络(三) 网络拓扑与训练神经网络
下一章:深度篇——神经网络(五) 细说 优化器
本小节,细说 调优神经网络,下一小节细说 优化器
前面,我讲解了神经网络 ANN 和 DNN 的网络拓扑结构,和训练方法,是已经可以开始训练神经网络了,但是,要想得到较好的模型,还需要学会对神经网络进行调优。这是接下来的重点。
5. 调优神经网络
(1). 对神经网络的理解
神经网络有着灵活性,同时这也是算法的主要缺点:有许多超参数需要去调节
①. 如神经元的层数,每层神经元的个数,在每层使用的激活函数、对权重初始化的逻辑。
②. 由于 DNN 神经网络都是全连接的,学习能力非常强,很容易过拟合。可以使用 early-stopping、、 正则化技术和 Dropout、数据增强等手段来防止过拟合。
③. 对样本进行归一化处理,使用优化器,有利于提高样本训练速度,即提高收敛速度。而且,对样本进行归一化处理,在一定程度上可以提高准确率。
④. 梯度消失的问题,对神经网络层数的控制,层数过深容易梯度消失。在每层神经网络之前先做 BN (Batch Normalization) 处理,可以在一定程度上缓解梯度消失的问题,防止过拟合,提高准确率,提高学习速度。
⑤. 使用 Grid search (网格搜索) 或 Cross Validation (交叉验证) 等方法来验证模型的好坏,并选出最适合的模型。
(2). early stopping (早停法)
①. 使用 early-stopping 的原因
a. 为了获得性能良好的神经网络,网络定型过程需要进行许多关于所用设置(超参数)的决策。超参数之一是定型周期(epoch) 的数量:亦即应当完成遍历数据集多少次。如果 epoch 数量太少,网络有可能发生欠拟合;如果 epoch 数量太多,则有可能发生过拟合。
b. 早停法旨在解决 epoch 数量需要手动设置的问题。它也可以被视为一种能够避免网络发生过拟合的正则化方法(与 、 权重衰减和丢弃法类似)
c. 根本原因就是因为继续训练会导致测试集上的准确率下降。继续训练导致测试集准确率下降的原因猜测可能有:
(a). 过拟合
(b). 学习率过大导致不收敛。
②. 原理
a. 将数据集分为训练集和验证集
b. 每个 epoch 结束后(或每 N 个 epoch 后):
在验证集上获取测试结果,随着 epoch 增加,如果在验证集上发现测试集误差上升,则停止训练。
c. 将停止之后的权重作为网络的最终参数
这种做法很符合直观感受,因为精度都不再提高了,再继续训练也是无益的,只会提高训练的时间。这就要确认什么时候验证精确度不再提高了,因为可能经过这个 epoch 后,精度降低了,但随后的 epoch 让精度又上去了,所以不能根据一两次的连续降低就判断不再提高。一般的做法是,在训练的过程中,记录到目前为止最好的验证集精度,当连续 10 次 epoch (或更多次) 没达到最佳精度时,则可以人为精度不再提高。
③. 停止的标准
a. 第一类停止标准
定义一个新变量叫泛化损失(Generalization Loss, GL),它描述的是在当前迭代周期 中,泛化误差相比较目前的最低误差的一个增长率:
:为在迭代次数 时取得最好的验证集误差。
:为在迭代次数 时取得的验证集误差。
较高的泛化损失显然是停止训练的一个候选标准,因为它直接表明了过拟合。即当泛化损失超过一定阈值的时候,停止训练。用 GL 来定义,即当 大于一定值 的时候,停止训练。
b. 第二类停止标准
当训练的速度很快的时候,可能希望模型继续训练。因为如果训练错误依然下降很快,那么泛化损失有很大概率被修复。通常会假设过拟合只会在训练错误降低很慢的时候出现。在这里 ,定义一个 周期,以及基于周期的一个新变量度量进展(Measure Progress):
:为在迭代次数 时刻训练集上的误差。
它表达的含义是,当前的指定迭代周期内的平均训练误差比该期间最小的训练误差大的多。
注意,当训练过程不稳定的时候,这个 measure progress 结果可能很大,其中训练误差会变大,而不是变小。实际中,很多算法都由于选择了不适当的较大的步长而导致这样的抖动。除非全局都不稳定,否则在较长的训练之后, measure progress 结果趋向于 0 (其实这个就是度量训练集误差在某段时间内的平均下降情况)。由此,即泛化损失和进展的商 大于指定值的时候停止,即
c. 第三类停止标准
第三类停止标准完全依赖于泛化错误的变化,即当泛化误差在连续 8 个周期内增长的时候停止(UP)。
当验证集误差在连续 8 个周期内出现增长的时候,假设这样的现象表明了过拟合,它与误差增长了多大独立。这个停止标准可以度量全局的变化,因此可以用在剪枝算法中,即在训练阶段,允许误差可以比前面最小值高很多的时候保留。
④. 停止标准选择规则
一般情况下,“较慢” 的标准会相对而言在平均水平上表现略好,可以提高泛化能力。然而,这些标准需要较长的训练时间。其实,总体而言,这些标准在系统性的区别很小。主要选择规则如下:
a. 除非较小的提升也有很大价值,否则选择较快的停止标准
b. 为了最大可能找到一个好的方案,使用 GL 标准
c. 为了最大化平均解决方案的质量,如果网络只是过拟合了一点点,可以使用 PQ 标准,否则使用 UP 标准。
⑤. 优缺点:
a. 优点:
只运用梯度下降,就可以找出 的较小值,中间值和较大值。而无需尝试 正则化的超级参数的许多值。
b. 缺点:
没有采用不同的方式来解决优化损失函数和降低方差这两个问题,而是用一种方法同时解决两个问题,结果就是要考虑的东西变得更加复杂。之所以不能独立地处理,是因为如果停止了优化代价函数,可能会出现代价函数的值不够小,而同时却又不希望过拟合。
(3). Dropout
①. 在训练深度神经网络的时候,经常会遇上容易过拟合、费时这两大问题。而 Dropout 的出现,可以比较有效地缓解过拟合的发生,在一定程度上达到正则化的效果,并且提高了训练的速度。
②. Dropout 是一种在深度学习环境中应用了正规化手段。它的运作如下:
在一次循环中,先随机选择神经网络中的一些单元并将其临时隐藏,然后再进行该循环中神经网络的训练和优化过程。在下一次循环中,又随机选择神经层中的一些单元并将其临时隐藏,然后再进行该次循环中神经网络的训练和优化过程。如此,直至训练结束。每次选择都是独立的。
③. 图示:
Dropout 一般用在全连接层。
④. 在训练时,每个神经元以概率 被保留 (dropout 丢弃率为 );在测试阶段,每个神经单元都是存在的,权重参数 需要乘以 ,成为:。
⑤. 测试时需要乘上 的原因
考虑第一个隐藏层的一个神经元在 dropout 之前的输出是 ,那么 dropout 之后的期望值是 ,在测试时该神经元总是激活的,为了保持同样的输出期望并使下一层也得到同样的结果,需要调整 。其中 是 Bernoulli 分布( 0 - 1 分布) 中值为 1 的概率。
⑥. inverted dropout
在训练时,由于舍弃了一些神经元,因此在测试时需要在激励的结果中乘上因子 进行缩放,只是这样需要对测试代码进行更改并增加了测试的计算量,非常影响测试性能。通常为了提高测试的性能(减少测试时的运算时间),可以将缩放的工作转移到训练阶段,而测试阶段与不用 dropout 时相同,称为 inverted dropout。将前向传播 dropout 时保留下来的神经元的权重乘上 (看作惩罚项,使权重扩大为原来的 倍,这样测试时不用缩小权重),在架构中添加 inverted dropout 这一改动仅会影响训练过程,而并不影响测试过程 ,dropout 的比例常用值为
⑦. Dropout 解决过拟合的原因
a. 取平均的作用
dropout 丢掉不同的隐藏层神经元就类似于在训练不同的网络,随机丢掉部分隐藏神经元导致网络结构已经不同,整个 dropout 过程就相当于对很多个不同的神经网络取平均。而不同的网络产生不同的拟合,一些互为 “反向” 的拟合相互抵消就可以达到整体上减小过拟合。
b. 减少神经元之间复杂的共适应关系
因为 dropout 程序导致两个神经元不一定每次都在一个 dropout 网络中出现。这样权值的更新不再依赖于有固定关系的隐含节点的共同作用,阻止了某些特征仅仅在其他特定特征下才有效果的情况。迫使网络取学习更加鲁棒性(健壮性)的特征,这些特征在其他的神经元的随机子集中也存在。换句话说,假如神经网络是在做某种预测,它不应该对一类特定的线索片段太过敏感,即使丢失特定的线索,它也应该可以从众多其他线索中学习到一些共同特征。从这个角度看 dropout 就有点像 正则,减少权重是的网络对丢失特定神经元连接的鲁棒性提高。
c. dropout 类似于生物学中性别繁衍在生物进化中的角色
物种为了生存,往往会倾向于适应所在的环境,环境的突变则会导致物种难以做出及时的反应。性别的出现可以繁衍出适应新环境的变种,有效地阻止过拟合,即避免环境改变时物种可能面临的灭绝。而 dropout 使神经随机组合成新的神经网络,就类似于性别繁衍时基因重组。
(4). BN (Batch Normalization, BN) 批量归一化
批量归一化,就是对每一批数据进行归一化处理。
①. 使用 BN 的原因
网络一旦 train 起来,那么参数就会发生更新,除了输入层数据外(假设输入层数据已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数分布是一直在发生变化的,因为在训练的时候,前面层训练参数 的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数 和 input 计算得到的,而第一层的参数 在整个训练过程中一直在更新变化,隐藏必然会引起后面每一层输入数据的改变。在网络中间层训练过程中,数据分布的改变被称为:“Internal Covariate Shift”。BN 的提出,就是要解决在训练过程中,中间层数据分布发生改变的情况。
②. BN 的使用
在神经网络的每个全连接和激活函数之间增加 BN 层,对每层的 input 都做 BN 操作,用 BN 返回的 data,再与全连接层的 代入激活函数进行计算。
③. BN 的网络结构
④. BN 的处理方法
输入:批量(mini batch) 输入的
输出:规范化后的
a. 求每一个训练批次数据的均值
b. 求每一个训练批次数据的方差
c. 做均值方差归一化, 为无穷小数,用于避免分母为零
d. 返回均值方差归一化后的
⑤. BN 的理解
BN 就是通过一定的规范化手段,对于每个隐层神经元,把逐渐向非线性函数映射后取值区间极限饱和区靠拢的输入分布强制拉回到均值为 0,方差为 1 的比较标准的正太分布,使得非线性变换函数的输入值落入比较敏感的区域,以此避免梯度消失的问题。
⑥. BN 的优点
a. BN 使得网络中每层输入数据分布相对稳定,加速模型学习速度
b. BN 使得模型对网络中的参数不那么敏感,简化调参过程,使得网络学习更加稳定。
c. BN 允许网络使用饱和性激活函数(如 Sigmoid、Tanh 等),缓解了梯度消失的问题。
d. BN 具有一定的正则化效果。
(5). 参数初始化
参数初始化常用的方法有以下三种:
①. uniform 均匀分布初始化
w = np.random.uniform(low=scale, high=scale, size=[n_in, n_out])
scale:在 Xavier 初始法,适用于普通激活函数(Tanh、Sigmoid 等)
scale = np.sqrt(3 / n)
在 He 初始法,适用于 ReLU:
scale = np.sqrt(6 / n)
n_in:为网络输入的大小
n_out: 为网络输出的大小
n:为 n_in 或
②. normal 高斯分布初始化
w = np.random.randn(n_in, n_out) * stdev
stdev:为高斯分布的标准化,均值设为 0
在 Xavier 初始法,适用于普通激活函数(Tanh、Sigmoid 等)
stdev = np.sqrt(n)
在 He 初始法,适用于 ReLU:
stdev = np.sqrt(2 / n)
Xavier 也可以用下面的计算方法 :
③. svd (白化) 初始化,对 RNN 有较好的效果
(6). 数据预处理方式
①. zero-center 零均值化,这个挺常用的。
x -= np.mean(x, axis=0)
axis:为对 x 的某一维度进行操作。
如 axis=0 时,表示对 x 的列进行求均值操作
axis=1 时,表示对 x 的行进行求均值操作
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# ============================================
# @Time : 2020/02/01 16:04
# @Author : WanDaoYi
# @FileName : test_code.py
# ============================================
import numpy as np
x = [[1, 3, 5],
[2, 4, 7],
[1, 5, 7]
]
print(np.mean(x, axis=0))
输出结果为 3 列相对应的均值:[1.33333333, 4.0 , 6.33333333]
同样的,还有 x /= np.std(x, axis=0) 或 normalize
②. PCA Whitening PCA 白化,这种用得比较少
a. Whitening 白化 相当于在零均值化和归一化之间插入一个旋转操作,将数据投影到主轴上。
(a). 首先将数据零均值化
x -= np.mean(x, axis=0)
(b). 再计算协方差
cov = np.dot(x.T, x) / x.shape[0]
(c). 计算数据协方差矩阵的奇异值分解
u, s, v = np.linalg.svd(cov)
(d). 对数据去相关
x_rot = np.dot(x, u)
(e). 白化,即把特征基空间的数据除以每个维度的特征值来标准化尺度。这里加了个 1e-5 是为了防止分母为 0 的情况
x_whiten = x_rot / np.sqrt(s + 1e-5)
b. PCA 白化的缺点
(a). 白化过程计算成本高
(b). 白化会增加数据中的噪声,因为它把输入数据的所有维度延伸到相同的大小,这些维度中就包含噪声维度(往往表现为不相关的且方差较小)。这种缺点在实际操作中可以通过把 1e-5 增大到一个更大的值来引入更强的平滑。
c. 在全连接层选择 BN,而不选择 PCA 白化的原因:
(a). 白化过程计算成本高昂,并且在每一轮训练中的每一层都需要做如此高成本计算的白化操作
(b). 白化过程由于改变了网络每一层的分布,因而改变了网络中本身数据的表达能力。底层网络学习到的参数信息会被白化操作丢失掉。
(7). 训练技巧
a. 样本需要足够多,足够随机,并且对样本进行归一化处理
b. 要做梯度归一化,即算出来的梯度除以 mini batch size。
c. 梯度裁剪
限制最大梯度,其实是 , 如果 value 超过了阈值,就算一个衰减系数,让 value 的值等于阈值,如 5, 10, 15 等。
d. dropout 对小数据防止过拟合有很好的效果,值一般设为 0.5。也可以使用 正则化防止过拟合。
e. 需要把神经网络层之间的输入限制成 零均值 之内,尽量不要使用 Sigmoid,可以用 Tanh 或 ReLU 之类的激活函数
Sigmoid 函数在 (-4, 4) 的区间,才有较大的梯度,之外的区间,梯度接近于 零,很容易造成梯度消失的问题。
输入 零均值,Sigmoid 函数的输入不是 零均值。
f. ReLU + BN 这套组合,可以满足 95% 的情况。除非有些特殊情况会用 identity,比如回归问题
g. 对数据 shuffle 和 augmentation
h. 降低学习率
随着网络训练的进行,学习率要逐渐降下来,同样的,fine-tuning 也要根据模型的性能设置合适的学习率
i. 合理的使用 tensorboard,监视网络的状况,来调整网络参数。
j. 随时存档模型,要有 validation
把每个 epoch 和其对应的 validation 结果存下来,可以分析出开始 overfitting 的时间点,方便下次加载 fine-tuning
k. 网络层数
在性能不丢的情况下,减到最小
l. batch_size
一般从 128 左右开始调整,调整为 2 的倍数。batch_size 合适最重要,并不是越大越好。
(8). Ensemble 集成学习
Ensemble 是论文刷结果的终极核武器,深度学习中一般有以下几种方式:
①. 同样的参数,不同的初始化方式
②. 不同的参数,通过 cross validation,选取最好的一组
③. 同样的参数,模型训练的不同阶段,即不同迭代次数的模型
④. 不同的模型,进行线性融合,例如 RNN 和 传统模型
⑤. 训练多个模型,在测试时将结果评价起来,大约可以得到 2% 提升。
⑥. 训练单个模型时,平均不同时期的 checkpoints 的结果,也可以有提升
⑦. 测试时可以将测试的参数和训练的参数组合起来。
上一章:深度篇——神经网络(三) 网络拓扑与训练神经网络
下一章:深度篇——神经网络(五) 细说 优化器