【NLP实践-Task5 神经网络基础】深度学习基础
目录
前馈神经网络
深度前馈网络(deep feedfoward network)也称作前馈神经网络(feedforward neural network)或者多层感知机(multilayer perceptron:MLP),它是最典型的深度学习模型。
- 卷积神经网络就是一种特殊的深度前馈网络。
- 深度前馈网络也是循环神经网络的基础。
反向传播
当我们定义神经网络时,我们为我们的节点分配随机权重和偏差值。一旦我们收到单次迭代的输出,我们就可以计算出网络的错误。然后将该错误与成本函数的梯度一起反馈给网络以更新网络的权重。 最后更新这些权重,以便减少后续迭代中的错误。使用成本函数的梯度的权重的更新被称为反向传播。
在反向传播中,网络的运动是向后的,错误随着梯度从外层通过隐藏层流回,权重被更新。
输入/隐藏/输出层
输入层是接收输入那一层,本质上是网络的第一层。而输出层是生成输出的那一层,也可以说是网络的最终层。处理层是网络中的隐藏层。这些隐藏层是对传入数据执行特定任务并将其生成的输出传递到下一层的那些层。输入和输出层是我们可见的,而中间层则是隐藏的。
隐藏单元(**函数 )
一旦将线性分量应用于输入,将会需要应用一个非线性函数。这通过将**函数应用于线性组合来完成。**函数将输入信号转换为输出信号。应用**函数后的输出看起来像 f(a *W1+ b),其中 f()就是**函数。
在下图中,我们将"n"个输入给定为 X1 到 Xn 而与其相应的权重为 Wk1 到 Wkn。我们有一个给定值为 bk 的偏差。权重首先乘以与其对应的输入,然后与偏差加在一起。而这个值叫做 u。
U =ΣW*X +b
**函数被应用于 u,即 f(u),并且我们会从神经元接收最终输出,如 yk = f(u)。
最常用的**函数就是ReLU 、Sigmoid和 softmax。
ReLU(修正线性单元)
公式:f(x)=max(x,0)
当 X>0 时,函数的输出值为 X;当 X<=0 时,输出值为 0。
它和线性单元非常类似,区别在于:修正线性单元在左侧的定义域上输出为零。函数图如下图所示:
使用 ReLU 函数的最主要的好处是对于大于 0 的所有输入来说,它都有一个不变的导数值。常数导数值有助于网络训练进行得更快。
修正线性单元的3个扩展:当z<0时,使用一个非零的斜率α:h = g(z, α) = max(0, z) + α*min(0, z)
- 绝对值修正absolute value rectification:使用 α = -1,此时 g(z) = |z|。
- 渗透修正线性单元leaky ReLU:将 α 固定成一个类似 0.01 的小值。
- 参数化修正线性单元parametric ReLU:将 α 作为学习的参数。此时 α 是与训练集相关的。不同的训练集,学得的 α 会不同。
Sigmoid/ tanh
公式:sigmoid(x)=1/(1+e -x )
Sigmoid 变换产生一个值为 0 到 1 之间更平滑的范围。我们可能需要观察在输入值略有变化时输出值中发生的变化。光滑的曲线使我们能够做到这一点,因此优于阶跃函数。
有一些网络不能使用修正线性单元,因此sigmoid**函数是个更好的选择,尽管它存在饱和问题。比如:
- RNN:修正线性单元会产生信息爆炸的问题。
- 一些概率模型:要求输出在0~1之间。
Softmax
Softmax **函数通常用于输出层,用于分类问题。它与 sigmoid 函数是很类似的,唯一的区别就是输出被归一化为总和为 1。Sigmoid 函数将发挥作用以防我们有一个二进制输出,但是如果我们有一个多类分类问题,softmax 函数使为每个类分配值这种操作变得相当简单,而这可以将其解释为概率。
以这种方式来操作的话,我们很容易看到——假设你正在尝试识别一个可能看起来像 8 的 6。该函数将为每个数字分配值如下。我们可以很容易地看出,最高概率被分配给 6,而下一个最高概率分配给 8,依此类推……
**函数对比
sigmoid
主要缺点:
- 容易饱和从而使得梯度消失。当**函数取值在接近0或者1时会饱和,此时梯度为近似为0。
- 函数输出不是零中心的。这会导致后续神经元的输出数值总是正数。
tanh
- 优点:函数输出是零中心的。
- 缺点:容易饱和从而使得梯度消失。
tanh **函数几乎在所有场合都是优于sigmoid **函数的。但是有一种情况例外:如果要求函数输出是0~1 之间(比如表征某个概率),则二者之间必须用sigmoid。
relu
-
优点:对随机梯度下降的收敛有巨大的加速作用,而且非常容易计算。
-
缺点:可能导致神经元死掉。当一个很大的梯度流过 relu神经元时,可能导致梯度更新到一种特别的状态:在这种状态下神经元无法被其他任何数据点再次**。此后流过这个神经元的梯度将变成 0,该单元在训练过程中不可逆的死亡。如果学习率设置的过高,可能会发现网络中大量神经元都会死掉。整个训练过程中,这些神经元都不会被**。
leaky relu
为了解决 relu 死亡神经元的问题的尝试,但是效果并不明显。
**函数选取准则
-
通常建议使用 relu**函数。
- 注意设置好学习率,同时监控网络中死亡的神经元占比。如果神经元死亡比例过高,则使用 leaky relu 或者 maxout **函数。
损失函数
损失函数的非凸性
在线性模型中,对于线性回归模型,可以直接求解出解析解。对于logistic回归或者SVM,其损失函数为凸的。
凸优化算法可以保证全局收敛,而且理论上保证从任何一种参数出发都可以收敛。实际计算中,可能遇到数值稳定性问题。
神经网络和线性模型的最大区别是:神经网络的非线性导致大多数的损失函数都是非凸的。损失函数非凸导致两个问题:
-
基于梯度的优化算法仅仅能够使得损失函数到达一个较小的值,而不是全局最小值。
-
基于梯度的优化算法无法保证从任何一个初始参数都能收敛,它对于参数的初值非常敏感。对于神经网络:(1)通常将所有的权重值初始化为小的随机数。(2)通常将偏置初始化为零或者小的正值。不用负数是因为如果偏置的初始值为负,很可能导致某些神经元一直处于未**状态。
常用的损失函数
损失函数分为经验风险损失函数和结构风险损失函数。经验风险损失函数:预测结果和实际结果的差别。结构风险损失函数:经验风险损失函数加上正则项。通常表示为如下:
分类问题:交叉熵(cross entropy)
回归问题:均方误差(MSE)
- 0-1损失
- 绝对值损失
- log对数损失函数
- 平方损失函数
- 指数损失函数
- Hinge损失函数
0-1损失
0-1损失是指,预测值和目标值不相等为1,否则为0:
感知机就是用的这种损失函数。但是由于相等这个条件太过严格,因此我们可以放宽条件,即满足 |Y−f(X)|<T 时认为相等。
绝对值损失
log对数损失函数
L(Y,P(Y|X))=−logP(Y|X)
平方损失函数
指数损失函数
AdaBoost就是以指数损失函数为损失函数的。指数损失函数的标准形式:
Hinge损失函数
正则化
正则化策略:以增大训练误差为代价,来减少测试误差(如果在训练误差上很小,可能出现过拟合的情况)。
参数范数惩罚
许多正则化方法通过对目标函数JJ添加一个参数范数惩罚 Ω(θ),限制模型的学习能力,我们将正则化后的目标函数记为:
常见的参数正则化函数包括:L1、L2参数正则化。
L2正则
L2参数正则化能让学习深度学习的算法“感知”到具有较高方差的输入x,因此与目标的协方差较小(相对增加方差)的特征的权值将会收缩。它是权重衰减一种最常见的方式!
L1正则
L1正则化会产生更加稀疏的解(参数具有0的最优值),它与L2正则化不同,L2正则化不会使得某个权重为0,而L1正则化有可能通过足够大的 α 实现稀疏。
由L1正则化导出的稀疏性质已经被广泛地用于特征选择机制,特征选择从可用的特征子集选择应该使用的子集。特别是著名的LASSO(Tibshirani,1995)模型将L1惩罚和线性模型结合,并使用最小二乘代价函数。L1惩罚使部分子集的权重为零,表明相应的特征可以被安全地忽略。
其余正则化方法
防止或拟合最有效的方法就是增强训练集,训练集合越大,出现过拟合的概率也就越小;
- 数据集增强。在目标识别领域常用的方法是将图片进行旋转、缩放等(图片变换的前提是通过变换不能改变图片所属类别,例如手写数字识别,类别6和9进行旋转后容易改变类目) 。
- 噪声添加。可以对输入添加噪声,也可以对隐藏层或者输出层添加噪声。
- 语音识别中对输入数据添加随机噪声
- NLP中常用思路是进行近义词替换
- 提前终止(early stop,最常用的正则化形式,由于其简单性和有效性)。
- Dropout
- Bagging
详见:http://www.huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/chapters/3_regularization.html
优化算法
常用的优化算法:批量梯度下降、随机梯度下降、小批量梯度下降、Momentum、AdaGrad、RMSProp、Adam等。
详见:DL优化算法总结 https://blog.****.net/yyy430/article/details/84957040
深度模型优化策略
Batch Normalization(BN层)
问题提出:深度网络参数训练时内部存在协方差偏移(Internal Covariate Shift)现象:深度网络内部数据分布在训练过程中发生变化的现象。
为什么会带来不好影响:训练深度网络时,神经网络隐层参数更新会导致网络输出层输出数据的分布发生变化,而且随着层数的增加,根据链式规则,这种偏移现象会逐渐被放大。这对于网络参数学习来说是个问题:因为神经网络本质学习的就是数据分布(representation learning),如果数据分布变化了,神经网络又不得不学习新的分布。为保证网络参数训练的稳定性和收敛性,往往需要选择比较小的学习速率(learning rate),同时参数初始化的好坏也明显影响训练出的模型精度,特别是在训练具有饱和非线性(死区特性)的网络,比如即采用S或双S**函数网络,比如LSTM,GRU。
解决办法:引入Batch Normalization,作为深度网络模型的一个层,每次先对input数据进行归一化,再送入神经网络输入层。
Batch normalization实现:使网络某一层的输入样本做白化处理(最后发现等价于零均值化(Normalization)处理,拥有零均值,方差为1),输入样本之间不相关。通过零均值化每一层的输入,使每一层拥有服从相同分布的输入样本,因此克服内部协方差偏移的影响。由于输入样本X规模可能上亿,直接计算几乎是不可能的。因此,选择每个batch来进行Normalization。
Batch Normalization的优点
- 减少梯度对参数大小或初始值的依赖,使网络在使用较大学习速率训练网络参数时,也不会出现参数发散的情况。过高的学习速率会导致梯度爆炸或梯度消失,或者陷入局部极小值,BN可以帮助处理这个问题:通过把梯度映射到一个值大但次优的变化位置来阻止梯度过小变化:比如,阻止训练陷入饱和死区。
- 正则化模型,减少对dropout的依赖。BN正则化模型:使用BN训练时,一个样本只与minibatch中其他样本有相互关系;对于同一个训练样本,网络的输出会发生变化。这些效果有助于提升网络泛化能力,像dropout一样防止网络过拟合,同时BN的使用,可以减少或者去掉dropout类似的策略。
- 网络可以采用具有非线性饱和特性的**函数(比如:s型**函数),因为它可以避免网络陷入饱和状态。
Layer Normalization(LN层)
问题提出:BN针对一个minibatch的输入样本,计算均值和方差,基于计算的均值和方差来对某一层神经网络的输入X中每一个case进行归一化操作。但BN有两个明显不足:
- 高度依赖于mini-batch的大小,实际使用中会对mini-Batch大小进行约束,不适合类似在线学习(mini-batch为1)情况;
- 不适用于RNN网络中normalize操作:BN实际使用时需要计算并且保存某一层神经网络mini-batch的均值和方差等统计信息,对于对一个固定深度的前向神经网络(DNN,CNN)使用BN,很方便;但对于RNN来说,sequence的长度是不一致的,换句话说RNN的深度不是固定的,不同的time-step需要保存不同的statics特征,可能存在一个特殊sequence比其的sequence长很多,这样training时,计算很麻烦。
但LN可以有效解决上面这两个问题。
LN基于BN转化而来,LN与BN的不同之处在于:LN中同层神经元输入拥有相同的均值和方差,不同的输入样本有不同的均值和方差;而BN中则针对不同神经元输入计算均值和方差,同一个minibatch中的输入拥有相同的均值和方差。因此,LN不依赖于mini-batch的大小和输入sequence的深度,因此可以用于bath-size为1和RNN中对边长的输入sequence的normalize操作。
在传统RNN中,recurrent unit经过累加求和后的输入(summed input)的量级会随着训练进行发生波动,导致梯度爆炸或梯度消失发生。加入LN之后,Normalization term会对summed input的进行尺度变换,使RNN在training和inference时更加稳定。
实践证明,LN用于RNN进行Normalization时,取得了比BN更好的效果。但用于CNN时,效果并不如BN明显。
参数初始化
全零初始化
如果神经元的权重被初始化为0, 在第一次更新的时候,除了输出之外,所有的中间层的节点的值都为零。一般神经网络拥有对称的结构,那么在进行第一次误差反向传播时,更新后的网络参数将会相同,在下一次更新时,相同的网络参数学习提取不到有用的特征,因此深度学习模型都不会使用0初始化所有参数。一般只在训练SLP/逻辑回归模型时才使用0初始化所有参数。
随机初始化
将参数初始化为小的随机数。其中randn从均值为0,标准差是1的高斯分布中取样,这样,参数的每个维度来自一个多维的高斯分布。需要注意的是参数初始值不能取得太小,因为小的参数在反向传播时会导致小的梯度,对于深度网络来说,也会产生梯度弥散问题,降低参数的收敛速度。
缺点: 一个神经元输出的方差会随着输入神经元数量的增多而变大。对于有n个输入单元的神经元来说,考虑χ2分布,每个输入的方差是1/n时,总的方差是1。
标准初始化
权重参数初始化从区间均匀随机取值。即从(-1/√d,1/√d)均匀分布中生成当前神经元的权重,其中d为每个神经元的输入数量。
为什么要除以d? 这样可以确保神经元的输出有相同的分布,提高训练的收敛速度。
优点: 隐层的状态的均值为0,方差为常量1/3,和网络的层数无关,这意味着对于sigmoid函数来说,自变量落在有梯度的范围内。
Xavier初始化
优秀的初始化应该使得各层的**值和状态梯度的方差在传播过程中的方差保持一致。不然更新后的**值方差发生改变,造成数据的不稳定。
下面这两个图分别是标准初始化和xavier初始化带来的各层的反传梯度方差,可以看出xavier确实保持了一致性。
由于ReLU无法控制数据幅度,所以可以将其与Xavier初始化搭配使用。
偏置初始化
通常偏置项初始化为0,或比较小的数,如:0.01。
参考
AI算法工程师手册(华校专) http://www.huaxiaozhuan.com/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/chapters/1_deep_forward.html
常见的损失函数 https://blog.****.net/weixin_37933986/article/details/68488339
深度学习的正则化 https://blog.****.net/u014686462/article/details/70314306
DL优化算法总结 https://blog.****.net/yyy430/article/details/84957040
<深度学习优化策略-1>Batch Normalization(BN) https://mp.weixin.qq.com/s?src=3×tamp=1552363536&ver=1&signature=tRD*4aXGxzxjBr4t5osT7LqML3YtIEJKiBBuOsdSsU99JxG5Djf5KyOY1rYd3QiICapZQhQgRPfAdyAdQ8QfDMaC8fehr3ffPGjD2Nd1NXdLkz680REOTNy*epGY6Mfq*ZD3YfHtlr70tnkp2gY2hYqHxXW77ZVGx9wnAH0yego=
<优化策略-2>深度学习加速器Layer Normalization-LN https://mp.weixin.qq.com/s?src=3×tamp=1552366316&ver=1&signature=tRD*4aXGxzxjBr4t5osT7LqML3YtIEJKiBBuOsdSsU*7CvZNn*Og5nHo*ViOAbhLtbXQ9AgSzlz5eGeidK8MZv3gBDjhlGqoMTInOyHAyDsuBEQR2ri3OmZQw7YgLNiqO-JLgBXb6ZBStxYXZTzETDjFafNgatuIK0I*HxmmLAc=
深度学习总结(一)——参数初始化 https://blog.****.net/manong_wxd/article/details/78734725