1. bp神经网络用啥算法
自己找个例子算一下,推导一下,这个回答起来比较复杂
神经网络对模型的表达能力依赖于优化算法,优化是一个不断计算梯度并调整可学习参数的过程,Fluid中的优化算法可参考优化器。
在网络的训练过程中,梯度计算分为两个步骤:前向计算与反向传播。
前向计算会根据您搭建的网络结构,将输入单元的状态传递到输出单元。
反向传播借助链式法则,计算两个或两个以上复合函数的导数,将输出单元的梯度反向传播回输入单元,根据计算出的梯度,调整网络的可学习参数。
BP算法
隐层的引入使网络具有很大的潜力。但正像Minskey和Papert当时所指出的.虽然对所有那些能用简单(无隐层)网结解决的问题有非常简单的学习规则,即简单感知器的收敛程序(主要归功于Widrow和HMf于1960年提出的Delta规刚),
BP算法
但当时并没有找到同样有技的含隐层的同培的学习规则。对此问题的研究有三个基本的结果。一种是使用简单无监督学习规则的竞争学习方法.但它缺乏外部信息.难以确定适台映射的隐层结构。第二条途径是假设一十内部(隐层)的表示方法,这在一些先约条件下是台理的。另一种方法是利用统计手段设计一个学习过程使之能有技地实现适当的内部表示法,Hinton等人(1984年)提出的Bolzmann机是这种方法的典型例子.它要求网络在两个不同的状态下达到平衡,并且只局限于对称网络。Barto和他的同事(1985年)提出了另一条利用统计手段的学习方法。但迄今为止最有教和最实用的方瑶是Rumelhart、Hinton和Williams(1986年)提出的一般Delta法则,即反向传播(BP)算法。Parter(1985年)也独立地得出过相似的算法,他称之为学习逻辑。此外, Lecun(1985年)也研究出大致相似的学习法则。
2. 常用优化器算法归纳介绍
优化器是神经网络训练过程中,进行梯度下降以寻找最优解的优化方法。不同方法通过不同方式(如附加动量项,学习率自适应变化等)侧重于解决不同的问题,但最终大都是为了加快训练速度。
这里就介绍几种常见的优化器,包括其原理、数学公式、核心思想及其性能;
核心思想: 即针对每次输入的训练数据,计算输出预测与真值的Loss的梯度;
从表达式来看,网络中参数的更新,是不断向着最小化Loss函数的方向移动的:
优点:
简单易懂,即对于相应的最优解(这里认为是Loss的最小函数),每次变量更新都是沿着局部梯度下降最快的方向,从而最小化损失函数。
缺点:
不同于标准梯度下降法(Gradient Descent)一次计算所有数据样本的Loss并计算相应的梯度,批量梯度下降法(BGD, Batch Gradient Descent)每次只取一个小批次的数据及其真实标签进行训练,称这个批次为mini-batch;
优点:
缺点:
随机梯度下降法的 batch size 选择不当可能导致模型难以收敛;由于这种方法是在一次更新中,就对整个数据集计算梯度,所以计算起来非常慢,遇到很大量的数据集也会非常棘手,而且不能投入新数据实时更新模型。
我们会事先定义一个迭代次数 epoch,首先计算梯度向量 params_grad,然后沿着梯度的方向更新参数 params,learning rate 决定了我们每一步迈多大。
Batch gradient descent 对于凸函数可以收敛到全局极小值,对于非凸函数可以收敛到局部极小值。
和 BGD 的一次用所有数据计算梯度相比,SGD 每次更新时对每个样本进行梯度更新,对于很大的数据集来说,可能会有相似的样本,这样 BGD 在计算梯度时会出现冗余,而 SGD 一次只进行一次更新,就没有冗余,而且比较快,并且可以新增样本。
即训练时,每次只从一批训练样本中随机选取一个样本进行梯度下降;对随机梯度下降来说,只需要一次关注一个训练样本,一点点把参数朝着全局最小值的方向进行修改了。
整体数据集是个循环,其中对每个样本进行一次参数更新
缺点:
梯度下降速度比较慢,而且每次梯度更新时往往只专注与局部最优点,而不会恰好指向全局最优点;
单样本梯度更新时会引入许多噪声(跟训练目标无关的特征也会被归为该样本分类的特征);
SGD 因为更新比较频繁,会造成 cost function 有严重的震荡。
BGD 可以收敛到局部极小值,当然 SGD 的震荡可能会跳到更好的局部极小值处。
当我们稍微减小 learning rate,SGD 和 BGD 的收敛性是一样的。
优点:
当处理大量数据时,比如SSD或者faster-rcnn等目标检测模型,每个样本都有大量候选框参与训练,这时使用随机梯度下降法能够加快梯度的计算。
随机梯度下降是通过每个样本来迭代更新一次,如果样本量很大的情况,那么可能只用其中部分的样本,就已经将 迭代到最优解了,对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。缺点是SGD的噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。所以虽然训练速度快,但是准确度下降,并不是全局最优。虽然包含一定的随机性,但是从期望上来看,它是等于正确的导数的。
梯度更新规则:
MBGD 每一次利用一小批样本,即 n 个样本进行计算,这样它可以降低参数更新时的方差,收敛更稳定,另一方面可以充分地利用深度学习库中高度优化的矩阵操作来进行更有效的梯度计算。
和 SGD 的区别是每一次循环不是作用于每个样本,而是具有 n 个样本的批次。
超参数设定值: n 一般取值在 50~256
缺点:(两大缺点)
鞍点就是:一个光滑函数的鞍点邻域的曲线,曲面,或超曲面,都位于这点的切线的不同边。例如这个二维图形,像个马鞍:在x-轴方向往上曲,在y-轴方向往下曲,鞍点就是(0,0)。
为了应对上面的两点挑战就有了下面这些算法
核心思想:
不使用动量优化时,每次训练的梯度下降方向,都是按照当前批次训练数据计算的,可能并不能代表整个数据集,并且会有许多噪声,下降曲线波动较大:
添加动量项之后,能够有效减小波动,从而加快训练速度:
当我们将一个小球从山上滚下来时,没有阻力的话,它的动量会越来越大,但是如果遇到了阻力,速度就会变小。
加入的这一项,可以使得梯度方向不变的维度上速度变快,梯度方向有所改变的维度上的更新速度变慢,这样就可以加快收敛并减小震荡。
优点:
通过动量更新,参数向量会在有持续梯度的方向上增加速度;
使梯度下降时的折返情况减轻,从而加快训练速度;
缺点:
如果数据集分类复杂,会导致 和 时刻梯度 向量方向相差较大;在进行向量求和时,得到的 会非常小,反而使训练速度大大下降甚至模型难以收敛。
这种情况相当于小球从山上滚下来时是在盲目地沿着坡滚,如果它能具备一些先知,例如快要上坡时,就知道需要减速了的话,适应性会更好。
目前为止,我们可以做到,在更新梯度时顺应 loss function 的梯度来调整速度,并且对 SGD 进行加速。
核心思想:
自适应学习率优化算法针对于机器学习模型的学习率,采用不同的策略来调整训练过程中的学习率,从而大大提高训练速度。
这个算法就可以对低频的参数做较大的更新,对高频的做较小的更新,也因此,对于稀疏的数据它的表现很好,很好地提高了 SGD 的鲁棒性,例如识别 Youtube 视频里面的猫,训练 GloVe word embeddings,因为它们都是需要在低频的特征上有更大的更新。
Adagrad 的优点是减少了学习率的手动调节
式中, 表示第 个分类, 表示第 迭代同时也表示分类 累计出现的次数。 表示初始的学习率取值(一般为0.01)
AdaGrad的核心思想: 缩放每个参数反比于其所有梯度历史平均值总和的平方根。具有代价函数最大梯度的参数相应地有较大的学习率,而具有小梯度的参数又较小的学习率。
缺点:
它的缺点是分母会不断积累,这样学习率就会收缩并最终会变得非常小。
这个算法是对 Adagrad 的改进,
和 Adagrad 相比,就是分母的 换成了过去的梯度平方的衰减平均值,指数衰减平均值
这个分母相当于梯度的均方根 root mean squared (RMS),在数据统计分析中,将所有值平方求和,求其均值,再开平方,就得到均方根值 ,所以可以用 RMS 简写:
其中 的计算公式如下, 时刻的依赖于前一时刻的平均和当前的梯度:
梯度更新规则:
此外,还将学习率 换成了 RMS[Δθ],这样的话,我们甚至都不需要提前设定学习率了:
超参数设定值: 一般设定为 0.9
RMSprop 是 Geoff Hinton 提出的一种自适应学习率方法。
RMSprop 和 Adadelta 都是为了解决 Adagrad 学习率急剧下降问题的,
梯度更新规则:
RMSprop 与 Adadelta 的第一种形式相同:(使用的是指数加权平均,旨在消除梯度下降中的摆动,与Momentum的效果一样,某一维度的导数比较大,则指数加权平均就大,某一维度的导数比较小,则其指数加权平均就小,这样就保证了各维度导数都在一个量级,进而减少了摆动。允许使用一个更大的学习率η)
超参数设定值:
Hinton 建议设定 为 0.9, 学习率 为 0.001。
这个算法是另一种计算每个参数的自适应学习率的方法。相当于 RMSprop + Momentum
除了像 Adadelta 和 RMSprop 一样存储了过去梯度的平方 vt 的指数衰减平均值 ,也像 momentum 一样保持了过去梯度 mt 的指数衰减平均值:
如果 和 被初始化为 0 向量,那它们就会向 0 偏置,所以做了偏差校正,通过计算偏差校正后的 和 来抵消这些偏差:
梯度更新规则:
超参数设定值:
建议
示例一
示例二
示例三
上面情况都可以看出,Adagrad, Adadelta, RMSprop 几乎很快就找到了正确的方向并前进,收敛速度也相当快,而其它方法要么很慢,要么走了很多弯路才找到。
由图可知自适应学习率方法即 Adagrad, Adadelta, RMSprop, Adam 在这种情景下会更合适而且收敛性更好。
如果数据是稀疏的,就用自适用方法,即 Adagrad, Adadelta, RMSprop, Adam。
RMSprop, Adadelta, Adam 在很多情况下的效果是相似的。
Adam 就是在 RMSprop 的基础上加了 bias-correction 和 momentum,
随着梯度变的稀疏,Adam 比 RMSprop 效果会好。
整体来讲,Adam 是最好的选择。
很多论文里都会用 SGD,没有 momentum 等。SGD 虽然能达到极小值,但是比其它算法用的时间长,而且可能会被困在鞍点。
如果需要更快的收敛,或者是训练更深更复杂的神经网络,需要用一种自适应的算法。
各种优化器Optimizer原理:从SGD到AdamOptimizer
深度学习——优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)
3. 非线性建模-神经网络
纳弯派 这学期选修了Python与算法基础,利用Python语言编写力图实现高效算法。前期接触了线性建模中的单变量及多元变量回归模型、多项式回归和灰度模型等。目前正在解决非线性建模问题,引入了神经网络的概念,这里作为自我梳理。
首先该网络有三层:输入层、隐含层和输出层。输入层进行变量与优化权重的加权计算,每个节点输出z=Σxiwij,此时我们把多个变量闹败(x),变为了单个变量(z)。隐含层完成“非线性的实现”,节点值ho=1/((1+e^(-z))),此处使用了生长函数。当我们调节wij(优化权重),使模型收敛,就能解决该非线性问题。
接着我们建立MLPClassifier神经网络模型。以下辨明多个参数。
hidden_layer_sizes :用元组,一个数字代表一个隐含层的节点。如hidden_layer_sizes=(50,50) 两个隐含层,每层50个节点hidden_layer_sizes=(60,) 一个隐含层,60个节点,其中逗号不能省略
activation :激活函数, 对Σxiwij的函数转换。
{'identity','logistic', 'tanh'洞贺, 'relu'}, 默认relu
•identity:f(x)= x
•logistic:其实就是sigmod,f(x) = 1 / (1 + exp(-x)).
•tanh:f(x) = tanh(x).
•relu:f(x) = max(0, x)
solver : {'bfgs', 'sgd', 'adam'}, 默认adam,用来优化权重
lbfgs:quasi-Newton(拟牛顿法)方法的优化器
sgd:随机梯度下降
adam: Kingma, Diederik, and Jimmy Ba提出的基于随机梯度的优化器
注意:默认solver 'adam',在相对较大的数据集上效果比较好(几千个样本或者更多),对小数据集来说,lbfgs收敛更快效果也更好。
learning_rate :学习率,用于权重更新,只有当solver为’sgd’时使用,{'constant','invscaling', 'adaptive'},默认constant
•constant: 由learning_rate_init给定的恒定学习率
•invscaling:随着时间t使用power_t的逆标度指数不断降低学习率learning_rate_ ,effective_learning_rate = learning_rate_init / pow(t, power_t)
•adaptive:只要训练损耗在下降,就保持学习率为learning_rate_init不变,当连续两次不能降低训练损耗或验证分数停止升高至少tol时,将当前学习率除以5。
4. 优化算法
SGD算法中的一个关键参数是学习率。之前,我们介绍的SGD使用固定的学习率。在实践中,有必要随着时间的推移逐渐降低学习率,因此我们将第 k 步迭代的学习率记作 ϵ k 。
这是因为SGD中梯度估计引入的噪声源(m 个训练样本的随机采样)并不会在极小点处消失。相比之下,当我们使用批量梯度下降到达极小点时,整个代价函数的真实梯度会变得很小,之后为 0,因此批量梯度下降可以使用固定的学习率。保证SGD收敛的一个充分条件是
若 ϵ 0 太大,学习曲线将会剧烈振荡,代价函数值通常会明显增加。温和的振荡是良好的,容易在训练随机代价函数(例如使用Dropout的代价函数)时出现。如果学习率太小,那么学习过程会很缓慢。如果初始学习率太低,那么学习可能会卡在一个相当高的代价值。通常,就总训练时间和最终代价值而言,最优初始学习率会高于大约迭代 100 次左右后达到最佳效果的学习率。因此,通常最好是检测最早的几轮迭代,选择一个比在效果上表现最佳的学习率更大的学习率,但又不能太大导致严重的震荡。
虽然随机梯度下降仍然是非常受欢迎的优化方法,但其学习过程有时会很慢。动量方法 (Polyak, 1964) 旨在加速学习,特别是处理高曲率、小但一致的梯度,或是带噪声的梯度。动量算法积累了之前梯度指数级衰减的移动平均,并且继续沿该方向移动。动量的效果如图8.5所示
受 Nesterov 加速梯度算法 (Nesterov, 1983, 2004) 启发,提出了动量算法的一个变种。这种情况的更新规则如下:
其中参数 α 和 ϵ 发挥了和标准动量方法中类似的作用。Nesterov 动量和标准动量之间的区别体现在梯度计算上。Nesterov 动量中,梯度计算在施加当前速度之后。因此,Nesterov 动量可以解释为往标准动量方法中添加了一个校正因子。完整的Nesterov动量算法如算法3.2所示
初始点能够决定算法是否收敛,有些初始点十分不稳定,使得该算法会遭遇数值困难,并完全失败。当学习收敛时,初始点可以决定学习收敛得多快,以及是否收敛到一个代价高或低的点。此外,差不多代价的点可以具有区别极大的泛化误差,初始点也可以影响泛化。
也许完全确知的唯一特性是初始参数需要在不同单元间 ‘‘破坏对称性’’。如果具有相同激活函数的两个隐藏单元连接到相同的输入,那么这些单元必须具有不同的初始参数。如果它们具有相同的初始参数,然后应用到确定性损失和模型的确定性学习算法将一直以相同的方式更新这两个单元。即使模型或训练算法能够使用随机性为不同的单元计算不同的更新(例如使用Dropout的训练),通常来说,最好还是初始化每个单元使其和其他单元计算不同的函数。这或许有助于确保没有输入模式
丢失在前向传播的零空间中,没有梯度模式丢失在反向传播的零空间中。每个单元计算不同函数的目标促使了参数的随机初始化。我们可以明确地搜索一大组彼此互不相同的基函数,但这经常会导致明显的计算代价。例如,如果我们有和输出一样多的输入,我们可以使用 Gram-Schmidt 正交化于初始的权重矩阵,保证每个单元计算彼此非常不同的函数。在高维空间上使用高熵分布来随机初始化,计算代价小并且不太可能分配单元计算彼此相同的函数。
通常情况下,我们可以为每个单元的偏置设置启发式挑选的常数,仅随机初始化权重。额外的参数(例如用于编码预测条件方差的参数)通常和偏置一样设置为启发式选择的常数。
我们几乎总是初始化模型的权重为高斯或均匀分布中随机抽取的值。高斯或均匀分布的选择似乎不会有很大的差别,但也没有被详尽地研究。然而,初始分布的大小确实对优化过程的结果和网络泛化能力都有很大的影响。
更大的初始权重具有更强的破坏对称性的作用,有助于避免冗余的单元。它们也有助于避免在每层线性成分的前向或反向传播中丢失信号——矩阵中更大的值在矩阵乘法中有更大的输出。如果初始权重太大,那么会在前向传播或反向传播中产生爆炸的值。在循环网络中,很大的权重也可能导致混沌(chaos)(对于输入中很小的扰动非常敏感,导致确定性前向传播过程表现随机)。在一定程度上,梯度爆炸问题可以通过梯度截断来缓解(执行梯度下降步骤之前设置梯度的阈值)。较大的权
重也会产生使得激活函数饱和的值,导致饱和单元的梯度完全丢失。这些竞争因素决定了权重的理想初始大小。
也有助于避免在每层线性成分的前向或反向传播中丢失信号——矩阵中更大的值在矩阵乘法中有更大的输出。如果初始权重太大,那么会在前向传播或反向传播中产生爆炸的值。在循环网络中,很大的权重也可能导致混沌(chaos)(对于输入中很小的扰动非常敏感,导致确定性前向传播过程表现随机)。在一定程度上,梯度爆炸问题可以通过梯度截断来缓解(执行梯度下降步骤之前设置梯度的阈值)。较大的权重也会产生使得激活函数饱和的值,导致饱和单元的梯度完全丢失。这些竞争因素决定了权重的理想初始大小。
有些启发式方法可用于选择权重的初始大小。一种初始化 m 个输入和 n 输出的全连接层的权重的启发式方法是从分布 U(−1/√ m ,
1/√ m ) 中采样权重,而 Glorot and Bengio 建议使用标准初始化
后一种启发式方法初始化所有的层,折衷于使其具有相同激活方差和使其具有相同梯度方差之间。这假设网络是不含非线性的链式矩阵乘法,据此推导得出。现实的神经网络显然会违反这个假设,但很多设计于线性模型的策略在其非线性对应中的效果也不错。
数值范围准则的一个缺点是,设置所有的初始权重具有相同的标准差,例如1/√ m ,会使得层很大时每个单一权重会变得极其小。Martens (2010) 提出了一种被称为稀疏初始化(sparse initialization)的替代方案,每个单元初始化为恰好有 k 个非零权重。这个想法保持该单元输入的总数量独立于输入数目 m,而不使单一权重元素的大小随 m 缩小。稀疏初始化有助于实现单元之间在初始化时更具多样性。但是,获得较大取值的权重也同时被加了很强的先验。因为梯度下降需要很长时间缩小 ‘‘不正确’’ 的大值,这个初始化方案可能会导致某些单元出问题,例如maxout单元有几个过滤器,互相之间必须仔细调整。
Delta-bar-delta 算法 (Jacobs, 1988) 是一个早期的在训练时适应模型参数各自学习率的启发式方法。该方法基于一个很简单的想法,如果损失对于某个给定模型参数的偏导保持相同的符号,那么学习率应该增加。如果对于该参数的偏导变化了符号,那么学习率应减小。当然,这种方法只能应用于全批量优化中。
AdaGrad 算法,如算法8.4所示,独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平方值总和的平方根 (Duchi et al., 2011)。具有损失最大偏导的参数相应地有一个快速下降的学习率,而具有小偏导的参数在学习率上有相对较小的下降。净效果是在参数空间中更为平缓的倾斜方向会取得更大的进步。
在凸优化背景中,AdaGrad 算法具有一些令人满意的理论性质。然而,经验上已经发现,对于训练深度神经网络模型而言,从训练开始时积累梯度平方会导致有效学习率过早和过量的减小。AdaGrad在某些深度学习模型上效果不错,但不是全部。
RMSProp 算法 (Hinton, 2012) 修改 AdaGrad 以在非凸设定下效果更好,改变梯度积累为指数加权的移动平均。AdaGrad旨在应用于凸问题时快速收敛。当应用于非凸函数训练神经网络时,学习轨迹可能穿过了很多不同的结构,最终到达一个局部是凸碗的区域。AdaGrad 根据平方梯度的整个历史收缩学习率,可能使得学习率在达到这样的凸结构前就变得太小了。RMSProp 使用指数衰减平均以丢弃遥远过去的历史,使其能够在找到凸碗状结构后快速收敛,它就像一个初始化于该碗状结构的 AdaGrad 算法实例。
RMSProp 的标准形式如算法8.5所示,结合 Nesterov 动量的形式如算法8.6所示。相比于 AdaGrad,使用移动平均引入了一个新的超参数ρ,用来控制移动平均的长度范围。经验上,RMSProp 已被证明是一种有效且实用的深度神经网络优化算法。目前它是深度学习从业者经常采用的优化方法之一。
Adam (Kingma and Ba, 2014) 是另一种学习率自适应的优化算法,最好被看作结合 RMSProp 和具有一些重要区别的动量的变种。首先,在 Adam 中,动量直接并入了梯度一阶矩(指数加权)的估计。将动量加入 RMSProp 最直观的方法是将动量应用于缩放后的梯度。结合缩放的动量使用没有明确的理论动机。其次,Adam 包括偏置修正,修正从原点初始化的一阶矩(动量项)和(非中心的)二阶矩的估计(算法8.7)。RMSProp 也采用了(非中心的)二阶矩估计,然而缺失了修正因子。因此,不像 Adam,RMSProp 二阶矩估计可能在训练初期有很高的偏置。Adam 通常被认为对超参数的选择相当鲁棒,尽管学习率有时需要从建议的默认修改。
目前,最流行并且使用很高的优化算法包括 SGD、具动量的 SGD、RMSProp、具动量的 RMSProp、AdaDelta 和 Adam。