当前位置: 首页 > article >正文

Adam优化器算法详解及代码实现

文章目录

  • 学习率调整与梯度估计修正
    • RMSprop 算法
    • 动量法
  • Adam

学习率调整与梯度估计修正

在介绍Adam算法之前,先谈谈Adam中两个关键的算法:学习率调整(RMSprop 算法)梯度估计修正

RMSprop 算法

学习率是神经网络优化时的重要超参数。在标准的梯度下降法中,每个参数在每次迭代时都使用相同的学习率,但是学习率如果过大就不会收敛,如果过小则收敛速度太慢。

RMSprop 算法是 Geoff Hinton 提出的一种自适应学习率的方法【RMSprop】,可以在有些情况下避免 AdaGrad 算法中学习率不断单调下降以至于过早衰减的缺点。

RMSprop 算法首先计算每次迭代梯度 𝒈𝑡 平方的指数衰减移动平均𝐺𝑡 :
在这里插入图片描述

其中,β为自定义衰减率(例如0.9)。

然后,根据指数衰减移动平均𝐺𝑡 计算参数更新差值Δ𝜃𝑡 :
在这里插入图片描述
其中, 𝛼 是初始的学习率,𝜖 是为了保持数值稳定性而设置的非常小的常数。

动量法

在随机(小批量)梯度下降法中,如果每次选取样本数量比较小,损失会呈现振荡的方式下降.也就是说,随机梯度下降方法中每次迭代的梯度估计和整个训练集上的最优梯度并不一致,具有一定的随机性。一种有效地缓解梯度估计随机性的方式是通过使用最近一段时间内的平均梯度来代替当前时刻的随机梯度来作为参数更新的方向,从而提高优化速度。

动量法用之前积累动量来替代真正的梯度,在第 𝑡 次迭代时,计算负梯度的“加权移动平均”作为参数的更新方向:
在这里插入图片描述
其中, 𝜌 为动量因子,通常设为 0.9,𝛼 为学习率。

动量法将每个参数的实际更新差值表示为最近一段时间内梯度的加权平均值。在迭代前期,梯度方向都一致,动量法加速参数更新幅度;在迭代后期,剃度方向会不一致,在收敛值附近振荡,动量法会降低参数更新幅度。

类比于物理学,动量法把当前梯度看做当前时刻受理参数的加速度,为了计算当前时刻的速度,应当考虑前一时刻速度和当前加速度共同作用的结果,因此参数的更新直接依赖于前一时刻的更新量和当前时刻的梯度,而不仅仅是当前梯度。另外,𝜌 扮演了阻力的作用。

Adam

Adam是由 OpenAI 的 Diederik Kingma 和多伦多大学的 Jimmy Ba于2015年提出的一种随机优化方法。
在这里插入图片描述

原文链接:ADAM: A METHOD FOR STOCHASTIC OPTIMIZATION:https://arxiv.org/pdf/1412.6980.pdf%5D

Adam算法结合RMSprop 算法和动量法,不但使用动量作为参数更新方向,而且可以自适应调整学习率来改进梯度下降。

  1. 计算梯度平方 g𝑡 平方的指数加权平均(RMSprop );
    在这里插入图片描述
g[:] = beta2 * s + (1 - beta2) * torch.mul(p.grad, p.grad)
  1. 计算梯度 g𝑡 的指数加权平均(动量法);
    在这里插入图片描述
    其中, 𝛽1 和 𝛽2 分别为两个移动平均的衰减率,在Adam原文中取值为 𝛽1 = 0.9, 𝛽2 = 0.999。
m[:] = beta1 * v + (1 - beta1) * p.grad
  1. 对偏差进行修正
    在这里插入图片描述
m_bias_corr = m / (1 - beta1 ** hyperparams['t'])
g_bias_corr = g / (1 - beta2 ** hyperparams['t'])
  1. 计算参数更新差值
    在这里插入图片描述
p[:] -= hyperparams['lr'] * m_bias_corr / (torch.sqrt(g_bias_corr) + eps)

在Adam论文原文中,对Adam的算法描述如下:

在这里插入图片描述

下面给出Adam的简单实现:

def adam(params, states, hyperparams):
    beta1, beta2, eps = 0.9, 0.99, 1e-6
    for p, (m, g) in zip(params, states):
        with torch.no_grad():
            m[:] = beta1 * m + (1 - beta1) * p.grad
            g[:] = beta2 * g + (1 - beta2) * torch.mul(p.grad, p.grad)
            m_bias_corr = m / (1 - beta1 ** hyperparams['t'])
            g_bias_corr = g / (1 - beta2 ** hyperparams['t'])
            p[:] -= hyperparams['lr'] * m_bias_corr / (torch.sqrt(g_bias_corr) + eps)
        p.grad.data.zero_()
    hyperparams['t'] += 1

Adam记录梯度的一阶矩,即过去梯度与当前梯度的平均,体现了惯性保持;还记录了梯度的二阶矩,即过去过去梯度平方与当前梯度平方的平均,体现了环境感知能力,为不同参数产生自适应的学习速率。

因此,Adam优化器具有以下优点:

  • 实现简单,计算高效,内存占有量少;

  • 适合解决含大规模数据和参数的优化问题

  • 适用于不稳定的目标函数

  • 适用于解决包含很高噪声或稀疏梯度的问题

  • 超参数可以很直观地解释,并且基本上只需极少量的调参

  • 自然地调整学习率


http://www.kler.cn/a/1013.html

相关文章:

  • 《跟我学Spring Boot开发》系列文章索引❤(2025.01.09更新)
  • Java 如何传参xml调用接口获取数据
  • 【Rust自学】11.7. 按测试的名称运行测试
  • EasyExcel(二)导出Excel表自动换行和样式设置
  • H2数据库在单元测试中的应用
  • 啥!GitHub Copilot也免费使用了
  • ubuntu不同版本的源(换源)(镜像源)(lsb_release -c命令,显示当前系统的发行版代号(Codename))
  • 【Android笔记85】Android之使用Camera和MediaRecorder录制视频
  • Java的jar包打包成exe应用
  • K8S集群之-ETCD集群监控
  • 有图解有案例,我终于把 Condition 的原理讲透彻了
  • 几个cve漏洞库查询网站-什么是CVE?常见漏洞和暴露列表概述
  • Android 自定义view优化方案
  • spring事务 只读此文
  • Go panic的学习
  • 初识C++需要了解的一些东西(2)
  • 从GPT到GPT-3:自然语言处理领域的prompt方法
  • 开源超级终端工具——WindTerm
  • Qt·Linux下Qt、Qml程序的打包
  • Linux(传输层二继续讲TCP)
  • 关于进制转换
  • 【C++】Google编码风格学习
  • 11广义表的基本概念和性质
  • mysql创建索引导致死锁,数据库崩溃,完美解决方案
  • 自训练和协同训练简述
  • C/C++考试必考题目(含答案*仅供参考)