纯优化:最小化目标J本身,比如线性模型的正规方程
学习:减低代价函数J,比如全连接层的梯度下降。有以下几个方面
从左图可以看出上面介绍的这些损失函数都可以 看作是0-1损失的单调连续近似函数,而因为这些损失函数通常是凸的连续函数,因此常用来代替 0-1损失进行优化。它们的相同点是都随 margin → − ∞ \operatorname{margin} \rightarrow-\infty margin→−∞而加大惩罚;不同点在于,他们增长方式不同。
代理损失函数可以进一步拉开不同类别的距离以改进分类器的鲁棒性,获得一个更强壮的、更值得信赖的分类器,从而,相对于简单地最小化训 练集上的平均 0 − 1 损失,它能够从训练数据中抽取更多信息。
小批量的大小通常由以下几个因素决定:
鞍点就是代价函数在某个横截面上的局部极小值. 它在一个维度方向上有极小值,而在另一个维度方向上可能是极大值,而非极小值。
(图片来源:https://arxiv.org/pdf/1211.5063.pdf)
悬崖是由于几较大个的权重相乘 导致的。遇到斜率极大的悬崖结构时,梯度更新会很大程度地改 变参数值,通常会完全跳过这类悬崖结构(我们可以看到一个局 部最小值在悬崖结构中间)。我们可以利用梯度截断(clipping)解决
由于变身的结构使模型丧失了学习到先前信息的能力,让优化变得极其困难。比如说RNN网络,如果时间跨度较大,后面的依赖关系就很难学习到早期序列的信息。经过许多阶段传播后的梯度倾向于消失(大部分情况)或者爆炸(很少,但是对优化过程影响很大)
在实践中,通常这些量会有噪声,甚至是有偏的估计。在一些情况下,我们希望最小化的目标函数实际上是难以处理的。当目标函数不可解时,通常其梯度也是难以处理的。在这种情况下,我们只能近似梯度。各种神经网络优化算法的设计都考虑到了梯度估计的缺陷。我们可以选择比真实损失函数更容易估计的代理损失函数来避免这个问题。
在训练中,每一步迭代都使用训练集的所有内容.
也就是说,利用现有参数对训练集中的每一个输入生成一个估计输出,然后跟实际输 出比较,统计所有误差,求平均以后得到平均误差,以此来作为更新参数的依据.
优点: 由于每一步都利用了训练集中的所有数据,因此当损失函数达到最小值以后, 能够保证此时计算出的梯度为0,换句话说,就是能够收敛(可以看到效果如左图所示 非常平滑).因此,使用BGD时不需要逐渐减小学习速率
缺点: 由于每一步都要使用所有数据,因此随着数据集的增大,运行速度会越来越慢.
在训练中,每次使用小批量(既一个小批量m 个训练 样本)的随机采样进行梯度下降。
训练方法和BGD一样,只是BGD最后的误差是对整个样本取平均,SGD是对小批 量的m个样本取平均。
因为小批量不能代表整个样本,使得梯度估计引入的噪声源,让SGD并 不是每次迭代都向着整体最优化方向,虽然包含一定的随机性(表现为 损失函数的震荡),但是从期望上来看,它是等于正确的导数的(表现 为损失函数有减小的趋势)。
优点:是训练速度会比较快。
缺点:是在样本数量较大的情况下,可能只用到了其中一部分数据就完成了训练, 得到的只是全局最优解。另外,小批量样本的噪声较大,所以每次执行梯度下降, 并不一定总是朝着最优的方向前进。
在训练中,采取的学习策略和SGD一样,不一样的是参数的更新。
SGD 在沟壑的情况下容易被困住, 沟壑就是曲面的一个方向比另一个方向更陡 (可以是鞍点),这时 SGD 会发生震荡而迟迟不能接近极小值。我们可以加入一个动量项,使得梯度方向不变的维度上速度变快,梯度方向有所改变的维度上的更新变慢,这样就可以加快收敛并减少震荡。
原来的优化是
{ v t = − η ∇ J ( θ t ) θ t + 1 = θ t + v t \left\{\begin{array}{ll} v_t = -\eta\nabla J(\theta_t) \\ \theta_{t+1} = \theta_{t} + v_{t} \\ \end{array}\right. { vt=−η∇J(θt)θt+1=θt+vt
加入动量项 α v t − 1 \alpha v_{t-1} αvt−1
{ v t = − η ∇ J ( θ t ) + α v t − 1 θ t + 1 = θ t + v t \left\{\begin{array}{ll} v_t = -\eta\nabla J(\theta_t) + \alpha v_{t-1} \\ \theta_{t+1} = \theta_{t} + v_{t} \\ \end{array}\right. { vt=−η∇J(θt)+αvt−1θt+1=θt+vt
这里超参数 α \alpha α一般取值0.9左右。【可以看出,如果没有动量项,那么从A点走到B点后,B点就会走向 B ′ B^{\prime} B′点,在纵轴维度上方向相反,产生振荡。加入了动量项之后,合成的梯度方向就会更加向横轴方向移动,减少在纵轴方向上的移动,也就抑制了震荡。这样一步一步下去,带着初速度的小球就会极速的奔向损失函数的极小值点。】这里 v t − 1 v_{t-1} vt−1表示之前所有步骤累积的动量和。
缺点:这种情况相当于小球从山上滚下来时是在盲目地沿着坡滚,如果它能具备一些先验知识,例如快要上坡时,就知道需要减速了的话,适应性会更好。
自适应学习率算法主要针对学习率的取值变化
AdaGrad 算法是借鉴 L 2 L_2 L2 正则化的思想,每次迭代时自适应地调整每个参数的学习率, 也就是对学习率进行了一个约束。
原先我们有 Δ θ t = − η ∇ J \Delta \theta_t=-\eta \nabla J Δθt=−η∇J,现在我们先设定 g t = ∇ J ( θ t ) g_t = \nabla J(\theta_t) gt=∇J(θt)
然后我们计算每个参数梯度平方的累积值
G t = ∑ τ = 1 t g τ ⊙ g τ G_{t}=\sum_{\tau=1}^{t} g_{\tau} \odot g_{\tau} Gt=τ=1∑tgτ⊙gτ
也就是
n t = n t − 1 + g t 2 n_{t}=n_{t-1}+g_{t}^{2} nt=nt−1+gt2
这里 ⊙ \odot ⊙表示按元素乘积。 g τ ∈ R ∣ θ ∣ g_{\tau} \in \mathbb{R}^{|\theta|} gτ∈R∣θ∣是第 τ \tau τ次迭代时的梯度
然后我们对梯度进行缩放
Δ θ t = − η n t + ϵ ⊙ g t \Delta \theta_{t}=-\frac{\eta}{\sqrt{n_{t}+\epsilon}} \odot g_{t} Δθt=−nt+ϵη⊙gt
【这里是逐元素的应用除、和、求平方根,也就是开平方、除、加运算都是按元素进行的操作 。】 ϵ \epsilon ϵ是为了保持数值稳定性而设置的非常小的常数,一般 取值 e − 7 e^{−7} e−7 到 e − 10 e^{−10} e−10
最后 θ ← θ + Δ θ \boldsymbol{\theta} \leftarrow \boldsymbol{\theta}+\Delta \boldsymbol{\theta} θ←θ+Δθ
注意:此处,对 g t g_t gt从1到t进行一个递推形成一个约束项regularizer,用来保证分母非0.
【简单说,就是通过累计梯度平方调节学习率】
特点:
缺点:
RMSprop 算法是 Geoff Hinton 提出的一种自适应学习率的方法可以在有些情况下避免 AdaGrad 算法中学习率不断单调下降以至于过早衰减的缺点。 RMSprop可以算作Adadelta的一个特例
RMSprop算法首先计算每次迭代梯度 g t g_t gt平方的指数衰减平均:
n t = β n t − 1 + ( 1 − β ) g t 2 n_{t}=\beta n_{t-1}+(1-\beta) g_{t}^{2} nt=βnt−1+(1−β)gt2
也就是
G t = β G t − 1 + ( 1 − β ) g t ⊙ g t G_{t}=\beta G_{t-1}+(1-\beta) g_{t} \odot g_{t} Gt=βGt−1+(1−β)gt⊙gt
其中 β \beta β是衰减率,一般取值为0.9或者0.5
参数更新差值就变成
Δ θ t = − η G t + ϵ ⊙ g t \Delta \theta_{t}=-\frac{\eta}{\sqrt{G_{t}+\epsilon}} \odot g_{t} Δθt=−Gt+ϵη⊙gt
特点:
Adam 算法(Adaptive Moment Estimation Algorithm)可以看作动量法和 RMSprop算法的结合,不但使用动量作为参数更新方向,而且可以自适应调整学习率。它对梯度的一阶矩估计(First Moment Estimation,即梯度的均值)和二阶矩估计(Second Moment Estimation,即梯度的未中心化的方差)进行综合考虑,计算出更新步长。
Adam 算法的提出者描述其为两种随机梯度下降扩展式的优点集合,即:
假设 t t t时刻,目标函数对于参数的一阶导数是 , g t ,g_t ,gt那么我们分别计算梯度平方 g t 2 g^{2}_{t} gt2的指数加权平均和梯度 g t g_t gt的指数加权平均(和动量法相似)
M t = β 1 M t − 1 + ( 1 − β 1 ) g t G t = β 2 G t − 1 + ( 1 − β 2 ) g t ⊙ g t \begin{array}{r} M_{t}=\beta_{1} M_{t-1}+\left(1-\beta_{1}\right) g_{t} \\ G_{t}=\beta_{2} G_{t-1}+\left(1-\beta_{2}\right) g_{t} \odot g_{t} \end{array} Mt=β1Mt−1+(1−β1)gtGt=β2Gt−1+(1−β2)gt⊙gt
接下来计算修正
M ^ t = M t 1 − β 1 t G ^ t = G t 1 − β 2 t \begin{aligned} \hat{M}_{t} &=\frac{M_{t}}{1-\beta_{1}^{t}} \\ \hat{G}_{t} &=\frac{G_{t}}{1-\beta_{2}^{t}} \end{aligned} M^tG^t=1−β1tMt=1−β2tGt
这是因为当t=0时,如果 G 0 = M 0 = 0 G_0=M_0=0 G0=M0=0, 那么在迭代初期, G t G_t Gt和 M t M_t Mt的值会比真实的均值和方差要小。如果 β 1 \beta_1 β1和 β 2 \beta_2 β2都接近1时,偏差会很大。
最后我们的梯度更新为
Δ θ t = − η G ^ t + ϵ M ^ t \Delta \theta_{t}=-\frac{\eta}{\sqrt{\hat{G}_{t}+\epsilon}} \hat{M}_{t}\\ Δθt=−G^t+ϵηM^t
其中学习率 η \eta η通常设为0.001, 并且也可以通过 η t = η 0 t \eta_t=\dfrac{\eta_0}{\sqrt{t}} ηt=tη0进行衰减操作。
Adam 在深度学习领域内是十分流行的算法,因为它能很快地实现优良的结果。经验性结果证明 Adam 算法 在实践中性能优异,相对于其他种类的随机优化算法具有很大的优势。主要包含以下几个显著的优点:
对于一个神经网络,在第 L L L层的输入输出分别是 h L h_L hL和 Z L Z_L ZL, 为了提高优化效率,我们可以对净输入 h L h_L hL做归一化,使得分布一致。【为了提高归一化效率,一般使用标准化将净输入的每一维都归一到标准正态分布】
比如在上图的示例中,假设上一层的输入维度是10, 当前L层的维度是100,当前喂入网络的batch size是30。那么对于L层,在输入到非线性激活函数之前,我们有一个 30 × 100 30\times 100 30×100的矩阵。我们添加batch normalization层之后,对于每一个维度,每一列,我们都提取均值和方差,对所有样本沿着特征维度方向做归一化。比如第0列特征,我们用上面的式子计算新的向量 h ~ L 0 \tilde{h}_{L0} h~L0, 然后再把新的100个向量组成新的矩阵,然后再输入到激活函数。
其中, a a a和 b b b是训练出来。
批量归一化的效果就是让数据的取值分布尽可能的移动到激活函数的有效部分,尤其是sigmoid函数的线性变化区域
有时,如果模型太复杂难以优化,或是如果任务非常困难,直接训练模型来解决特定任务的挑战可能 太大。有时训练一个较简单的模型来求解问题,然后使模型更复杂会更有效。训练模型来求解一个简化的问题,然后转移到最后的问题,有时也会更有效些。这些在直接训练目标模型求解目标问题之前, 训练简单模型求解简化问题的方法统称为预训练(pretraining)
改进优化的最好方法并不总是改进优化算法。相反,深度模型中优化的许多改进来自于设计易于优化的模型。
现代神经网络的设计选择体现
特别地,创新的模型,如 LSTM,整流线性单元和 maxout 单元都比先前的模型(如基于sigmoid 单 元的深度网络)使用更多的线性函数。这些模型都具有简化优化的性质。如果线性变换的 Jacobian 具有相对合理的奇异值,那么梯度能够流经很多层。此外,线性函数在一个方向上一致增加,所以即使模型的输出远离正确值,也可以简单清晰地计算梯度,使其输出方向朝降低损失函数的方向移动。换言之,现代神经网络的设计方案旨在使其局部梯度信息合理地对应着移向一个遥远的解。
其他的模型设计策略有助于使优化更简单。
以这些方式,我们可以在一个阶段联合训练所有层,而不改变架构,使得中间层 (特别是低层)能够通过更短的路径得到一些如何更新的有用信息。这些信息为底层提供了误差信号。