手撕深度学习中的优化器

news/2024/11/30 0:40:16/

深度学习中的优化算法采用的原理是梯度下降法,选取适当的初值params,不断迭代,进行目标函数的极小化,直到收敛。由于负梯度方向时使函数值下降最快的方向,在迭代的每一步,以负梯度方向更新params的值,从而达到减少函数值的目的。

Gradient descent in deep learning

在这里插入图片描述

Optimizer

class Optimizer:"""优化器基类,默认是L2正则化"""def __init__(self, lr, weight_decay):self.lr = lrself.weight_decay = weight_decaydef step(self, grads, params):# 计算当前时刻下降的步长decrement = self.compute_step(grads)if self.weight_decay:decrement += self.weight_decay * params# 更新参数params -= decrementdef compute_step(self, grads):raise NotImplementedError

SGD

随机梯度下降
θt=θ−η⋅gt\theta_t = \theta-\eta \cdot g_t θt=θηgt

  • 每次随机抽取一个batch的样本进行梯度下降

  • 对学习率敏感,太小收敛速度很慢,太大会在极小值附近震荡

  • 对于非凸函数,容易陷入局部最小值或鞍点

class SGD(Optimizer):"""stochastic gradient descent"""def __init__(self, lr=0.1, weight_decay=0.0):super().__init__(lr, weight_decay)def compute_step(self, grads):return self.lr * grads

SGDm

SGD中加入动量(momentum)模拟是物体运动时的惯性,即更新的时候在一定程度上保留之前更新的方向,同时利用当前batch的梯度微调最终的更新方向。这样一来,可以在一定程度上增加稳定性,从而学习地更快,并且还有一定摆脱局部最优的能力。
υt=γυt−1+gtθt=θt−1−ηυt\upsilon_t = \gamma \upsilon_{t-1} + g_t \qquad \theta_t=\theta_{t-1} - \eta \upsilon_t υt=γυt1+gtθt=θt1ηυt

  • gt是当前时刻的梯度,vt是当前时刻参数的下降距离
  • 带动量的小球滚下山坡,可能会错过山谷
class SGDm(Optimizer):"""stochastic gradient descent with momentum"""def __init__(self, lr=0.1, momentum=0.9, weight_decay=0.0):super().__init__(lr, weight_decay)self.momentum = momentumself.beta = 0def compute_step(self, grads):self.beta = self.momentum * self.beta + (1 - self.momentum) * gradsreturn self.lr * self.beta

Adagrad

θt=θt−1−η∑i=0t−1(gi)2gt−1\theta_t=\theta_{t-1} - \frac{\eta}{\sqrt{\sum^{t-1}_{i=0}{(g_i)^2}}}g_{t-1} θt=θt1i=0t1(gi)2ηgt1

  • 自适应调节学习率
  • 对低频的参数做较大的更新,对高频的做较小的更新,也因此,对于稀疏的数据它的表现很好,很好地提高了 SGD 的鲁棒性
  • 缺点是分母梯度的累积,最后梯度消失
class Adagrad(Optimizer):"""Divide the learning rate of each parameter by theroot-mean-square of its previous derivatives"""def __init__(self, lr=0.1, eps=1e-8, weight_decay=0.0):super().__init__(lr, weight_decay)self.eps = epsself.state_sum = 0def compute_step(self, grads):self.state_sum += grads ** 2decrement = grads / (self.state_sum ** 0.5 + self.eps) * self.lrreturn decrement

RMSProp

指数滑动平均更新梯度的平方,为解决Adagrad 梯度急剧下降而提出
υ1=g02υt=αυt−1+(1−α)(gt−1)2\upsilon_1 = g_0^2 \qquad \upsilon_t = \alpha\upsilon_{t-1} + (1-\alpha)(g_{t-1})^2 υ1=g02υt=αυt1+(1α)(gt1)2

θt=θt−1−ηυtgt−1\theta_t=\theta_{t-1} - \frac{\eta}{\sqrt{\upsilon_t}} g_{t-1} θt=θt1υtηgt1

class RMSProp(Optimizer):"""Root Mean Square Prop optimizer"""def __init__(self, lr=0.1, alhpa=0.99, eps=1e-8, weight_decay=0.0):super().__init__(lr, weight_decay)self.eps = epsself.alpha = alhpaself.state_sum = 0def compute_step(self, grads):self.state_sum = self.alpha * self.state_sum + (1 - self.alpha) * grads ** 2decrement = grads / (self.state_sum ** 0.5 + self.eps) * self.lrreturn decrement

Adam

SGDmRMSProp的结合,Adam 算法通过计算梯度的一阶矩估计和二阶矩估计而为不同的参数设计独立的自适应性学习率。

  • SGDm

θt=θt−1−mtmt=β1mt−1+(1−β1)gt−1\theta_t=\theta_{t-1} - m_t \qquad m_t = \beta_1 m_{t-1} + (1-\beta_1)g_{t-1} θt=θt1mtmt=β1mt1+(1β1)gt1

  • RMSProp

θt=θt−1−ηυtgt−1\theta_t=\theta_{t-1} - \frac{\eta}{\sqrt{\upsilon_t}} g_{t-1} θt=θt1υtηgt1

υ1=g02υt=β2υt−1+(1−β2)(gt−1)2\upsilon_1 = g_0^2 \qquad \upsilon_t = \beta_2\upsilon_{t-1} + (1-\beta_2)(g_{t-1})^2 υ1=g02υt=β2υt1+(1β2)(gt1)2

  • Adam

θt=θt−1−ηυt′+εmt′\theta_t = \theta_{t-1} - \frac{\eta}{\sqrt{\upsilon_t'+\varepsilon}} m_t' θt=θt1υt+εηmt

mt′=mt1−β1tvt′=vt1−β2tβ1=0.9β2=0.999m_t' = \frac{m_t}{1-\beta_1^t} \qquad v_t' = \frac{v_t}{1-\beta_2^t} \qquad \beta_1=0.9 \quad \beta_2=0.999 mt=1β1tmtvt=1β2tvtβ1=0.9β2=0.999

class Adam(Optimizer):"""combination of SGDm and RMSProp"""def __init__(self, lr=0.1, betas=(0.9, 0.999), eps=1e-8, weight_decay=0.0):super().__init__(lr, weight_decay)self.eps = epsself.beta1, self.beta2 = betasself.mt = self.vt = 0self._t = 0def compute_step(self, grads):self._t += 1self.mt = self.beta1 * self.mt + (1 - self.beta1) * gradsself.vt = self.beta2 * self.vt + (1 - self.beta2) * (grads ** 2)mt = self.mt / (1 - self.beta1 ** self._t)vt = self.vt / (1 - self.beta2 ** self._t)decrement = mt / (vt ** 0.5 + self.eps) * self.lrreturn decrement

我平时做视觉任务主要用SGDm和Adam两个优化器,感觉带正则化的SGDm的效果非常好,然后调一下学习率和衰减策略


参考资料:

torch.optim — PyTorch documentation
tinynn: A lightweight deep learning library


http://www.ppmy.cn/news/41656.html

相关文章

竞赛无人机搭积木式编程——以2022年TI电赛送货无人机一等奖复现为例学习(7月B题)

在学习本教程前,请确保已经学习了前4讲中无人机相关坐标系知识、基础飞行控制函数、激光雷达SLAM定位条件下的室内定点控制、自动飞行支持函数、导航控制函数等入门阶段的先导教程。 同时用户在做二次开发自定义的飞行任务时,可以参照第5讲中2021年国赛植…

编程的核心目的:计算数据

编程的核心目的是通过程序设计实现对数据的计算。计算数据涉及到对数据的获取、变量类型的定义、算术和逻辑运算、条件和循环控制等广泛的计算机科学概念和技术。 对数据的获取可以通过硬编码、用户输入等方式实现。变量类型的定义则是程序中的数据类型、这些类型确保数据的安…

【软考备战·希赛网每日一练】2023年4月10日

文章目录一、今日成绩二、错题总结第一题第二题三、知识查缺题目及解析来源:2023年04月10日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析: 本题属于专业英语,大体了解意思即可。 题目大意: 第二题 解析&#xff1a…

java面试题-基础问题-如何理解Java中的多态?

如何理解Java中的多态?如何理解Java中的多态?典型回答扩展知识方法的重载与重写重载和重写的区别如何理解Java中的多态? 典型回答 多态的概念比较简单,就是同一操作作用于不同的对象,可以有不同的解释,产…

哪个网站的电子书最多?

程序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store 随便找一个电子书导航,就会给你提供几十个电子书下载网站。 然而,当真正用到时会发现,质量层次不齐,在绝大多数时候试遍几十个网站都找不到自己想要的书…

分享初用Jmeter时可能遇到的一些问题

很多朋友在刚刚接触jmeter的时候会遇到各种各样感觉稀奇古怪的问题,明明请求对了却总是返回不如意的结果,jmeter功能强大,但没有postman那样的界面简洁易上手的特性,本文分享在最初接触jmeter时有可能会遇到的问题,让各…

MySQL架构

文章目录前言MySQL的架构1.连接层2.查询分析器3.优化器4.执行引擎5.存储引擎总结前言 MySQL是一个非常流行的关系型数据库管理系统,具有很好的可靠性和性能。然而,由于MySQL是一个多用户系统,因此必须使用并发控制来处理多个用户之间的并发访…

ROS系统的相关命令+订阅发布代码

1.5.2 ROS文件系统相关命令 1.增 catkin_create_pkg 自定义包名 依赖包 创建新的ROS功能包sudo apt install xxx 安装 ROS功能包2.删 sudo apt purge xxx 删除某个功能包3.查 rospack list 列出所有功能包rospack find 包名 查找某个功能包是否存在,如果存…