2019-09-05 14:55:05 sunflower_sara 阅读数 190
  • C++开发环境搭建-第1部分第2课

    《跟朱老师从C高级到征服C++》属于系列课程《朱有鹏老师热门编程语言全解》的第一部分,主要针对C++语言完全学习。本课程可以看做是嵌入式linux核心课程中《C语言高级专题》课程的延续,在学好了C语言前提下继续深度学习C++语言。整个课程共分为5部分。涵盖了C++基础语法和使用,面向对象,STL与泛型,Boost库和设计模式,C++编程优化技巧等非常广泛的内容,是市面上非常缺少的深度完整学习C++,培养编程技能和修养的一套系列学习课程。整个课程预计2020年底前录制完成,总时长预计150-200小时。 朱老师C++第1部分-从C到C++ 朱老师C++第2部分-C++和面向对象 朱老师C++第3部分-STL等高阶话题 朱老师C++第4部分-Boost库和设计模式 朱老师C++第5部分-C++编程优化 课程特色 *完全零基础,降低学习门槛。 *深入浅出,通俗易懂。不怕学不会,就怕你不学习。 *思路清晰、语言风趣,对着视频看也不会想睡觉······ *视频 + 文档 + 练习题 + 答疑,全方位保证学习质量。 *基础知识 + 思路引导的教学方式,授之以鱼更授之以渔。 *系列课程。本教程只是入门篇,后续还有更多更精彩视频更新中。

    10 人正在学习 去看看 朱有鹏

深度学习优化学习方法总结 (一阶为主)https://blog.csdn.net/sunflower_sara/article/details/81321886

常用的优化算法:梯度下降法,牛顿法,拟牛顿法,共轭梯度法 (二阶为主) https://blog.csdn.net/sunflower_sara/article/details/81215135

 

一阶方法:

随机梯度下降(Stochastic Gradient Descent,SGD)

动量(SGD with Momentum,SGDM)

牛顿动量法(Nesterov Acceleration Gradient,NAG)

AdaGrad(自适应梯度)

RMSProp(均方差传播)

Adam

Nadam

 

二阶方法:

牛顿法

拟牛顿法

共轭梯度法 CG

BFGS

L-BFGS

2017-04-05 18:05:36 Gavin__Zhou 阅读数 1675
  • C++开发环境搭建-第1部分第2课

    《跟朱老师从C高级到征服C++》属于系列课程《朱有鹏老师热门编程语言全解》的第一部分,主要针对C++语言完全学习。本课程可以看做是嵌入式linux核心课程中《C语言高级专题》课程的延续,在学好了C语言前提下继续深度学习C++语言。整个课程共分为5部分。涵盖了C++基础语法和使用,面向对象,STL与泛型,Boost库和设计模式,C++编程优化技巧等非常广泛的内容,是市面上非常缺少的深度完整学习C++,培养编程技能和修养的一套系列学习课程。整个课程预计2020年底前录制完成,总时长预计150-200小时。 朱老师C++第1部分-从C到C++ 朱老师C++第2部分-C++和面向对象 朱老师C++第3部分-STL等高阶话题 朱老师C++第4部分-Boost库和设计模式 朱老师C++第5部分-C++编程优化 课程特色 *完全零基础,降低学习门槛。 *深入浅出,通俗易懂。不怕学不会,就怕你不学习。 *思路清晰、语言风趣,对着视频看也不会想睡觉······ *视频 + 文档 + 练习题 + 答疑,全方位保证学习质量。 *基础知识 + 思路引导的教学方式,授之以鱼更授之以渔。 *系列课程。本教程只是入门篇,后续还有更多更精彩视频更新中。

    10 人正在学习 去看看 朱有鹏

一般来说,深度学习通过仔细的设计Objective function和constraints来确保优化问题是convex的,从而避开一下通用优化算法的难题。
优化(optimization)说的有点大,因为存在一阶优化(first-order)和二阶(second-order)优化算法。我们常用的优化算法,比如Adam,SGD等其实都是一阶优化算法(基于gradient),这篇写的也是一阶优化算法.

现今的一阶优化算法都是基于batch或者是minibatch的,所以从minibatch开始说起吧


batch and minibatch

假设做最大似然估计,需要优化下面的式子:

等价于需要在经验分布上最大化期望:

优化上式自然想到梯度:

求这个期望需要计算每个example的梯度,对于大数据集(比如100W)来说计算成本过高,一个常用的解决方法就是:random sampling

In practice, we can compute these expectations by randomly sampling a small number of examples from the dataset, then taking the average over only those examples.

这样做就是使用近似的梯度估计来代替精确的梯度,毫无疑问计算代价很小,计算的代价是不随training set的增加而增加的.

batch gradient descent

Optimization algorithms that use the entire training set are called batch or deterministic gradient methods, because they process all of the training examples simultaneously in a large batch.

使用所有的训练数据来计算梯度

SGD(stochastic gradient descent)

Optimization algorithms that use only a single example at a time are sometimes called stochastic or sometimes online methods.

minibatch SGD

SGD和batch GD是两个极端,一个每次只使用一个训练数据来计算梯度,一个是使用所有的训练数据;batch GD计算成本太高,SGD太具有随机性,所以需要综合下。

using more than one but less than all of the training examples. These were traditionally called minibatch or minibatch stochastic methods and it is now common to simply call them stochastic methods.

重要的一点是:选择minibatch的数据时一定要随机

It is also crucial that the minibatches be selected randomly. Computing an unbiased estimate of the expected gradient from a set of samples requires that those samples be independent. We also wish for two subsequent gradient estimates to be independent from each other, so two subsequent minibatches of examples should also be independent from each other.

这里只是为了区分batch和minibatch的概念,现在所说的stochastic其实都是minibatch的.

SGD

SGD和它的变种是最常用的一阶优化算法,具体描述:

SGD

momentum

SGD的问题就是它可能会很慢,所以使用momentum来加速学习过程.

The method of momentum (Polyak, 1964) is designed to accelerate learning, especially in the face of high curvature, small but consistent gradients, or noisy gradients.

momentum的原理:

The momentum algorithm accumulates an exponentially decaying moving average of past gradients and continues to move in their direction.

引入一个参数α ∈ [0 ,1),作用是:

determines how quickly the contributions of previous gradients exponentially decay.

更新公式:

其中L是损失函数,v代表速度
使用了momentum之前,step_size = ||g||*lr(梯度乘以学习率),使用了momentum之后的step_size,取决于两个因素:

  • how large a sequence of gradients are.
  • how aligned a sequence of gradients are.

这个对齐(align)怎么理解,可以放到物理上想,当所有的物体的运动方向是一致的时候,这个整体的动量是最大的.

step_size_with_momentum=lr/(1-α)*||g||,通常典型的α值是0.9

CS231n上有比较形象的解释: 地址在这
中文翻译过来就是:

损失值可能理解为山峰的高度, 用随机数字初始化参数等同于在某个位置给质点设定初始速度为0. 这样最优化过程可以看做是模拟参数向量(即质点)在地形上滚动的过程, 质点所受的力就是损失函数的负梯度. 在普通的更新(比如SGD)中,梯度直接影响位置,momentum上是梯度影响速度,速度影响位置.

SGD with momentum

Nesterov momentum

跟momentum非常像,只是计算梯度的位置(x+a*v)不一样,所以可以把nesterov momentum看成是对标准的momentum的一个correction factor.

对于上式更新来说:theta <- theta + v == theta + alpha * v -step_size
此时的theta+alpha*v看做是未来的近似位置,所以算梯度时我们直接在未来的位置(前向位置)处计算就可以了. 所以Nesterov的核心就是在前向位置而不是原始的位置计算梯度.

更新公式:

直观上的理解就是:

Nesterov

Nesterov直接在前向位置(绿色箭头指向的位置)处更新梯度.

SGD with nesterov momentum

AdaGrad

是个学习率自适应的优化算法

individually adapts the learning rates of all model parameters by scaling them inversely proportional to the square root of the sum of all of their historical squared values.

对loss有很大贡献的parameter的学习率会下降的比较快:

The parameters with the largest partial derivative of the loss have a correspondingly rapid decrease in their learning rate, while parameters with small partial derivatives have a relatively small decrease in their learning rate.

经验表明:

the accumulation of squared gradients from the beginning of training can result in a premature and excessive decrease in the effective learning rate.

所以其实AdaGrad使用的也不是很多

RMSprop

RMSProp是从AdaGrad上修改来的,也是个自适应的算法,就是把gradient accumulation换成exponentially weighted moving average.

两者之间的区别:

  1. AdaGrad shrinks the learning rate according to the entire history of the squared gradient and may have made the learning rate too small before arriving at such a convex structure.
  2. RMSProp uses an exponentially decaying average to discard history from the extreme past so that it can converge rapidly after finding a convex bowl.

RMSProp with nesterov momentum

可以将nesterov momentum和RMSProp结合:

Adam

同样的也是个自适应学习率的优化算法,基本和SGD各占半边天.
可以把Adam看成是RMsProp+momentum的变体(存在几个主要的区别)
区别在于:

  1. First, in Adam, momentum is incorporated directly as an estimate of the first order moment (with exponential weighting) of the gradient.
  2. Second, Adam includes bias corrections to the estimates of both the first-order moments (the momentum term) and the (uncentered) second-order moments to account for their initialization at the origin.

算法如下所示:

总结

  1. 优化算法有一阶和二阶算法
  2. 常见优化算法的几乎都是一阶算法比如SGD ,Adam, AdaGrad, RMSProp等
  3. 二阶算法由于计算的代价等问题不常用,比如牛顿法, BFGS, L-BFGS等
  4. 最常用的一阶优化算法是SGD和Adam
2018-02-03 19:46:47 JNingWei 阅读数 770
  • C++开发环境搭建-第1部分第2课

    《跟朱老师从C高级到征服C++》属于系列课程《朱有鹏老师热门编程语言全解》的第一部分,主要针对C++语言完全学习。本课程可以看做是嵌入式linux核心课程中《C语言高级专题》课程的延续,在学好了C语言前提下继续深度学习C++语言。整个课程共分为5部分。涵盖了C++基础语法和使用,面向对象,STL与泛型,Boost库和设计模式,C++编程优化技巧等非常广泛的内容,是市面上非常缺少的深度完整学习C++,培养编程技能和修养的一套系列学习课程。整个课程预计2020年底前录制完成,总时长预计150-200小时。 朱老师C++第1部分-从C到C++ 朱老师C++第2部分-C++和面向对象 朱老师C++第3部分-STL等高阶话题 朱老师C++第4部分-Boost库和设计模式 朱老师C++第5部分-C++编程优化 课程特色 *完全零基础,降低学习门槛。 *深入浅出,通俗易懂。不怕学不会,就怕你不学习。 *思路清晰、语言风趣,对着视频看也不会想睡觉······ *视频 + 文档 + 练习题 + 答疑,全方位保证学习质量。 *基础知识 + 思路引导的教学方式,授之以鱼更授之以渔。 *系列课程。本教程只是入门篇,后续还有更多更精彩视频更新中。

    10 人正在学习 去看看 朱有鹏

优化算法 类型

优化算法 类型 包括 一阶优化法 和 二阶优化法:

一阶优化法 二阶优化法
具体算法 随机梯度下降法、基于动量的随机梯度下降法、Nesterov型动量随机下降法、Adagrad法、Adadelta法、RMSProp法、Adam法 牛顿法
计算难度 较易
运用程度 主流 少有人用

一阶优化法 对比

随机梯度下降法 基于动量的随机梯度下降法 Nesterov型动量随机下降法 Adagrad法 Adadelta法 RMSProp法 Adam法
运用程度 最广
训练速度
模型结果 可靠 可靠

随机梯度下降法、基于动量的随机梯度下降法 和 Nesterov型动量随机下降法 彼此性能相近
Adagrad法、Adadelta法、RMSProp法 和 Adam法 彼此性能相近

一阶优化法

ω :待学习参数;
η :学习率;
g :一阶梯度值;
t :第t轮训练。

随机梯度下降法

随机梯度下降算法,Stochastic Gradient Descent,简称 SGD

ωtωt1ηg

基于动量的随机梯度下降法

由于SGD更新时可能出现 振荡 ,遂通过 累积前几轮的动量 (momentum) 信息辅助参数更新

vtμvt1ηg

ωtωt1+vt

μ :动量因子,控制动量信息对整体梯度更新的影响程度。设置方法分为 静态 (始终为 0.9) 和 动态 (初始为 0.5,逐渐增长为 0.9 或 0.99) 。

Nesterov型动量随机下降法

较罕见,遂略过。

Adagrad法

根据训练轮数的不同,对学习率进行动态调整:

ηtηglobalt=1tgt2+ϵgt

ηglobal :全局学习率 (必须提前指定) ;
ϵ :防止分母为0。

初始时,ηt 接近于 ηglobal ,随着 t=1tgt2 的不断增大,ηt 渐渐趋近于 0 。

Adadelta法

Adadelta法 在 Adagrad法 的 基础上,通过引入衰减因子 ρ ,使得 g 也和 ηglobal 一起来对 ηt 施加影响,防止 ηglobal 垄断:

rtρrt1+(1ρ)g2

ηtst1+ϵrt+ϵ

stρst1+(1ρ)(ηtg)2

ρ :衰减因子,取值范围 [0, 1] ,值越大越促进网络更新,推荐为 0.95
ϵ :防止为 0,推荐为 106

RMSProp法

较罕见,遂略过。

Adam法

在 RMSProp法 基础上 加上了 动量项

利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。

优点:
经过偏置校正后,每一次迭代学习率都有一个确定范围,这样可以使得参数更新比较平稳。


[1] 解析卷积神经网络—深度学习实践手册

2017-10-03 15:27:00 u012151283 阅读数 7535
  • C++开发环境搭建-第1部分第2课

    《跟朱老师从C高级到征服C++》属于系列课程《朱有鹏老师热门编程语言全解》的第一部分,主要针对C++语言完全学习。本课程可以看做是嵌入式linux核心课程中《C语言高级专题》课程的延续,在学好了C语言前提下继续深度学习C++语言。整个课程共分为5部分。涵盖了C++基础语法和使用,面向对象,STL与泛型,Boost库和设计模式,C++编程优化技巧等非常广泛的内容,是市面上非常缺少的深度完整学习C++,培养编程技能和修养的一套系列学习课程。整个课程预计2020年底前录制完成,总时长预计150-200小时。 朱老师C++第1部分-从C到C++ 朱老师C++第2部分-C++和面向对象 朱老师C++第3部分-STL等高阶话题 朱老师C++第4部分-Boost库和设计模式 朱老师C++第5部分-C++编程优化 课程特色 *完全零基础,降低学习门槛。 *深入浅出,通俗易懂。不怕学不会,就怕你不学习。 *思路清晰、语言风趣,对着视频看也不会想睡觉······ *视频 + 文档 + 练习题 + 答疑,全方位保证学习质量。 *基础知识 + 思路引导的教学方式,授之以鱼更授之以渔。 *系列课程。本教程只是入门篇,后续还有更多更精彩视频更新中。

    10 人正在学习 去看看 朱有鹏

梯度下降沿着整个训练集的梯度方向下降。可以使用随机梯度下降很大程度地加速,沿着随机挑选的小批量数据的梯度下降。

批量算法和小批量算法

使用小批量的原因

  • n个样本均值的标准差是σn,其中σ是样本值真实的标准差。分母n表明使用更多的样本来估计梯度的方法的回报是低于线性的。
  • 另一个促使从小数目样本中获得梯度的统计估计的动机是训练集的冗余。大量样本可能对梯度做出了非常相似的贡献。
  • 可能是由于小批量在学习过程中加入了噪声,它们会有一些正则化效果。

其他

  • 鲁棒性
    不同的算法使用不同的方法从小批量中获取不同的信息。有些算法对采样误差比其他算法更敏感,这通常有两个原因。一个是它们使用了很难在少量样本上精确估计的信息,另一个是它们以放大采样误差的方式使用了信息。
    基于梯度g的更新方法通常相对鲁棒,并能使用较小的批量获得成功,如100。使用Hessian矩阵H,计算如H1g更新的二阶方法通常需要更大的批量,如10000。

  • 随机顺序
    小批量是随机抽取的这点也很重要。从一组样本中计算出梯度期望的无偏估计要求这些样本是独立的。在数据集中的顺序有很大影响的情况下,有必要在抽取小批量样本前打乱样本顺序。
    不以某种方式打乱样本顺序会极大地降低算法的性能。

  • 异步并行
    在计算小批量样本X上最小化J(X)的更新时,同时可以计算其他小于样本上的更新。
  • 无重复样本,遵循真实泛化误差的梯度
    很多小批量随机梯度下降方法的实现都会打乱数据顺序一次,然后多次遍历数据来更新参数。第一次遍历,每个小批量样本都用来计算真实泛化误差的无偏估计。第二次遍历,估计将会是有偏的,因为重新抽取了已经用过的样本,而不是从和原先样本相同的数据生成分布中获取新的无偏的样本。
  • 在线学习中的SGD
    在线学习中,样本永远不会重复,每次更新的样本是从分布中采样获得的无偏样本。
  • 实际使用
    在实际使用中,除非训练集特别大,通常还是多次遍历训练集,额外的遍历会由于减小训练误差而得到足够的好处,以抵消其带来的训练误差和测试误差差距的增加。

基本算法

随机梯度下降SGD

SGD及其变种是深度学习中应用最多的优化算法。按照数据生成分布抽取m个小批量(独立同分布)样本,通过计算它们的梯度均值,我们可以得到梯度无偏估计。
这里写图片描述
SGD算法中的一个关键参数是学习率。在实践中,有必要随着时间的推移逐渐降低学习率。
将第k步迭代的学习率记作ϵk。一般会线性衰减学习率直到第τ次迭代:
ϵk=(1α)ϵ0+αϵτ
其中α=kτ。在τ次迭代之后,一般使ϵ保持常数。
通常ϵτ应设为大约ϵ0的1%。
对于足够大的数据集,SGD可能会在处理整个训练集之前就收敛到最终测试集误差的某个固定容差范围内。
批量梯度下降在理论上比随机梯度下降有更好的收敛率。可以在学习过程中逐渐增大批量大大小,以此权衡批量梯度下降和随机梯度下降两者的优点。

带动量的SGD

指数加权平均数
vt=βvt1+(1β)θt
该公式利用过去11β项的θ的加权平均来计算当前的vt
偏差修正
使用vt1βt来对进行修正,当t比较大的时候,分母接近于1。
在机器学习中,一般不进行偏差修正,人们一般不使用初期的参数。
这里写图片描述
另一种形式
这里写图片描述
在实践中,动量参数一般取值为0.5,0.9和0.99。和学习率一样,α也会随着时间不断调整。一般初始值是一个较小的值,随后会慢慢变大。随着时间调整α没有收缩ϵ重要。

Nesterov动量

Nesterov动量中,梯度计算在施加当前速度之后。因此,Nesterov动量可以解释为往标准动量方法中添加了一个校正因子。
这里写图片描述

标准的动量方法(由Nesterov在1983年提出)是在当前位置计算梯度,然后在累积的更新梯度方向上做一个大的跳跃。下面给出了一种更好地动量方法(由IIya Sutskever在2012年提出),其先在先前累积的梯度方向上做一个大的跳跃,再计算新的梯度并修正错误。
下面对两种方法做了比较,图中蓝色箭头是做两次标准动量方法得到的;而图中棕色箭头是改进动量方法先做的一次大跳跃得到的,红色箭头是修正,绿色箭头是进行一次改进动量方法得到的。可以看到,改进的比标准的要快很多。

这里写图片描述

自适应学习率算法

习率算法

AdaGrad

AdaGrad独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平方值总和的平方根

这里写图片描述
在凸优化中,AdaGrad算法具有一些令人满意的理论性质。然而,经验上对于训练深度神经网络模型而言,从训练开始时积累梯度平方会导致有效学习率过早和过量减小。

AdaDelta

AdaGrad主要存在三个问题

  • 其学习率是单调递减的,训练后期学习率非常小
  • 其需要手工设置一个全局的初始学习率
  • 更新θ时,左右两边的单位不同一

我们令每一个时刻的r随之时间按照ρ指数衰减,这样就相当于仅使用离当前时刻比较近的g信息,不会使得r增加过快,分母过大而导致参数更新减缓。在AdaDelta中,累积平方梯度定义为
rρr+(1ρ)gg
在计算更新时,用梯度历史该变量平方值期望的平方根代替学习率η,则得到Adadelta更新规则:
这里写图片描述
由此看出,甚至不需要设定缺省学习率,因为更新规则已经不受它影响了

RMSProp

RMSProp算法修改AdaGrad以在非凸设定下效果更好,改变梯度累积为指数加权的移动平均
AdaGrad旨在应用于凸问题时快速收敛。AdaGrad根据平方梯度的整个历史收缩学习率,可能使得学习率在达到这样的凸结构前就变得太小了。
RMSprop使用指数衰减平均来丢弃遥远过去的历史,使其在找到凸结构后快速收敛,就像一个初始化于该碗装结构的AdaGrad算法实例。
相比于AdaGrad,使用移动平均引入了一个新的超参数ρ,用来控制移动平均的长度范围。
这里写图片描述
这里写图片描述

Adam

派生自短语”adaptive moments”
Adam被看作结合RMSProp和具有一些重要区别的动量的变种。
首先,Adam中动量直接并入梯度一阶矩(指数加权)的估计。
其次,Adam包括偏置修正,修泽和那个从原点初始化的一阶矩(动量项)和(非中心的)二阶矩的估计。RMSProp也采用了(非中心的)二阶矩估计,然而缺失了修正因子。因此,RMSProp二阶矩估计可能在训练初期有很高的偏置。

Adam通常被认为对超参数的选择相当鲁棒,尽管学习率有时需要遵从建议的默认参数0.001
这里写图片描述

二阶近似方法

牛顿法

牛顿法是基于二阶泰勒级数展开在某点θ0附近来近似J(θ)的优化方法,其忽略了高阶导数
J(θ)J(θ0)+(θθ0)TθJ(θ0)+12(θθ0)TH(θθ0),
其中HJ相对于θ的Hessian矩阵在θ0处的矩估计。通过求解这个函数的临界点,得到牛顿参数更新规则:
θ=θ0H1θJ(θ0)
因此,对于局部的二次函数(具有正定的H),用H1重新调整梯度,牛顿法会直接跳到极小值。如果目标函数是凸的但非二次的(有高阶项),该更新是迭代的。
这里写图片描述
这里写图片描述

共轭梯度

共轭梯度是一种通过迭代下降的共轭方向以有效避免Hessian矩阵求逆计算的方法。
在共轭梯段法中,我们寻求一个和先前线性搜索方向共轭的搜索方向,即它不会撤销该方向上的进展。在训练迭代t时,下一步的搜索方向dt的形式如下:
dt=θJ(θ)+βtdt1
其中,系数βt的大小控制我们应沿方向dt1加回多少到当前搜索方向。
如果dTtHdt1=0,其中H是Hessian矩阵,则两个方向dtdt1被称为共轭的。
这里写图片描述
这里写图片描述

BFGS

Broyden-Fletcher-Goldfarb-Shanno(BFGS)算法具有牛顿法的一些优点,但没有牛顿法的计算负担。
http://blog.csdn.net/u012151283/article/details/78148890#t3
拟牛顿法采用矩阵Mt近似逆,迭代地低秩更新精度以更好地近似H1
当Hessian逆近似Mt更新时,下降方向ρtρt=Mtgt。该方向上的线性搜索用于决定该方向上的步长ϵ。参数的最后更新为:
θt+1=θt+ϵρt

相比于共轭梯度,BFGS的优点是其花费较少的时间改进每个线性搜索。在另一方面,BFGS算法必须存储Hessian逆矩阵M,需要O(n2)的存储空间,使BFGS不适用于大多数具有百万级参数的现代深度学习模型。

L-BFGS

L-BFGS算法就是对拟牛顿算法的一个改进。L-BFGS算法的基本思想是:算法只保存并利用最近m次迭代的曲率信息来构造海森矩阵的近似矩阵。
LBFGS,起始假设是G(t1)是单位矩阵,而不是每一步都要存储近似矩阵。每步存储一些用于更新Gk的向量,且每步存储代价为O(n)

BFGS算法关于Gk的迭代形式如下
Gk+1=(IskyTkyTksk)Gk(IyksTkyTksk)+sksTkyTksk

ρk=1yTkskVk=IρkyksTk,则有
Gk+1=VTkGkVk+ρksksTk
对于给定的G0=I,可以迭代地计算Gk,Gk的计算只依赖于[si,yi]ki=0
L-BFGS算法通过存储最近连续的m组si,yi向量,来近似地计算Gk

批标准化

批标准化是一种自适应重参数化的方法,试图解决训练非常深的模型的困难。批标准化主要解决的是训练极深网络时梯度消失的问题。
这里写图片描述

BN起作用的原因

  1. 通过使得批量数据归一化具有0均值1方差的统计分布,避免数据处于激活函数的饱和区,具有较大的梯度,从而加速网络的训练过程。
  2. 减少了网络输入变化过大的问题,使得网络的输入稳定,减弱了与前层参数关系之间的作用,使得当前层独立于整个网络

BN具有轻微正则化的效果,可以和dropout一起使用
主要是归一化激活值前的隐藏单元来加速训练,正则化是副作用

BN具有正则化效果的原因

  1. 每个批量的数据仅根据当前批量计算均值和标准差,然后缩放
  2. 这就为该批量的激活函数带来了一些噪音,类似于dropout向每一层的激活函数带来噪音
  3. 若使用了较大的batch_size如512,则减小了噪音,减少了正则化带来的效果

训练过程中的算法

这里写图片描述
由于BN在最后重参数化过程中会学习得到一个γ,所以神经网络中的bias可以省略掉。

推断时算法

由于在推断的时,batch的大小不能确定,很有可能1次只有一个样本,不通过对当前批量的数据的归一化来加速训练。作者提出使用训练数据集上的全部数据来计算均值和方差。通常出与计算效率考虑,使用滑动平均的方法来计算
这里写图片描述

tensorflow实现

使用tf.layers.batch_normalization可以快速实现BN算法。注意使用该API时在优化器调用时要加入以下代码:

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
  with tf.control_dependencies(update_ops):
    train_op = optimizer.minimize(loss)

这里还有一个我看到知乎匿名用户的实现,感觉比较清晰

from tensorflow.python.training.moving_averages import assign_moving_average

def batch_norm(x, train, eps=1e-05, decay=0.9, affine=True, name=None):
    with tf.variable_scope(name, default_name='BatchNorm2d'):
        params_shape = tf.shape(x)[-1:]
        moving_mean = tf.get_variable('mean', params_shape,
                                      initializer=tf.zeros_initializer,
                                      trainable=False)
        moving_variance = tf.get_variable('variance', params_shape,
                                          initializer=tf.ones_initializer,
                                          trainable=False)

        def mean_var_with_update():
            mean, variance = tf.nn.moments(x, tf.shape(x)[:-1], name='moments')
            with tf.control_dependencies([assign_moving_average(moving_mean, mean, decay),
                                          assign_moving_average(moving_variance, variance, decay)]):
                return tf.identity(mean), tf.identity(variance)
        mean, variance = tf.cond(train, mean_var_with_update, lambda: (moving_mean, moving_variance))
        if affine:
            beta = tf.get_variable('beta', params_shape,
                                   initializer=tf.zeros_initializer)
            gamma = tf.get_variable('gamma', params_shape,
                                    initializer=tf.ones_initializer)
            x = tf.nn.batch_normalization(x, mean, variance, beta, gamma, eps)
        else:
            x = tf.nn.batch_normalization(x, mean, variance, None, None, eps)
        return x

优化策略和元算法

  • 坐标下降

参考资料

《深度学习》第8章
LBFGS算法笔记
知乎匿名用户回答BN的实现

2019-07-08 16:26:58 m0_38097757 阅读数 226
  • C++开发环境搭建-第1部分第2课

    《跟朱老师从C高级到征服C++》属于系列课程《朱有鹏老师热门编程语言全解》的第一部分,主要针对C++语言完全学习。本课程可以看做是嵌入式linux核心课程中《C语言高级专题》课程的延续,在学好了C语言前提下继续深度学习C++语言。整个课程共分为5部分。涵盖了C++基础语法和使用,面向对象,STL与泛型,Boost库和设计模式,C++编程优化技巧等非常广泛的内容,是市面上非常缺少的深度完整学习C++,培养编程技能和修养的一套系列学习课程。整个课程预计2020年底前录制完成,总时长预计150-200小时。 朱老师C++第1部分-从C到C++ 朱老师C++第2部分-C++和面向对象 朱老师C++第3部分-STL等高阶话题 朱老师C++第4部分-Boost库和设计模式 朱老师C++第5部分-C++编程优化 课程特色 *完全零基础,降低学习门槛。 *深入浅出,通俗易懂。不怕学不会,就怕你不学习。 *思路清晰、语言风趣,对着视频看也不会想睡觉······ *视频 + 文档 + 练习题 + 答疑,全方位保证学习质量。 *基础知识 + 思路引导的教学方式,授之以鱼更授之以渔。 *系列课程。本教程只是入门篇,后续还有更多更精彩视频更新中。

    10 人正在学习 去看看 朱有鹏

a. 牛顿法使用的是目标函数的二阶导数,在高维情况下这个矩阵非常大,计算和存储都是问题。

b. 在小批量的情况下,牛顿法对于二阶导数的估计噪声太大。

c.目标函数非凸的时候,牛顿法容易受到鞍点或者最大值点的吸引。

最大的问题就是计算复杂度。二阶一次迭代更新的复杂度是n*n,这在高维的时候是不可行的
稳定性。越简单的东西往往越robust,对于优化算法也是这样。
二阶求导不易
二阶方法能够更快地求得更高精度的解,但是在神经网络这类深层模型中,不高的精度对模型还有益处,能够提高模型的泛化能力。
 

没有更多推荐了,返回首页