【NLP面试QA】基本策略
西多士NLP 人气:2
[TOC]
#### 防止过拟合的方法
- 根据验证集分数设置 early_stoping
- 数据增强
- dropout
- 正则化:正则化会使得参数值更小,模型更简单,从而避免过拟合,即奥卡姆剃刀原理
- 还有一些其他的方法,比如采用对抗训练的方法可以增强模型的鲁棒性和抗干扰能力,也能一定程度上防止过拟合
#### 什么是梯度消失和梯度爆炸?如何解决?
- 由于梯度反向传播遵循链式求导法则,浅层网络的梯度包含深层网络梯度的累乘项,当多个梯度远小于 1 时,使得浅层神经网络的梯度趋向于 0,难以训练。相对的,若多个梯度远大于 1,将使得浅层网络的梯度远大于 1,不断对梯度进行修正,使得网络权重不断增大从而导致上溢,无法被训练。
- 梯度爆炸:
- 产生原因:(1)隐藏层的层数过多;(2)权重的初始化值过大
- 解决方案:(1)梯度裁剪;(2)采用 ReLU 等激活函数
- 梯度消失:
- 产生原因:(1)隐藏层的层数过多;(2)激活函数梯度较小
- 解决方案:(1)采用残差网络;(2)合适的权重初始化策略;(3)采用 Relu 等激活函数(梯度为1);(4)BatchNorm 等规范化方法
#### 在深度学习中,网络层数增多会伴随哪些问题,怎么解决?
- 计算资源的消耗(GPU)
- 模型容易过拟合(Dropout)
- 梯度消失/梯度爆炸问题的产生(批量归一化BN):归一化操作能对各层的输出做归一化,这样梯度在反向层层传递后仍能保持大小稳定,不会出现过小或过大的情况。
- 退化问题:随着网络层数的增多,训练集loss逐渐下降,然后趋于饱和,当你再增加网络深度的话,训练集loss反而会增大(残差网络ResNet)
#### 关于模型参数
##### 模型参数初始化的方法
- 均匀分布
- 正态分布
- 正交初始化
- 稀疏初始化
- Xavier 正态分布(Xavier 根据每一层的神经元个数来设置每层权值初始化的方差,防止梯度消失的情况出现,对于中心对称的激活函数十分有效)
- Kaiming 正态分布(针对于 ReLU 激活函数,Xavier 还是会出现梯度消失的情况,因此提出了Kaiming 分布)
##### 模型参数初始化为 0、过大、过小会怎样?
- 初始化为 0,前向计算时,所有的隐层神经元的激活值都相同。这样会导致所有神经元都是对称的而没有区分性,无法提取不同特征。不仅仅在初始化为 0 的时候会出现这种情况,严格上来说不能将网络参数初始化为一个常数值
- 参数过小或过大:对于 sigmoid 和 tanh 这一类激活函数,初始化参数过小,意味着激活函数将丢失非线性能力。而当参数初始化过大的时候,将导致参数的激活值变得饱和,从而导致梯度变为零,导致模型难以训练
##### 为什么说模型参数越小,模型越简单
- 模型参数越小,使得某些维度上的特征受到抑制难以表达,类似于 dropout 的作用
- 另一方面,对于 sigmoid 以及 tanh 这一类的激活函数,模型参数过小,将使得模型丢失非线性能力
#### 正则化 Regularization
##### 正则化方法
- 正则化是在损失函数中加入一个正则化项,正则化项表明,模型参数越大,对损失函数的惩罚越大,迫使模型参数在低损失的同时尽量变小。
- L1正则化:$J = \frac{1}{m} \sum_{i=1}^m L(f(x_i), y) + \frac{\lambda}{2m} \sum_{j}|w_j|$
- L2正则化:$J = \frac{1}{m} \sum_{i=1}^m L(f(x_i), y) + \frac{\lambda}{2m} \sum_{j}w_j^2$
- L1正则化会是的网络稀疏的原因:由于L正则化中绝对值的引入,使得当权重 $w_i=0$ 的时候,其反向传播梯度在$0^+$和$0^-$是非连续的,当两侧的梯度异号时,$w_i=0$ 则成为了一个极小值,从而不再更新。多个权重发生这个情况的话,就使得网络变得稀疏了。
##### 正则化如何解决过拟合的
- 正则化在损失函数中加上了权值相关的惩罚项,对解空间加了额外的约束,避免模型过度拟合数据
- 另一方面正则化会使得模型参数尽量小,参数越小,对于 sigmoid 和 tanh 等激活函数的激活值容易落在线性区间,使得模型的非线性能力减弱(模型越简单越能避免过拟合即奥卡姆剃刀原理——“如无必要,勿增实体”,即“简单有效原理”)
##### 如何在代码中加入正则化
- 通常加正则化不会直接加在 loss 函数上,在 pytorch 的 optimization 中有一个 weight_decay 的关键字,可以对其进行设置,等效为 L2 正则化
#### 关于梯度下降
##### Batch/Mini-Batch/SGD梯度下降
- Batch 梯度下降:训练所有样本,累加loss之后,再进行梯度反向传播,更新模型参数。通常在小数据集时采用这种方法,因为越多的数据越能代表样本总体
- SGD随机梯度下降:
- 每次仅训练单个样本传播一次梯度
- 容易受到单个样本噪声的影响
- 训练速度较慢
- 最终通常在最优点附近持续震荡,难以收敛
- mini-Batch梯度下降:训练mini-batch个样本,累加 loss 之后,进行梯度反向传播,更新参数,如果 mini-batch 为1,则是随机梯度下降算法,如果 mini-batch 为 m(数据集大小),即是 batch 梯度下降法。当数据量足够大,m 足够大时,可以等价于 Batch 梯度下降
##### 增大 batch size 的影响
- 增大内存利用率,并行效率提高,训完一个 epoch 的迭代次数减少
- 各个样本之间的梯度相互抵消,减小单个样本噪声的影响,下降方向更接近样本总体的方向
- 但过大的 batch size 会使得迭代次数减少,想要达到相同的精度的时间大大增加,
- batch size 增大到一定程度梯度下降方向基本不再改变
##### 优化算法(Momentum/RMSProp/Adam)
- 动量梯度下降算法(Momentum)
- 额外维护了参数梯度的一个滑动平均值,更新参数的不直接利用权重的梯度,而是利用当前的一个滑动平均值来进行更新,这样的做法使得多次迭代的梯度在非收敛方向上的分量相互抵消,而收敛方向上的分量不断叠加,使得收敛速度更快。
$$
\begin{aligned}
&v_{dW^{l}} = \beta v_{dW^{l}} + (1-\beta)dW^{l}\\
&v_{db^{l}} = \beta v_{db^{l}} + (1-\beta)db^{l}\\
&W^{l} = W^{l} - lr v_{dW^{l}}\\
&b^{l} = b^{l} - lr v_{db^{l}}
\end{aligned}$$
- RMSProp算法(Root Mean Square Prop,均方根支):
- RMSProp算法额外维护了参数梯度二阶动量的滑动平均,二阶动量记载了历史梯度的变化幅度大小,利用二阶动量信息对梯度的更新做了一个限制作用,如果二阶动量的平均信息较大,说明该时段的梯度变化范围较大,我们在该时段的梯度更新幅度就应该更小,减少在前往最小值路径上的摆动情况
$$
\begin{aligned}
&s_{dW^{l}} = \beta s_{dW^{l}} + (1-\beta)(dW^{l})^2\\
&s_{db^{l}} = \beta s_{db^{l}} + (1-\beta)(db^{l})^2\\
&W^{l} = W^{l} - lr \frac{dW}{\sqrt{s_{dW}} + \epsilon}\\
&b^{l} = b^{l} - lr \frac{dW}{\sqrt{s_{db}} + \epsilon}
\end{aligned}
$$
- Adam优化算法:结合了动量梯度下降算法以及 RMSProp 算法,能够有一个超越两者单独的一个效果
#### 归一化 Normalization
##### 深度学习中的 Internal Covariate Shift(内部协变量偏移)
深度神经网络涉及到很多层的叠加,而每一层的参数更新会导致上层的输入数据分布发生变化,通过层层叠加,高层的输入分布变化会非常剧烈,这就使得高层需要不断去重新适应底层的参数更新。Google 将这一现象总结为 Internal Covariate Shift,简称 ICS。
##### ICS 会导致什么问题
- 上层参数需要不断适应新的输入数据分布,降低学习速度。
- 下层输入的变化可能趋向于变大或者变小,导致上层落入饱和区,使得学习过早停止。
- 每层的更新都会影响到其它层,因此每层的参数更新策略需要尽可能的谨慎。
##### Normalization 的基本思想与通用框架
- **基本思想**:在将 **输入数据** 送给神经元之前,先对其做平移和伸缩变换, 将 **输入数据** 的分布规范化成在固定区间范围的标准分布。
- **通用变换框架**:
$$h=f(g\cdot \frac{x-\mu}{\sigma} + b)$$
其中 $\mu$ 和 $\sigma$ 是平移和缩放参数,用于将数据转化为标准正态分布。而 $b$ 和 $\sigma$ 为**再平移和再缩放参数**,为可学习的,用于将数据转化为相应的非标准正态分布。**再平移和再缩放的操作是为了保证模型的表达能力不因为规范化而下降,或者说,在一定程度上尊重了神经元的学习结果**。
- **Batch Normalization** —— 纵向规范化
- 其规范化针对单个维度的输出 $x_i$(单个神经元的输出)进行的,利用网络训练时一个 mini-batch 该神经源的输出来计算 $x_i$ 的均值和方差,因而称为 Batch Normalization。
$$\mu_i = \frac{1}{M}\sum x_i, \sigma_i = \sqrt{\frac{1}{M}\sum (x_i-\mu_i)^2+\epsilon}$$
其中,$M$ 是 Mini-batch 的大小。BN 比较适用的场景是:每个 mini-batch 比较大,数据分布比较接近。在进行训练之前,要做好充分的 shuffle. 否则效果会差很多。该方法在CNN中表现良好,但是在RNN中表现欠佳
- **Layer Normalization** —— 横向规范化
- 层规范化就是针对 BN 的上述不足而提出的。与 BN 不同,LN 是一种横向的规范化,同一个规范化操作来转换所有维度的输入。
$$\mu = \sum x_i, \sigma = \sqrt{\sum (x_i-\mu_i)^2+\epsilon}$$
参数均为标量(BN中是向量),所有输入共享一个规范化变换。LN 针对单个训练样本进行,不依赖于其他数据,因此可以避免 BN 中受 mini-batch 数据分布影响的问题,可以用于 小mini-batch场景、动态网络场景和 RNN,特别是自然语言处理领域。此外,LN 不需要保存 mini-batch 的均值和方差,节省了额外的存储空间。
##### 为什么 NLP 中用 Layer Normalization 效果较好而 CV 中 Batch Normalization 的效果较好
LN 和 BN 的主要区别在于 normalization的方向不同。
对于 RNN 等时序模型,具有两个特点:
- 同一个 batch 内部的训练实例长度不一(不同长度的句子),样本间的数据分布差别较大
- 另外对于文本数据同一个词很可能出现在不同的位置,即同一位置的数据分布会非常不一致
数据分布差异大是 BatchNorm 无法解决的问题,因此不适用。而对于句子方向上的归一化更为合适的,不会引入样本间的差异,而且句子的基本成分都是固定的,因此 LayerNorm 更为合适。
加载全部内容