【optimizer详解】

2023-05-16

optimizer

定义

  • optimizer就是在深度学习反向传播过程中,指引损失函数(目标函数)的各个参数往正确的方向更新合适的大小,使得更新后的各个参数让损失函数(目标函数)值不断逼近全局最小

步骤

待优化参数: ω \omega ω
目标函数: f ( x ) f(x) f(x)
初始学习率: α \alpha α
迭代epoch: t t t

参数更新步骤如下:

Ⅰ.计算目标函数关于当前参数的梯度:
g t = ∇ f ( ω t ) g_t=\nabla{f(\omega_t)} gt=f(ωt)
Ⅱ. 根据历史梯度计算一阶动量和二阶动量:
m t = ∅ ( g 1 , g 2 , . . . . , g t ) V t = ∑ i = 0 t x i 2 m_t=\varnothing(g1,g2,....,gt)\\V_t=\sum_{i=0}^tx_i^2 mt=(g1,g2,....,gt)Vt=i=0txi2
Ⅲ. 计算当前时刻的下降梯度:
η t = α ⋅ m t / V t \eta_t=\alpha \cdot {m_t}/\sqrt{V_t} ηt=αmt/Vt
Ⅳ. 根据下降梯度进行更新参数:
ω t + 1 = ω t − η t \omega_{t+1}=\omega_t-\eta_t ωt+1=ωtηt
步骤Ⅲ、Ⅳ对于各个算法都是一致的,主要的差别就体现在步骤Ⅰ、Ⅱ上

常见方法

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

    • 每次从训练集中随机选择一个样本来进行学习,SGD没有动量的概念

    • m t = g t ; V t = I 2 m_t=g_t;V_t=I^2 mt=gt;Vt=I2

    • η t = α ⋅ g t g t \eta_t=\alpha \cdot {g_t} \qquad g_t ηt=αgtgt是当前参数的梯度

    • ω t + 1 = ω t − η t = ω t − α ⋅ g t \omega_{t+1}=\omega_t-\eta_t=\omega_t-\alpha \cdot {g_t} ωt+1=ωtηt=ωtαgt

    • '''
      params(iterable)- 参数组,优化器要优化的那部分参数。
      lr(float)- 初始学习率,可按需随着训练过程不断调整学习率。
      momentum(float)- 动量,通常设置为 0.9,0.8
      dampening(float)- dampening for momentum ,暂时不了其功能,在源码中是这样用的:buf.mul_(momentum).add_(1 - dampening, d_p),值得注意的是,若采用nesterov,dampening 必须为 0.
      weight_decay(float)- 权值衰减系数,也就是 L2 正则项的系数
      nesterov(bool)- bool 选项,是否使用 NAG(Nesterov accelerated gradient)
      '''
      torch.optim.SGD(params, 
                      lr=<object object>, 
                      momentum=0, 
                      dampening=0, 
                      weight_decay=0, 
                      nesterov=False)
      
    • SGD with Momentum

      • 在SGD基础上引入了一阶动量: m t = β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅ g t m_t=\beta_1 \cdot m_{t-1}+(1-\beta_1)\cdot {g_t} mt=β1mt1+(1β1)gt
      • ω t + 1 = ω t − α ⋅ m t = ω t − α ⋅ ( β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅ g t ) \omega_{t+1}=\omega_t-\alpha\cdot m_t=\omega_t-\alpha \cdot (\beta_1 \cdot m_{t-1}+(1-\beta_1)\cdot {g_t}) ωt+1=ωtαmt=ωtα(β1mt1+(1β1)gt)
      • β \beta β的经验值为0.9
      • 一阶动量是各个时刻梯度方向的指数移动平均值,也就是说t时刻的下降方向,不仅由当前点的梯度方向决定,而且由此前累积的下降方向决定
    • SGD with Nesterov Acceleration

      • NAG在步骤Ⅰ,不计算当前位置的梯度方向,而是计算如果按照累积动量走了一步,那个时候的下降方向: g t = ∇ f ( ω − α ⋅ m t − 1 / V t − 1 ) g_t=\nabla{f(\omega-\alpha\cdot m_{t-1}/\sqrt{V_{t-1}})} gt=f(ωαmt1/Vt1 )
      • 参数更新公式如下
        ω t + 1 = ω t − α ⋅ g t = ω t − α ∗ ( ∇ f ( ω − α ⋅ m t − 1 / V t − 1 ) ) \omega_{t+1}=\omega_t-\alpha\cdot g_t=\omega_t-\alpha*(\nabla{f(\omega-\alpha\cdot m_{t-1}/\sqrt{V_{t-1}})}) ωt+1=ωtαgt=ωtα(f(ωαmt1/Vt1 ))
      • 然后用下一个点的梯度方向,与历史累积动量相结合,计算步骤Ⅱ中当前时刻的累积动量
      • 有利于跳出当前局部最优的沟壑,寻找新的最优值,但是收敛速度慢
  • AdaGrad(自适应学习率算法)

    • SGD系列的都没有用到二阶动量。二阶动量的出现,才意味着“自适应学习率”优化算法时代的到来
    • 二阶动量——该维度上,记录到目前为止所有梯度值的平方和
      V t = ∑ τ = 1 t g τ 2 V_t=\sum_{\tau=1}^tg_{\tau}^2 Vt=τ=1tgτ2
    • AdaGrad参数更新公式
      ω t + 1 = ω t − α ⋅ m t / V t = ω − α ⋅ m t / ∑ τ = 1 t g τ 2 \omega_{t+1}=\omega_t-\alpha\cdot m_t/\sqrt{V_t}=\omega-\alpha \cdot m_t/\sqrt{\sum_{\tau=1}^tg_\tau^2} ωt+1=ωtαmt/Vt =ωαmt/τ=1tgτ2
    • 此时实质上的学习率由 α \alpha α变成了 α / V t \alpha/\sqrt{V_t} α/Vt ,一般为了避免分母为0,会在分母上加一个小的平滑项,因此 V t \sqrt{V_t} Vt 是恒大于0的,而且参数更新越频繁,二阶动量越大,学习率就越小
  • AdaDelta / RMSProp

    • AdaGrad单调递减的学习率变化过于激进,考虑一个改变二阶动量计算方法的策略:不累积全部历史梯度,而只关注过去一段时间窗口的下降梯度。
    • V t = β 2 ⋅ V t − 1 + ( 1 − β 2 ) g t 2 V_t=\beta_2 \cdot V_{t-1}+(1-\beta_2)g^2_t Vt=β2Vt1+(1β2)gt2
    • AdaDelta / RMSProp参数更新公式
      ω t + 1 = ω t − α ⋅ m t / V t = ω − α ⋅ m t / β 2 ⋅ V t − 1 + ( 1 − β 2 ) g t 2 \omega_{t+1}=\omega_t-\alpha\cdot m_t/\sqrt{V_t}=\omega-\alpha \cdot m_t/\sqrt{\beta_2 \cdot V_{t-1}+(1-\beta_2)g^2_t} ωt+1=ωtαmt/Vt =ωαmt/β2Vt1+(1β2)gt2
    • 避免了二阶动量持续累积、导致训练过程提前结束的问题了
  • Adam

    • 把一阶动量和二阶动量都用起来,就是Adam了——Adaptive + Momentum

    • SGD的一阶动量:
      m t = β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅ g t m_t=\beta_1 \cdot m_{t-1}+(1-\beta_1)\cdot {g_t} mt=β1mt1+(1β1)gt

    • 加上AdaDelta的二阶动量:
      V t = β 2 ⋅ V t − 1 + ( 1 − β 2 ) g t 2 V_t=\beta_2 \cdot V_{t-1}+(1-\beta_2)g^2_t Vt=β2Vt1+(1β2)gt2

    • Adam参数更新公式
      ω t + 1 = ω t − α ⋅ m t / V t = ω − α ⋅ ( β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅ g t ) / β 2 ⋅ V t − 1 + ( 1 − β 2 ) g t 2 \omega_{t+1}=\omega_t-\alpha\cdot m_t/\sqrt{V_t}\\\qquad=\omega-\alpha \cdot (\beta_1 \cdot m_{t-1}+(1-\beta_1)\cdot {g_t})/\sqrt{\beta_2 \cdot V_{t-1}+(1-\beta_2)g^2_t} ωt+1=ωtαmt/Vt =ωα(β1mt1+(1β1)gt)/β2Vt1+(1β2)gt2

    • '''
      params 模型里需要被更新的可学习参数
      lr 学习率
      betas 平滑常数β1和β2
      eps 加在分母上防止除0
      weight_decay L2正则化,和Adam并无直接关系
      amsgrad 如果amsgrad为True,保留历史最大的v_t,记为v_max,每次计算都是用最大的v_max,否则是用当前v_t
      '''
      torch.optim.Adam(params,
                  lr=0.001,
                  betas=(0.9, 0.999),
                  eps=1e-08,
                  weight_decay=0,
                  amsgrad=False)
      
    • Adam缺点

      • 可能不收敛
        • 二阶动量是固定时间窗口内的累积,随着时间窗口的变化,遇到的数据可能发生巨变,使得 V t V_t Vt可能时大时小,不是单调变化。可能引起学习率震荡,模型无法收敛
        • 修正方法 V t = m a x ( β 2 ∗ V t − 1 + ( 1 − β 2 ) g t 2 , V t − 1 ) V_t=max(\beta_2*V_{t-1}+(1-\beta_2)g_t^2,V_{t-1}) Vt=max(β2Vt1+(1β2)gt2,Vt1)
          保证 ∣ ∣ V t ∣ ∣ > = ∣ ∣ V t − 1 ∣ ∣ ||V_t||>=||V_{t-1}|| ∣∣Vt∣∣>=∣∣Vt1∣∣,使得学习率单调递减
      • 可能错过全局最优解
        • 自适应学习率算法可能会对前期出现的特征过拟合,后期才出现的特征很难纠正前期的拟合效果。后期Adam的学习率太低,影响了有效的收敛
  • Nadam

    • Adam是集大成者,但它居然遗漏了Nesterov
    • 按照NAG的步骤 g t = ∇ f ( ω t − α ⋅ m t − 1 / V t ) g_t=\nabla{f(\omega_t-\alpha \cdot m_{t-1}/\sqrt{V_t})} gt=f(ωtαmt1/Vt )
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【optimizer详解】 的相关文章

  • 关于二叉树的建立(C语言)(链式)

    首先 xff0c 我们得知道二叉树是什么 xff01 xff01 这东西网上一大把 还有 xff0c 二叉树的遍历顺序 xff0c 前序 xff08 根左右 xff09 xff0c 中序 xff08 左根右 xff09 xff0c 后序 x
  • [springMVC学习]1、springmvc设置spring配置文件

    我们给springmvc设置配置文件 xff0c 实际上就是让某个类在tomcat启动时 xff0c 自动的去读取配置文件 xff0c 完成ioc容器的创建 xff0c 完成初始化工作 在spring中 xff0c 我们是手动new出来 x
  • 无法连接 MKS: Login(username/password)incorrect

    升级到Vmware Workstation 12之后 xff0c 客户端能连上虚拟机服务器 xff0c 但却打不开共享的虚拟机 xff0c 提示报错 无法连接 MKS Login username password incorrect 查了
  • 李永乐(一)行列式计算——笔记

    行列式基本性质 一 行列式求值 说明 xff1a 第 i 行元素 乘 第 j 列的代数余子式 之和 61 0 二 转置行列式值不变 引申 xff1a 行有什么性质 xff0c 列就有什么性质 三 两行互换 xff0c 行列式值变号 引申 x
  • 计算机网络——组播地址(多播地址、D类地址)详解——不断完善更新中

    1 是什么 先看这张图 xff0c 组播地址是分类编址的IPv4地址中的D类地址 xff0c 又叫多播地址 xff0c 他的前四位必须是1110 xff0c 所以网络地址的取值范围是224 239 2 这些IP地址用来做什么 224 0 0
  • 线代——猴博士笔记

    求向量组的秩 xff0c 先求极大无关组 xff0c 极大无关组里几个向量 xff0c 秩就是几 什么是极大无关组 xff1f 从一向量组挑出几个向量 xff0c 他们线性无关 xff0c 且原来向量组中任意一个向量加进去 xff0c 又变
  • C++ std::ref————详解

    想学习ref xff0c 必须先学习reference rapper 1 是什么 xff1f ref是个函数模板 xff1a 用来构建一个reference wrapper对象并返回 xff0c 该对象拥有传入的elem变量的引用 如果参数
  • I/O复用的高级应用:聊天室程序———实例代码

    1概述 这是一个聊天室程序 xff0c 分为服务端和客户端两部分 多个客户端可以连接到同一个服务器 xff0c 当一个客户端向服务器发送消息时 xff0c 该消息会被转发给除发送端外的其他客户端 xff0c 其他客户端收到该消息并输出到标准

随机推荐

  • CMake指令解析 set(CMAKE_CXX_FLAGS “$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprec

    完整代码 set span class token punctuation span CMAKE CXX FLAGS span class token string 34 span class token variable ENV span
  • vscode找不到头文件报错,就离谱

    最近在vscode写一个项目 xff0c 进行编译测试的时候发现死活找不到头文件 xff0c 就离谱 xff0c CMakeLists txt里的include directories所有头文件包含路径写的明明白白清清楚楚 xff0c 就是
  • 有26个字母a~z,找出所有字母组合,a、b、c、ab、abc、a~z 都是一个组合(顺序无关)

    mark 一下 xff0c 好像是用深搜做的 xff0c 目前看不太懂 span class token keyword int span list span class token punctuation span span class
  • 对顶堆模板:求动态数组的中位数

    模板 priority queue span class token operator lt span span class token keyword int span span class token operator gt span
  • C++八股文

    文章目录 C 43 43 语言int function int a int b 指针数组和数组指针的区别 xff1f 数组指针指针数组 函数指针和指针函数的区别函数指针指针函数 常量指针和指针常量的区别数组和指针的区别指针和引用的区别数组名
  • 一个HTML网页简单有效的验证码更换方法

    代码展示 lt img name 61 34 verifycode 34 src 61 34 verifyServlet 34 height 61 34 40px 34 width 61 34 150px 34 onclick 61 34
  • 获取CSDN文章内容并转换为markdown文本的python

    这篇文章主要介绍了自己写的小工具 xff0c 可以直接获取csdn文章并转换为markdown格式 需要的朋友可以参考下 自己写的小工具 xff0c 可以直接获取csdn文章并转换为markdown格式 效果图 核心代码 span clas
  • Android-视图绑定

    举例 xff1a 此时 xff0c first layout xml中定义了一个button且id为button1的按钮 在FirstActivity中我们想要调用这个按钮的话 xff0c 有两种方法 第一种 xff0c 通过FindVie
  • C语言程序设计1

    C语言程序设计1 计算机语言分类 xff1a 机器语言 xff1a xff08 machine language xff09 计算机直接使用的二进制形式的程序语言或机器代码 汇编语言 xff1a 借助助记符进行描述的计算机语言 高级语言 x
  • ZYNQ中的GPIO与AXI GPIO

    GPIO GPIO 一种外设 xff0c 对器件进行观测和控制MIO 将来自PS外设和静态存储器接口的访问多路复用到PS引脚上处理器控制外设的方法 通过一组寄存器包括状态寄存器和控制寄存器 xff0c 这些寄存器都是有地址的 xff0c 通
  • FTP文件传输协议

    简介 FTP协议 xff1a 文件传输协议 xff08 File Transfer Protocol xff09 协议定义了一个在远程计算机系统和本地计算机系统之间传输文件的一个标准FTP运行在OSI模型的应用层 xff0c 并利用传输协议
  • python中如何用for循环语句1加到100?

    计算机是现代一种用于高速计算的电子计算机器 xff0c 是一种高级的计算工具 可以进行数值计算 xff0c 又可以进行逻辑计算 xff0c 还具有存储记忆功能 是能够按照程序运行 xff0c 自动 高速处理海量数据的现代化智能电子设备 计算
  • controller层配置全局配置拦截器

    大家好 xff0c 我是一名在算法之路上不断前进的小小程序猿 xff01 体会算法之美 xff0c 领悟算法的智慧 希望各位博友走过路过可以给我点个免费的赞 xff0c 你们的支持是我不断前进的动力 xff01 xff01 加油吧 xff0
  • 用python写DFS和BFS算法

    前言 xff1a 菜鸟学算法 加油 xff01 一 什么是DFS和BFS xff1f 1 BFS算法 xff1a 宽度优先搜索算法 xff08 又称广度优先搜索 xff09 是最简便的图的搜索算法之一 xff0c 这一算法也是很多重要的图的
  • 进程同步 生产者消费者问题

    题目 xff1a 某超级市场 xff0c 可容纳100人同时购物 入口处备有篮子 xff0c 每个购物者可持一只篮子入内购物 出口处结帐 xff0c 并归还篮子 xff08 出 入口仅容一人通过 xff09 请试用P xff08 S xff
  • Windows-取消锁屏密码

    开始 gt 设置 gt 账户 gt 登录选项 gt 密码 gt 输入当前密码 gt 更改密码 xff08 默认为空就行 xff09 gt 下一步 gt 完成
  • 腾讯云4核服务器和2核区别大吗?性能差异

    腾讯云服务器2核和4核性能有什么区别 xff1f 云服务器核数指的是vCPU处理器 xff0c 云服务器CPU核心数如何选择主要取决于用户实际应用情况 xff0c 如果当前应用对CPU计算能力要求不高 xff0c 2核完全可以胜任 xff0
  • 最详细的手工LAMP环境搭建

    环境 xff1a 阿里云服务器ECS xff0c Alibaba Cloud Linux 3 2104 LTS 64位 xff0c 2核 vCPU 2 GiB LAMP 是搭建Web应用时最常用的环境 xff0c LAMP 分别表示 Lin
  • python 语音播报 简单入门

    coding utf 8 import pyttsx3 import time 初始化 pt 61 pyttsx3 init 说什么 pt say 34 你好 xff0c dbirder 34 开始说吧 pt runAndWait time
  • 【optimizer详解】

    optimizer 定义 optimizer就是在深度学习反向传播过程中 xff0c 指引损失函数 xff08 目标函数 xff09 的各个参数往正确的方向更新合适的大小 xff0c 使得更新后的各个参数让损失函数 xff08 目标函数 x