手撕深度学习中的优化器

这篇具有很好参考价值的文章主要介绍了手撕深度学习中的优化器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

Gradient descent in deep learning

手撕深度学习中的优化器

Optimizer

class Optimizer:
    """
    优化器基类,默认是L2正则化
    """

    def __init__(self, lr, weight_decay):
        self.lr = lr
        self.weight_decay = weight_decay

    def step(self, grads, params):
        # 计算当前时刻下降的步长
        decrement = self.compute_step(grads)
        if self.weight_decay:
            decrement += self.weight_decay * params
        # 更新参数
        params -= decrement

    def compute_step(self, grads):
        raise NotImplementedError

SGD

随机梯度下降
θ t = θ − η ⋅ g t \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 + g t θ 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 = momentum
        self.beta = 0

    def compute_step(self, grads):
        self.beta = self.momentum * self.beta + (1 - self.momentum) * grads
        return self.lr * self.beta

Adagrad

θ t = θ t − 1 − η ∑ i = 0 t − 1 ( g i ) 2 g t − 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 the
    root-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 = eps
        self.state_sum = 0

    def compute_step(self, grads):
        self.state_sum += grads ** 2
        decrement = grads / (self.state_sum ** 0.5 + self.eps) * self.lr
        return decrement

RMSProp

指数滑动平均更新梯度的平方,为解决Adagrad 梯度急剧下降而提出
υ 1 = g 0 2 υ t = α υ t − 1 + ( 1 − α ) ( g t − 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 − η υ t g t − 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 = eps
        self.alpha = alhpa
        self.state_sum = 0

    def compute_step(self, grads):
        self.state_sum = self.alpha * self.state_sum + (1 - self.alpha) * grads ** 2
        decrement = grads / (self.state_sum ** 0.5 + self.eps) * self.lr
        return decrement

Adam

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

  • SGDm

θ t = θ t − 1 − m t m t = β 1 m t − 1 + ( 1 − β 1 ) g t − 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 − η υ t g t − 1 \theta_t=\theta_{t-1} - \frac{\eta}{\sqrt{\upsilon_t}} g_{t-1} θt=θt1υt ηgt1

υ 1 = g 0 2 υ t = β 2 υ t − 1 + ( 1 − β 2 ) ( g t − 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 ′ + ε m t ′ \theta_t = \theta_{t-1} - \frac{\eta}{\sqrt{\upsilon_t'+\varepsilon}} m_t' θt=θt1υt+ε ηmt

m t ′ = m t 1 − β 1 t v t ′ = v t 1 − β 2 t β 1 = 0.9 β 2 = 0.999 m_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 = eps
        self.beta1, self.beta2 = betas
        self.mt = self.vt = 0
        self._t = 0

    def compute_step(self, grads):
        self._t += 1
        self.mt = self.beta1 * self.mt + (1 - self.beta1) * grads
        self.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.lr
        return decrement

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


参考资料:

torch.optim — PyTorch documentation
tinynn: A lightweight deep learning library 文章来源地址https://www.toymoban.com/news/detail-408385.html

到了这里,关于手撕深度学习中的优化器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度学习HashMap之手撕HashMap

    HashMap其实是数据结构中的哈希表在Java里的实现。 哈希表也叫散列表,我们先来看看哈希表的定义: 哈希表是根据关键码的值而直接进行访问的数据结构。 简单说来说 ,哈希表由两个要素构成: 桶数组 和 散列函数 。 我们可能知道,有一类基础的数据结构线性表,而线性

    2024年02月09日
    浏览(52)
  • 机器学习策略——优化深度学习系统

    老式电视机,有很多旋钮可以用来调整图像的各种性质,对于这些旧式电视,可能有一个旋钮用来调图像垂直方向的高度,另外有一个旋钮用来调图像宽度,也许还有一个旋钮用来调梯形角度,还有一个旋钮用来调整图像左右偏移,还有一个旋钮用来调图像旋转角度之类的。

    2024年02月10日
    浏览(39)
  • 《动手学深度学习》优化算法学习&习题

    小批量随机梯度下降,通过平均梯度来减小方差 基础 泄露平均法:用来取代梯度的计算 β beta β 这个参数控制了取多久时间的平均值 上述推理构成了”加速”梯度方法的基础,例如具有动量的梯度。 在优化问题条件不佳的情况下(例如,有些方向的进展比其他方向慢得多

    2024年02月13日
    浏览(36)
  • 机器学习策略二——优化深度学习系统

    如果你希望让学习算法能够胜任人类能做的任务,但你的学习算法还没有达到人类的表现,那么人工检查一下你的算法犯的错误也许可以让你了解接下来应该做什么。这个过程称为错误分析。 假设你正在调试猫分类器,然后你取得了90%准确率,相当于10%错误,在你的开发集上

    2024年02月09日
    浏览(34)
  • PyTorch深度学习实战(9)——学习率优化

    学习率( learning rate )是神经网络训练中一个重要的超参数,用于控制模型更新参数的步长大小,它决定了每次迭代中模型参数更新的幅度。学习率的选择对于训练的结果具有重要影响,学习率过高会导致模型震荡不收敛甚至发散,无法有效优化目标函数;而学习率过低则会导

    2024年02月14日
    浏览(34)
  • 深度学习优化算法相关文章

    综述性文章 一个框架看懂优化算法之异同 SGD/AdaGrad/Adam 从 SGD 到 Adam —— 深度学习优化算法概览(一)

    2024年02月10日
    浏览(36)
  • 【深度学习】优化器详解

    深度学习模型通过引入损失函数,用来计算目标预测的错误程度。根据损失函数计算得到的误差结果,需要对模型参数(即权重和偏差)进行很小的更改,以期减少预测错误。但问题是如何知道何时应更改参数,如果要更改参数,应更改多少?这就是引入优化器的时候了。简

    2024年02月06日
    浏览(26)
  • 深度学习优化算法

    优化算法 要训练一个好的 CNN 模型,通常需要很多训练数据,尤其是模型结构比较复杂的时候, 比如 ImageNet 数据集上训练的模型。虽然深度学习在 ImageNet 上取得了巨大成功,但是一个 现实的问题是,很多应用的训练集是较小的,如何在这种情况下应用深度学习呢?有三种方

    2024年02月19日
    浏览(42)
  • 深度学习——优化器Optimizer

    2024年02月16日
    浏览(39)
  • 机器学习&&深度学习——随机梯度下降算法(及其优化)

    在我们没有办法得到解析解的时候,我们可以用过梯度下降来进行优化,这种方法几乎可以所有深度学习模型。 关于优化的东西,我自己曾经研究过智能排班算法和优化,所以关于如何找局部最小值,以及如何跳出局部最小值的一些基本思想是有感触的,随机梯度算法和其优

    2024年02月15日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包