自适应学习率调整:AdaDelta

2024-02-12 01:48
文章标签 学习 调整 适应 adadelta

本文主要是介绍自适应学习率调整:AdaDelta,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自适应学习率调整:AdaDelta

Reference:ADADELTA: An Adaptive Learning Rate Method

链接:  http://www.cnblogs.com/neopenx/p/4768388.html

超参数

超参数(Hyper-Parameter)是困扰神经网络训练的问题之一,因为这些参数不可通过常规方法学习获得。

神经网络经典五大超参数:

学习率(Leraning Rate)、权值初始化(Weight Initialization)、网络层数(Layers)

单层神经元数(Units)、正则惩罚项(Regularizer|Normalization)

这五大超参数使得神经网络更像是一门实践课,而不是理论课。

懂神经网络可能只要一小时,但是调神经网络可能要几天。

因此,后来Vapnik做SVM支持向量机的时候,通过巧妙的变换目标函数,避免传统神经网络的大部分超参数,

尤其是以自适应型的支持向量替代人工设置神经元,这使得SVM可以有效免于过拟合之灾。

传统对抗这些超参数的方法是经验规则(Rules of Thumb)。

这几年,随着深度学习的推进,全球神经网络研究者人数剧增,已经有大量研究组着手超参数优化问题:

★深度学习先锋的RBM就利用Pre-Traning自适应调出合适的权值初始化值。

★上个世纪末的LSTM长短期记忆网络,可视为“神经网络嵌套神经网络”,自适应动态优化层数。

★2010年Duchi et.al 则推出AdaGrad,自适应来调整学习率。

自适应调整学习率的方法,目前研究火热。一个经典之作,是 Matthew D. Zeiler 2012年在Google实习时,

提出的AdaDelta。

Matthew D. Zeiler亦是Hinton的亲传弟子之一,还是商业天才,大二时办了一个公司卖复习旧书。

Phd毕业之后,创办了Clarifai,估值五百万刀。参考[知乎专栏]

Clarifai的杰出成就是赢得了ImageNet 2013冠军,后来公布出CNN结构的时候,Caffe、Torch之类

的框架都仿真不出他在比赛时候跑的结果,应该是用了不少未公布的黑科技的。

再看他2012年提出的AdaDelta,肯定是用在的2013年的比赛当中,所以后来以普通方式才无法仿真的。

梯度更新

2.1 [一阶方法] 随机梯度

SGD(Stochastic Gradient Descent)是相对于BGD(Batch Gradient Descent)而生的。

BGD要求每次正反向传播,计算所有Examples的Error,这在大数据情况下是不现实的。

最初的使用的SGD,每次正反向传播,只计算一个Example,串行太明显,硬件利用率不高。

后续SGD衍生出Mini-Batch Gradient Descent,每次大概推进100个Example,介于BGD和SGD之间。

现在,SGD通常是指Mini-Batch方法,而不是早期单Example的方法。

一次梯度更新,可视为:

xt+1=xt+ΔxtwhereΔxt=ηgt xt+1=xt+ΔxtwhereΔxt=−η⋅gt

x x为参数 t t为时序 Δ Δ为更新量 η η为学习率 g g为梯度

2.2 [二阶方法] 牛顿法

二阶牛顿法替换梯度更新量:

Δxt=H1tgt Δxt=Ht−1⋅gt

H H为参数的二阶导矩阵,称为Hessian矩阵。

牛顿法,用Hessian矩阵替代人工设置的学习率,在梯度下降的时候,可以完美的找出下降方向,

不会陷入局部最小值当中,是理想的方法。

但是,求逆矩阵的时间复杂度近似 O(n3) O(n3),计算代价太高,不适合大数据。

常规优化方法

3.1 启发式模拟退火

早期最常见的手段之一就是模拟退火。当然这和模拟退火算法没有半毛钱关系。

引入一个超参数(常数)的退火公式:

ηt=η01+d×t ηt=η01+d×t

η0 η0为初始学习率 d d为衰减常数通常为 103 10−3

模拟退火基于一个梯度法优化的事实:

在优化过程中,Weight逐渐变大,因而需要逐渐减小学习率,保证更新平稳。

3.2 动量法

中期以及现在最普及的就是引入动量因子:

Δxt=ρΔxt1ηgt Δxt=ρΔxt−1−η⋅gt

ρ ρ为动量因子,通常设为0.9

在更新中引入0.9这样的不平衡因子,使得:

★在下降初期,使用前一次的大比重下降方向,加速。

★在越过函数谷面时,异常的学习率,会使得两次更新方向基本相反,在原地”震荡“

此时,动量因子使得更新幅度减小,协助越过函数谷面。

★在下降中后期,函数面局部最小值所在的吸引盆数量较多,一旦陷进吸引盆当中,

Gradient0 Gradient→0,但是前后两次更新方向基本相同。

此时,动量因子使得更新幅度增大,协助跃出吸引盆。

3.3  AdaGrad

AdaGrad思路基本是借鉴L2 Regularizer,不过此时调节的不是 W W,而是 Gradient Gradient:

Δxt=ηtτ=1(gτ)2gt Δxt=−η∑τ=1t(gτ)2⋅gt

AdaGrad过程,是一个递推过程,每次从 τ=1 τ=1,推到 τ=t τ=t,把沿路的 Gradient Gradient的平方根,作为Regularizer。

分母作为Regularizer项的工作机制如下:

★训练前期,梯度较小,使得Regularizer项很大,放大梯度。[激励阶段]

★训练后期,梯度较大,使得Regularizer项很小,缩小梯度。[惩罚阶段]

另外,由于Regularizer是专门针对Gradient的,所以有利于解决Gradient Vanish/Expoloding问题。

所以在深度神经网络中使用会非常不错。

当然,AdaGrad本身有不少缺陷:

★初始化W影响初始化梯度,初始化W过大,会导致初始梯度被惩罚得很小。

此时可以人工加大 η η的值,但过大的 η η会使得Regularizer过于敏感,调节幅度很大。

★训练到中后期,递推路径上累加的梯度平方和越打越多,迅速使得 Gradinet Gradinet被惩罚逼近0,提前结束训练。

AdaDelta

AdaDelta基本思想是用一阶的方法,近似模拟二阶牛顿法。

4.1 矩阵对角线近似逆矩阵

1988年,[Becker&LeCun]提出一种用矩阵对角线元素来近似逆矩阵的方法:

Δxt=1|diag(Ht)|+μgt Δxt=−1|diag(Ht)|+μ⋅gt

diag diag指的是构造Hessian矩阵的对角矩阵, μ μ是常数项,防止分母为0。

2012年,[Schaul&S. Zhang&LeCun]借鉴了AdaGrad的做法,提出了更精确的近似:

Δxt=1|diag(Ht)|E[gtw:t]2E[g2tw:t]gt Δxt=−1|diag(Ht)|E[gt−w:t]2E[gt2−w:t]⋅gt

E[gtw:t] E[gt−w:t]指的是从当前t开始的前w个梯度状态的期望值。

E[g2tw:t] E[gt2−w:t]指的是从当前t开始的前w个梯度状态的平方的期望值。

同样是基于Gradient的Regularizer,不过只取最近的w个状态,这样不会让梯度被惩罚至0。

4.2 窗口和近似概率期望

计算 E[gtw:t] E[gt−w:t],需要存储前w个状态,比较麻烦。

AdaDelta使用了类似动量因子的平均方法:

E[g2]t=ρE[g2]t1+(1ρ)g2t E[g2]t=ρE[g2]t−1+(1−ρ)gt2

ρ=0.5 ρ=0.5时,这个式子就变成了求梯度平方和的平均数。

如果再求根的话,就变成了RMS(均方根):

RMS[g]t=E[g2]t+ϵ RMS[g]t=E[g2]t+ϵ

再把这个RMS作为Gradient的Regularizer:

Δxt=ηRMS[g]tgt Δxt=−ηRMS[g]t⋅gt

其中, ϵ ϵ是防止分母爆0的常数。

这样,就有了一个改进版的AdaGrad。

该方法即Tieleman&Hinton的RMSProp,由于RMSProp和AdaDelta是同年出现的,

Matthew D. Zeiler并不知道这种改进的AdaGrad被祖师爷命名了。

RMSProp利用了二阶信息做了Gradient优化,在BatchNorm之后,对其需求不是很大。

但是没有根本实现自适应的学习率,依然需要线性搜索初始学习率,然后对其逐数量级下降。

另外,RMSProp的学习率数值与MomentumSGD差别甚大,需要重新线性搜索初始值。

注: ϵ ϵ的建议取值为1,出处是Inception V3,不要参考V3的初始学习率。

4.3 Hessian方法与正确的更新单元

Zeiler用了两个反复近似的式子来说明,一阶方法到底在哪里输给了二阶方法。

首先,考虑SGD和动量法:

Δxgfx1x Δx∝g∝∂f∂x∝1x

Δx Δx可以正比到梯度 g g问题,再正比到一阶导数。而 log log一阶导又可正比于 1x 1x

再考虑二阶导Hessian矩阵法:

这里为了对比观察,使用了[Becker&LeCun 1988]的近似方法,让求逆矩阵近似于求对角阵的倒数:

ΔxH1gfx2fx21x1x1xx Δx∝H−1g∝∂f∂x∂2f∂x2∝1x1x∗1x∝x

Δx Δx可以正比到Hessian逆矩阵 H1g H−1⋅g问题,再正比到二阶导数。而 log log二阶导又可正比于 x x

可以看到,一阶方法最终正比于 1x 1x,即与参数逆相关:参数逐渐变大的时候,梯度反而成倍缩小。

而二阶方法最终正比于 x x,即与参数正相关:参数逐渐变大的时候,梯度不受影响。

因此,Zeiler称Hessian方法得到了Correct Units(正确的更新单元)。

4.4 由Hessian方法推导出一阶近似Hessian方法

基于[Becker&LeCun 1988]的近似方法,有:

Δxfx2fx2 Δx≈∂f∂x∂2f∂x2

进而又有:

fx2fx2=12fx2fx=12fx2gt ∂f∂x∂2f∂x2=1∂2f∂x2⋅∂f∂x=1∂2f∂x2⋅gt

简单收束变形一下, 然后用RMS来近似:

12fx2=ΔxfxRMS[Δx]t1RMS[g]t 1∂2f∂x2=Δx∂f∂x≈−RMS[Δx]t−1RMS[g]t

最后,一阶完整近似式:

Δx=RMS[Δx]t1RMS[g]tgt Δx=−RMS[Δx]t−1RMS[g]t⋅gt

值得注意的是,使用了 RMS[Δx]t1 RMS[Δx]t−1而不是 RMS[Δx]t RMS[Δx]t,因为此时 Δxt Δxt还没算出来。

4.5 算法流程

ALGORITHM:ADADELTARequire:DecayRateρ,ConstantϵRequire:InitialParamx11:InitializeaccumulationvariablesE[g2]0=E[Δx2]0=02:Fort=1:TdoLoopallupdates3:ComputeGradients:gt4:AccumulateGradient:E[g2]t=ρE[g2]t1+(1ρ)g2t5:ComputeUpdate:Δx=RMS[Δx]t1RMS[g]tgt6:AccumulateUpdates:E[Δx2]t=ρE[Δx2]t1+(1ρ)Δx27:ApplyUpdate:xt+1=xt+Δxt8:EndFor ALGORITHM:ADADELTARequire:DecayRateρ,ConstantϵRequire:InitialParamx11:InitializeaccumulationvariablesE[g2]0=E[Δx2]0=02:Fort=1:TdoLoopallupdates3:ComputeGradients:gt4:AccumulateGradient:E[g2]t=ρE[g2]t−1+(1−ρ)gt25:ComputeUpdate:Δx=−RMS[Δx]t−1RMS[g]t⋅gt6:AccumulateUpdates:E[Δx2]t=ρE[Δx2]t−1+(1−ρ)Δx27:ApplyUpdate:xt+1=xt+Δxt8:EndFor

4.6 Theano实现

论文中,给出的两个超参数的合适实验值。

ρ=0.95ϵ=1e6 ρ=0.95ϵ=1e−6

Theano的实现在LSTM的教学部分,个人精简了一下:

def AdaDelta(tparams,grads):p=0.95;e=1e-6# initdelta_x2=[theano.shared(p.get_value() * floatX(0.)) for k, p in tparams.iteritems()]g2 = [theano.shared(p.get_value() * floatX(0.)) for k, p in tparams.iteritems()]# first to update g2update_g2=[(g2, p * g2 + (1-p) * (g ** 2)) for g2, g in zip(g2, grads)]fn_update_1=theano.function(inputs=[],updates=update_g2)#calc delta_x by RMSdelta_x=[-T.sqrt(delta_x2_last + e) / T.sqrt(g2_now + e) * g for g, delta_x2_last, g2_now in zip(grads,delta_x2,g2)]# then to update delta_x2 and paramupdate_delta_x2=[(delta_x2, p * delta_x2 + (1-p) * (delta_x ** 2)) for delta_x2, delta_x in zip(delta_x2, delta_x)]update_param=[(param, param + delta) for param, delta in zip(tparams.values(), delta_x)]fn_update_2=theano.function(inputs=[],updates=update_delta_x2+update_param)#return the update function of theanoreturn fn_update_1, fn_update_2

 

4.7 Dragon(Caffe)实现

默认代码以我的Dragon框架为准,对Caffe代码进行了重写。

  View Code

AdaDelta的缺陷

局部最小值

从多个数据集情况来看,AdaDelta在训练初期和中期,具有非常不错的加速效果。

但是到训练后期,进入局部最小值雷区之后,AdaDelta就会反复在局部最小值附近抖动。

主要体现在验证集错误率上,脱离不了局部最小值吸引盆。

这时候,切换成动量SGD,如果把学习率降低一个量级,就会发现验证集正确率有2%~5%的提升,

这与常规使用动量SGD,是一样的。

之后再切换成AdaDelta,发现正确率又退回去了。

再切换成动量SGD,发现正确率又回来了。

---------------------------------------------------------------------

注:使用Batch Norm之后,这样从AdaDelta切到SGD会导致数值体系崩溃,原因未知。

---------------------------------------------------------------------

个人猜测,人工学习率的量级降低,给训练造成一个巨大的抖动,从一个局部最小值,

抖动到了另一个局部最小值,而AdaDelta的二阶近似计算,或者说所有二阶方法,

则不会产生这么大的抖动,所以很难从局部最小值中抖出来。

这给追求state of art的结果带来灾难,因为只要你一直用AdaDelta,肯定是与state of art无缘的。

基本上state of art的结果,最后都是SGD垂死挣扎抖出来的。

这也是SGD为什么至今在state of art的论文中没有废除的原因,人家丑,但是实在。

精度

eps的数值不是固定的。

1e-6在Caffe Cifar10上就显得过小了,1e-8比较适合。

这意味着不同数值比例体系,精度需要人工注意。

paper里高精度反而没低精度好,说明精度也有比较大抖动。

so,究竟什么样的精度是最好的呢?

————————————————————————————————————

2016.5.19 更新:

在FCNN-AlexNet里,1e-8在epoch1之后就会产生数值问题。

原因是sqrt(1e-8)*grad很大,这时候1e-10是比较好的。

另外,DensePrediction一定要做normalize,否则也有可能让AdaDelta的迭代步长计算出现数值问题。

该问题在FCNN-AlexNet进行到epoch5左右时候开始明显化。

caffe默认给的1e-10实际上要比paper里的1e-6要相对robust。

这篇关于自适应学习率调整:AdaDelta的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/701370

相关文章

C#中图片如何自适应pictureBox大小

《C#中图片如何自适应pictureBox大小》文章描述了如何在C#中实现图片自适应pictureBox大小,并展示修改前后的效果,修改步骤包括两步,作者分享了个人经验,希望对大家有所帮助... 目录C#图片自适应pictureBox大小编程修改步骤总结C#图片自适应pictureBox大小上图中“z轴

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个