梯度优化算法Adam

25 篇文章 21 订阅
22 篇文章 5 订阅

前言

最近读一个代码发现用了一个梯度更新方法, 刚开始还以为是什么奇奇怪怪的梯度下降法, 最后分析一下是用一阶梯度及其二次幂做的梯度更新。网上搜了一下, 果然就是称为Adam的梯度更新算法, 全称是:自适应矩估计(adaptive moment estimation)

国际惯例, 参考博文:

一文看懂各种神经网络优化算法:从梯度下降到Adam方法

Adam:一种随机优化方法

An overview of gradient descent optimization algorithms

梯度下降优化算法综述

Hinton的神经网络课程第六课

理论

由于参考博客介绍的很清晰, 我就直接撸公式了:

假设 t 时刻, 目标函数对于参数的一阶导数是gt,那么我们可以先计算

mtvt=β1mt1+(1β1)gt=β2vt1+(1β2)g2t

接下来计算
mt^=mt1βt1vt^=vt1βt2

最后我们的梯度更新方法就是
θt+1=θtηmt^vt^+ϵ

注意几个量, η 是学习步长, 剩下的三个参数取值的建议是 β1=0.9,β2=0.999,ϵ=108 , 分母中的 ϵ 是为了防止除零. 其实这个步长的话,一般来说是建议选 η=0.001 之类的, 注意 βt1,βt2 中的 t 是参与指数运算的

其实再看一下公式,其实就是当前时刻的梯度更新利用了上一时刻的平方梯度vt的指数衰减均值 vt^ 和上一时刻的梯度 mt 的指数衰减均值 mt^

代码实现

以下非一个神经网络的完整实现, 主要在于看看定义网络参数以后怎么去使用Adam去更新每一时刻的梯度, 在theano中的实现方法如下:

先看看神经网络的参数

self.layers = [
            self.W0, self.W1, self.W2,
            self.b0, self.b1, self.b2]

self.params = sum([layer.params for layer in self.layers], [])

然后初始化一开始时候的 mt,vt ,分别对应代码中的 m0params,m1params

self.params = network.params
self.m0params = [theano.shared(np.zeros(p.shape.eval(), dtype=theano.config.floatX), borrow=True)                   for p in self.params]
self.m1params = [theano.shared(np.zeros(p.shape.eval(), dtype=theano.config.floatX), borrow=True)                   for p in self.params]
self.t = theano.shared(np.array([1], dtype=theano.config.floatX))

定义目标函数=损失函数+正则项:

 cost = self.cost(network, input, output) + network.cost(input)

计算当前梯度

gparams = T.grad(cost, self.params)

计算 m0params,m1params

m0params = [self.beta1 * m0p + (1-self.beta1) *  gp     for m0p, gp in zip(self.m0params, gparams)]
        m1params = [self.beta2 * m1p + (1-self.beta2) * (gp*gp) for m1p, gp in zip(self.m1params, gparams)]

使用Adam梯度更新

params = [p - self.alpha * 
                  ((m0p/(1-(self.beta1**self.t[0]))) /
            (T.sqrt(m1p/(1-(self.beta2**self.t[0]))) + self.eps))
            for p, m0p, m1p in zip(self.params, m0params, m1params)]

然后更新下一时刻网络中的梯度值, m0params , m1params , t <script type="math/tex" id="MathJax-Element-20">t</script>

updates = ([( p,  pn) for  p,  pn in zip(self.params, params)] +
                   [(m0, m0n) for m0, m0n in zip(self.m0params, m0params)] +
                   [(m1, m1n) for m1, m1n in zip(self.m1params, m1params)] +
                   [(self.t, self.t+1)])
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风翼冰舟

额~~~CSDN还能打赏了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值