深度学习
该内容由个人整理和归纳,如有不同见解,还望指教~
为什么要通过梯度下降求解参数?
梯度的方向是函数增长速度最快的方向,那么梯度的反方向就是函数下降最快的方向,通过往函数下降最快的方向走,可以走到函数的极小/最小值点。
Embedding
为什么需要 Embedding?
- 因为有些类别特征转换为onehot编码后会非常稀疏,而深度学习的结构不适合处理稀疏向量,因此需要通过Embedding将稀疏向量转换为稠密向量。
- Embedding 的表达能力相比原始向量更强,可以融合大量有价值信息,是极其重要的特征向量。
初始化
为什么要初始化神经网络权重?(全0初始化的问题?)
全零初始化方法在前向传播过程中会使得隐层神经元的激活值均未0,在反向过程中根据BP公式,不同维度的参数会得到相同的更新。
需要破坏这种“对称性”。
本质是为了让输入输出的方差在一个水平上,让收敛过程稳定,防止输入空间比输出空间稠密太多导致收敛震荡,以及防止输入空间比输出空间稀疏太多收敛过慢。
Glorot(Xavier)初始化器的缺点
因为Xavier的推导过程是基于几个假设的,
-
其中一个是激活函数是线性的,这并不适用于ReLU,sigmoid等非线性激活函数;
-
另一个是激活值关于0对称,这个不适用于sigmoid函数和ReLU函数它们不是关于0对称的。
损失函数
focal loss怎么实现的(字节)
center loss(字节)
优化器
优化方法有哪些?(京东)
-
梯度下降 GD:在参数更新时使用所有样本进行更新。
- 缺点:计算量大,速度慢。
-
小批梯度下降 Mini-batch GD:参数更新时使用一部分样本进行更新。
- 优点:减少了参数更新的次数,可以达到更加稳定收敛结果。
-
随机梯度下降 SGD:参数更新时只使用一个样本来进行更新。
- 优点:训练速度快
- 缺点:由于仅使用一个样本点来进行迭代,导致迭代方向变化很大,使得收敛到局部最优解的过程更加的复杂。
上述算法是从每次更新时使用的样本数量来划分的。
-
牛顿法:采用了二阶导来作为一阶导的学习率来更新梯度。
-
动量梯度下降 Momentum:采用累积加权梯度来作为要更新的梯度。使得算法更关注于趋势而非噪声。
\[v_t = m * v_{t-1} + g_t \\ W_{t} = W_{t-1} - \mu * v_t \]如果衰减率 \(\mu\) 为 0,那么它与原版梯度下降完全相同。如果衰减率 \(\mu\) 为1,那么它就会像我们开始提到的无摩擦碗的类比一样,前后不断地摇摆; 你不会想要这样的结果。通常衰减率选择在0.8-0.9左右,它就像一个有一点摩擦的表面,所以它最终会减慢并停止。
-
动量移动得更快(因为它积累的所有动量)
-
动量有机会逃脱局部极小值(因为动量可能推动它脱离局部极小值)。同样,它也将更好地通过高原区。
- 优点:由于存在历史梯度的累积,因此每次更新震荡相比不采用动量的梯度没那么大。
- 缺点:在临近最小点时,动量也会增加。如果动量增加过大,算法将无法停在正确位置。
-
-
ADAGrad:加入了二阶累积动量的根号项作为当前更新梯度的分母来动态调整学习率。
\[G_t = G_{t-1} + g_{t}^2 \\ W_t = W_{t-1} - \frac{\mu}{\sqrt{G_t}} g_{t} \]对于经常更新的参数,我们已经积累了大量关于它的知识,不希望被单个样本影响太大,希望学习速率慢一些;对于偶尔更新的参数,我们了解的信息太少,希望能从每个偶然出现的样本身上多学一些,即学习速率大一些。
这一方法在稀疏数据场景下表现非常好。但也存在一些问题:因为 是单调递增的,会使得学习率单调递减至0,可能会使得训练过程提前结束,即便后续还有数据也无法学到必要的知识。
- 优点:能更好地避开鞍点
- 缺点:到后期更新会非常慢 (因为分母在不停增大)
-
ADADelta / RMSProp(Root Mean Squared Propagation): 不累积全部历史梯度,而只关注过去一段时间窗口(移动平均的思想)的下降梯度。
\[G_t = \lambda * G_{t-1} + (1 - \lambda) * g_{t}^2 \\ W_t = W_{t-1} - \frac{\mu}{\sqrt{G_t}} g_{t} \]优点:避免了二阶动量持续累积、导致训练过程提前结束的问题
-
ADAM:结合了ADADetla和Momentum的特点,既采用了在一阶指数移动平均动量来控制梯度,也采用了二阶指数移动平均动量来控制学习率。
\[v_t = m * v_{t-1} + (1-m) * g_t \\ G_t = \lambda * G_{t-1} + (1 - \lambda) * g_{t}^2 \\ W_{t} = W_{t-1} - \frac{\mu}{\sqrt{G_t}} v_{t} \\ \]m 通常设置为 0.9,\(\lambda\) 通常设置为 0.999。
Adam 的能力来自于动量的速度和 RMSProp 适应不同方向的梯度的能力。这两者的结合使它变得更强大。
为什么有解码器和编码器的模型需要两个优化器?
因为在构建优化器对象时,需要传入模型参数 model.parameters()
作为一个输入,与此同时也可以分别设置不同部分的学习率。
小批梯度下降的样本数 m 怎么选择?
小批梯度下降的样本怎么进行采样?
梯度下降算法中的学习率如何选取?
GD和SGD原理和各自的缺陷?(京东)
ADAM和SGD的优缺点以及讲诉方法(云从)
Mini-Batch SGD相对于One Example SGD的两个优势:梯度更新方向更准确;并行计算速度快;
反向传播 BP 算法:
以目标函数的负梯度方向对参数进行调整并更新参数,\(W \gets W - \alpha \frac{\partial Loss}{\partial W}\)
首先,假设某个神经元的输入为z,经过激活函数\(f_1(·)\)得到输出\(a\)。即函数值\(a=f1(z)\)。如果这里的输入\(z\)又是另一个函数\(f_2\)的输出的话(当然啦,这里的\(f_2\)就是线性映射函数,也就是连接某两层的权重矩阵),即\(z=f_2(x)\),那么如果基于\(a\)来对\(z\)中的变量\(x\)求导的时候,由于
\[\frac{\partial a}{\partial x}=\frac{\partial a}{\partial z}\cdot \frac{\partial z}{\partial x}=f_1'(z)\cdot \frac{\partial z}{\partial x} \]显然只要乘以激活函数\(f_1\)的导数,就不用操心激活函数的输出以及更后面的事儿了(这里的“后面”指的是神经网络的输出端方向),只需要将精力集中在前面的东西,即只需要关注z以及z之前的那些变量和函数就可以了。因此,误差反向传播到某非线性映射层的输出时,只需要乘上该非线性映射函数在z点的导数就算跨过这一层啦。
而由于\(f_2(·)\)是个线性映射函数,即\(f_2(x)=w\cdot x\),因此
\[\frac{\partial z}{\partial x}=f_2'(x)=[wx]'=w \]因此,当误差反向传播到线性映射层的输出时,若想跨过该层,只需要乘以线性映射函数的参数就可以啦~即乘上w。
而这里的x,又是更后面的非线性映射层的输出,因此误差在深度前馈网络中反向传播时,无非就是反复的跨过非线性层和线性层,也就是反复的乘以非线性函数的导数(即激活函数的导数)和线性函数的导数(即神经网络的参数/权重/连接边)。