神经网络参数最优化的方法(SGD、Momentum、AdaGrad、Adam)

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

神经网络的学习的目的就是找到合适的参数使损失函数的值尽可能的小。这种寻找最优参数的过程就叫做最优化(optimization)。然而在深度神经网络中,参数的数量非常庞大,导致最优化的问题非常复杂。下面介绍四种常见的最优化的方法,并通过一个例子进行比较。

1. SGD(stochastic gradient descent)

SGD即随机梯度下降法,这个方法通过梯度下降法更新参数,不过因为这里使用的数据是随机选择的min batch数据,所以称为随机梯度下降法。这里的“随机”指的是“随机选择的”的意思,因此随机梯度下降法是“对随机选择的数据进行的梯度下降法”。用数学式表示为:

                                                             W\leftarrow W-\eta \frac{\partial L}{\partial W}

这里把需要更新的权重参数记为W,把损失函数关于W的梯度记为\frac{\partial L}{\partial W}\eta表示学习率,实际上会取0.001或0.0001这些事先决定好的值。这个式子表示,SGD是朝着梯度方向前进一小步的简单方法。现在将SGD实现为一个python类。

class SGD:
    def __init__(self,  lr=0.01):
        self.lr = lr

    def update(self, params, grads):
        for key in params.keys():
            params[key] -= self.lr * grads[key]

2. Momentum

Momentum是“动量”的意思,和物理有关。用数学式表示如下:

                                                     v\leftarrow \alpha v-\eta \frac{\partial L}{\partial W}

                                                     W\leftarrow W+v

       和前面SGD一样,W表示要更新的权重参数,\frac{\partial L}{\partial W}表示损失函数关于W的梯度,\eta表示学习率。这里新出现了一个变量v,对应物理上的速度。第一个式子表示物体在梯度方向上受力,在这个力的作用下,物体的速度增加这一法则。\alpha v表示物理在不受任何力时,该项承担使物体逐渐减速的任务(\alpha设定为0.9之类的值),对应物理上的地面摩擦力或空气阻力。Momentum方法给人的感觉就像是小球在地面上滚动。

下面是Momentum代码实现:

class Momentum:
    def __init__(self, lr=0.01, momentum=0.9):
        self.lr = lr
        self.momentum = momentum
        self.v = None
        
    def update(self, params, grads):
        if self.v is None:
            self.v = {}
            for key, val in params.items():
                self.v[key] = np.zeros_like(val)
                
        for key in params.keys():
            self.v[key] = self.momentum * self.v[key] - self.lr * grads[key]
            params[key] += self.v[key]

实例变量v会保存物体的速度。初始化时,v中什么都不保存,但当第一次调用update()时,v会以字典型变量的形式保存与参数结构相同的数据。

3. AdaGrad

    在神经网络的学习中,学习率(数学式中记为\eta)的值很重要。学习率过小,会导致学习花费过多时间;学习率过大,则会导致学习发散而不能正确进行。

    在关于学习率的有效技巧中,有一种被称为学习率衰减(learning rate decay)的方法,即随着学习的进行,使学习率逐渐减小。实际上,一开始“多”学,然后逐渐“少”学的方法,在神经网络的学习中经常被使用。

    逐渐减少学习率的想法,相当于将“全体”参数的学习率值一起降低。而AdaGrad进一步发展了这个想法,针对“一个一个”参数,赋予其“定制” 的值。用数学式表示:

                                                               h\leftarrow h+\frac{\partial L}{\partial W}\odot \frac{\partial L}{\partial W}

                                                               W\leftarrow W-\eta \frac{1}{\sqrt{h}}\frac{\partial L}{\partial W}

    和前面SGD一样,W表示要更新的权重参数,\frac{\partial L}{\partial W}表示损失函数关于W的梯度,\eta表示学习率。这里新出现了一个变量h,它保存了以前的所有梯度值的平方和(\odot表示对应矩阵元素的乘法)。然后在更新参数时,通过乘以\frac{1}{\sqrt{h}},就可以调整学习的尺度。这意味着,参数的元素中变动较大(被大幅更新)的元素的学习率将变小。也就是说,可以按参数的元素进行学习率衰减,使变动大的参数的学习率逐渐减小。

    现在来实现AdaGrad:

class AdaGrad:
    def __init__(self, lr=0.01):
        self.lr = lr 
        self.h = None
        
    def update(self, params, grads):
        if self.h is None:
            self.h = {}
            for key, val in params.items():
                self.h[key] = np.zeros_like(val)
                
        for key in params.keys():
            self.h[key] += grads[key] * grads[key]
            params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)

这里需要注意的是,最后加上的1e-7是为了防止self.h[key]中有0时,将0用作除数的情况。在很多深度学习框架中,这个微小值也可以设定为参数,但这里我们用的是1e-7这个固定值。

    拓展:AdaGrad会记录过去所有梯度的平方和。因此,学习越深入,更新的幅度越小。实际上,如果无止境的学习,更新量就会变成0,完全不再更新。为了改善这个问题,可以使用RMSProp方法。RMSProp方法不是将过去的所有梯度一视同仁的相加,而是逐渐遗忘过去的梯度,在做加法运算时将新的梯度信息更多的反映出来。这种操作从专业上讲,称为“指数移动平均”,呈指数函数式地减小过去的梯度的尺度。

4. Adam

    Momentum参照小球在碗中滚动的物理规则进行移动,AdaGrad为参数的每个元素适当的调整更新步伐。Adam就是将这两个方法融合在一起。这只是一个直观的说明,并不完全正确,详细内容可以参考作者的论文。Diederik Kingma and Jimmy Ba. Adam: A Method for Stochastic Optimization.

class Adam:
    def __init__(self, lr=0.001, beta1=0.9, beta2=0.999):
        self.lr = lr
        self.beta1 = beta1
        self.beta2 = beta2
        self.iter = 0
        self.m = None
        self.v = None

    def update(self, params, grads):
        if self.m is None:
            self.m, self.v = {}, {}
            for key, val in params.items():
                self.m[key] = np.zeros_like(val)
                self.v[key] = np.zeros_like(val)

        self.iter += 1
        lr_t = self.lr * np.sqrt(1.0 - self.beta2 ** self.iter) / (1.0 - self.beta1 ** self.iter)

        for key in params.keys():
            self.m[key] += (1 - self.beta1) * (grads[key] - self.m[key])
            self.v[key] += (1 - self.beta2) * (grads[key] ** 2 - self.v[key])

            params[key] -= lr_t * self.m[key] / (np.sqrt(self.v[key]) + 1e-7)

 

 

例:下面用这个四种方法寻找f(x,y) = \frac{1}{20}x^{2}+y^{2}的最小值点。

从(x,y)=(-7.0,2.0)的位置开始搜索,用导数法求梯度,\frac{\partial f}{\partial x}=\frac{1}{10}x\frac{\partial f}{\partial y} = 2y

具体代码如下:

import numpy as np
import matplotlib.pyplot as plt
from collections import OrderedDict
from ch06.optimizer import *

# 原函数
def f(x, y):
    return x ** 2 / 20.0 + y ** 2

# 求梯度
def df(x, y):
    return x / 10.0, 2.0 * y


init_pos = (-7.0, 2.0)   # 初始点
params = {}
params['x'], params['y'] = init_pos[0], init_pos[1]
grads = {}
grads['x'], grads['y'] = 0, 0

optimizers = OrderedDict()
optimizers["SGD"] = SGD(lr=0.95)
optimizers["Momentum"] = Momentum(lr=0.1)
optimizers["AdaGrad"] = AdaGrad(lr=1.5)
optimizers["Adam"] = Adam(lr=0.3)

idx = 1

for key in optimizers:
    optimizer = optimizers[key]
    x_history = []
    y_history = []
    params['x'], params['y'] = init_pos[0], init_pos[1]

    for i in range(30):
        x_history.append(params['x'])
        y_history.append(params['y'])

        grads['x'], grads['y'] = df(params['x'], params['y'])
        optimizer.update(params, grads)

    x = np.arange(-10, 10, 0.01)
    y = np.arange(-5, 5, 0.01)

    X, Y = np.meshgrid(x, y)  # 生成网格点坐标矩阵
    Z = f(X, Y)

    # for simple contour line
    mask = Z > 7
    Z[mask] = 0

    # plot
    plt.subplot(2, 2, idx)
    idx += 1
    plt.plot(x_history, y_history, 'o-', color="red")
    plt.contour(X, Y, Z)
    plt.ylim(-10, 10)
    plt.xlim(-10, 10)
    plt.plot(0, 0, '+')
    # colorbar()
    # spring()
    plt.title(key)
    plt.xlabel("x")
    plt.ylabel("y")

plt.show()

运行结果:

                                   

    到目前为止,介绍了4种最优化的方法,那么哪种方法好呢。其实并不存在能在所有问题中表现都好的方法。这4种方法各有各的特点,都有各自擅长的领域。目前用的比较多的就是SGD和Adam.

深度学习入门之SGD随机梯度下降法 SGD SGD为随机梯度下降法。用数学式可以将 SGD 写成如下的式(6.1)。 这里把需要更新的权重参数记为W,把损失函数关于W的梯度记为∂L/∂W 。η 表示学习率,实际上会取 0.01 或 0.001 这些事先决定好的值。式子中的←表示用右边的值更新左边的值。如式(6.1)所示,SGD 是朝着梯度方向只前进一定距离的简单方法。现在,我们将 SGD 实现为一个 Python 类(为方便后面使用,我们将其实现为一个名为 SGD 的类)。 class SGD: def __init__(self, 阅读详情

相关推荐

随机梯度下降法 (SGD)

SGD的基本思想是通过逐个样本或小批量样本来更新模型参数,而不是使用整个数据集。这种方法大大提高了计算效率,特别是在处理大规模数据集时。

We1ky的博客 8425

SGD简介

给你一个xyxyxy坐标系,上面有一些点,给你过原点的一条直线ywxy=wxywx,如何用最快的方法来拟合这些点?为了解决这个问题,我们要对问题定义一个目标,即让所有的点离直线的偏差最小。我们常用的误差函数为均方误差,对于一个点p1p_1p1​来说,它与直线的均方误差可以定义为e1e_1e1​e1y1−wx12wx1−y12e1​y1​−wx1​2wx1​−y1​2e1w2x1。

qq_55126913的博客 1万+

SGD+Momentum:提速优化的强力组合

SGD+Momentum算法通过结合SGDMomentum的优点,能够更快地收敛、避免局部极小值,并提高深度学习模型的性能。在深度学习领域的各个任务和模型中,SGD+Momentum已被广泛应用,并取得了良好的优化效果。SGD+Momentum(随机梯度下降+动量法)是一种强大的优化算法组合,它结合了SGD的简单性和Momentum的收敛速度,:SGD+Momentum通过引入动量项,使更新方向在梯度变化较大的维度上具有一定的惯性,从而加速收敛并提高性能。SGD+Momentum是一种优化算法的组合。

m0_70911440的博客 2165

SGD优化器Momentum的理解

一、介绍     在深度学习中,Momentum(动量)优化算法是对梯度下降法的一种优化, 它在原理上模拟了物理学中的动量,已成为目前非常流行的深度学习优化算法之一。在介绍动量优化算法前,需要对 指数加权平均法 有所了解,它是动量优化算法的理论基础,可参见本人另外一篇博文:深度学习: 指数加权平均。 物理学中动量的定义: 设物体的质量为 ,速度为...

weixin_43120290的博客 8530

十九: 深度学习技巧() -- 参数更新

深度学习中参数更新技巧

Waruler的博客 1102

【深度学习】5-1 与学习相关的技巧 - 参数更新MomentumAdaGrad, Adam

神经网络的学习的目的是找到使损失函数的值尽可能小的参数。这是寻找最优参数的问题,解决这个问题的过程称为。但是神经网络最优化问题非常难。这是因为参数空间非常复杂,无法轻易找到最优解。而且,在深度神经网络中,参数的数量非常庞大,导致最优化问题更加复杂。

loyd3的博客 2281

AI-02a5a4.神经网络-与学习相关的技巧-参数更新

以 手 写 数 字 识 别 为 例,比 较 前 面 介 绍 的 SGDMomentumAdaGradAdam这4种方法,并确认不同的方法在学习进展上有多大程度的差异。一个5层神经网络为对象,其中每层有100个神经元。激活函数使用的是ReLU。结果如下图所示,算法梯度计算方式学习率调整机制核心优势SGD当前梯度固定学习率简单直观,适合凸优化问题动量法当前梯度 + 历史梯度累积固定学习率加速收敛,缓解震荡RMSProp当前梯度基于历史梯度平方自适应调整。

Little_fxc的博客 947

第五章.与学习相关技巧—参数更新最优化方法SGD,Momentum,AdaGrad,Adam

第五章.与学习相关技巧—参数更新最优化方法SGD,Momentum,AdaGrad,Adam

weixin_45116749的博客 1245

深度学习入门(四):与学习相关的技巧

与学习相关的技巧 本章介绍的方法,可以高效地进行神经网络(深度学习)的学习,提高识别精度 参数更新 神经网络的学习的目的是找到使损失函数的值尽可能小的参数。这是寻找最优参数的问题,解决这个问题的过程称为最优化。 在前几章中。为了找到最优参数,我们将参数的梯度作为线索,使用参数的梯度,沿梯度方向更新参数,并重复这个步骤若干次,从而靠近最优参数。这个过程称为SGD 随机梯度下降法。 代码 SGD class SGD: def __init__(self, lr = 0.01): self.lr = lr

weixin_46013817的博客 370

gitchat训练营15天共度深度学习入门课程笔记()

第6章 与学习相关的技巧6.1 学习过程中参数更新最优化方法6.1.2 SGD1. SGD的实现2. SGD 的缺点6.1.4 Momentum1. Momentum公式2. Momentum的实现6.1.5 AdaGrad1. AdaGrad的公式2. AdaGrad的实现6.1.6 Adam1. Adam的特点2. Adam的实现6.1.8 基于 MNIST 数据集的更新方法的比较6...

weixin_43114885的博客 459

与“学习”相关的优化技巧

1、参数更新最优化即解决寻找最优参数的问题,神经网络进行最优化比较困难是因为参数空间非常复杂,无法轻易找到最优解。为了寻找最优参数,将参数梯度作为线索,使用参数梯度沿着梯度方向更新,并不断重复直至逐渐靠近最优参数的过程称为随机梯度下降法SGD,除此之外还有其他最优化方法。 2、随机梯度下降法SGD:把需要更新参数记为W,把损失函数关于W的梯度记为偏导,η表示学习率,用右边的值来更新左边的值朝着梯度方向前进一定距离。 class SGD: def __init__(self,lr=0.01):

Hello World 341

关于卷积神经网络(CNN)的深入理解与代码实现

卷积神经网络卷积神经网络其实是做互相关运算,和概率论里面的卷积公式不是一个东西。理论就不过多介绍了,记住卷积神经网络是用于图像处理的,并且接受的输入不再是机器学习或者多层感知机里面的二维输入,由于图片本身就是二维数据了,再加上样本的个数这个维度,图片起码都是三维数据,并且考虑颜色通道不一样,四维的数据也很常见。

DJJ5210的博客 573

第五章与学习(训练网络)相关的技巧

前面已经系统了解了神经网络的工作原理,但是还有一些需要了解的其他细节点,本章将会学习除了梯度下降的其他权重最优化方法,权重初始值设定,超参数设定和过拟合处理方法等四个模块等内容。

weixin_45256637的博客 336

【笔记】深度学习入门:基于Python的理论与实现(四)

本章主题涉及寻找最优权重参数最优化方法、权重参数的初始值、超参数的设定方法等。此外,为了应对过拟合,本章还将介绍权值衰减、Dropout 等正则化方法,并进行实现。最后将对近年来众多研究中使用的Batch Normalization方法进行简单的介绍。

小賀のBlog 1070

深度学习入门-ANN神经网络参数最优化问题(SGD,Momentum,AdaGrad,RMSprop,Adam)

SGD随机梯度下降法,Momentum动量法,AdaGrad,RMSprop指数加权/移动平均,Adam神经网络参数更新优化方法

泥签的博客 3886

SGDMomentumAdaGradAdam

目录 1.SGD 1.1 SGD的缺点 2. Momentum 3. AdaGrad 4. Adam 5 使用哪种更新方法神经网络的学习的目的是找到使损失函数的值尽可能小的参数。这是寻找最优参数的问题,解决这个问题的过程称为最优化(optimization)。遗憾的是,神经网络最优化问题非常难。 为了找到最优参数,我们将参数的梯度(导数)作为了线索。使用参数的梯度,沿梯度方向更新参数,并重复这个步骤多次,从而逐渐靠近最优参数,这个过程称为随机梯度下降法(stochastic gradie

A496608119的博客 2396

神经网络(深度学习)常用的4种最优化方法——SGDMomentumAdaGradAdam

一、SGD 描述 随机梯度下降法(stochastic gradient descent),策略是朝着当前所在位置的坡度最大的方向前进。 数学式 Python类 class SGD: def __init__(self, lr=0.01): self.lr = lr def update(self, params, grads): for key in params...

黄大堂 8601

DL之DNN优化技术:DNN优化器参数优化—更新参数的四种最优化方法(SGD/Momentum/AdaGrad/Adam)的案例理解、图表可视化比较

DL之DNN优化技术:DNN优化器参数优化—更新参数的四种最优化方法(SGD/Momentum/AdaGrad/Adam)的案例理解、图表可视化比较 目录 四种最优化方法简介 优化器案例理解 输出结果 设计思路 核心代码 四种最优化方法简介 DL之DNN优化技术:神经网络算法简介之GD/SGD算法(BP算法)的简介、理解、代码实现、SGD缺点及改进(...

头部AI社区如有邀博主AI主题演讲请私信—心比天高,仗剑走天涯,保持热爱,奔赴向梦想!低调,专注,谦虚,自律,反思,成长,还算比较正能量的博主,公益免费传播…内心特别想在AI界做出一些可以推进历史进程影响力的技术(兴趣使然,有点小情怀,也有点使命感呀 9972

NN学习技巧之参数最优化的四种方法对比(SGD, Momentum, AdaGrad, Adam),基于MNIST数据集

前面几篇博文分析了每一种参数优化方案,现在做一个对比,代码参考斋藤的红鱼书第六章。 实验对mnist数据集的6万张图片训练,使用5层全连接神经网络(4个隐藏层,每个隐藏层有100个神经元),共迭代2000次,下图是损失函数随着训练迭代次数的变化: 可以看到SGD是最慢的,而AdaGrad最快, 且最终的识别精度也更高,这并不是一定的,跟数据也有关 主要代码:(完整代码可去图灵社区找红鱼书,随书下...

wulimmya的博客 2038
上一篇: 经典损失函数——均方误差(MSE)和交叉熵误差(CEE)的python实现
下一篇: 四种抑制过拟合的方法
Answerlzd
博客等级 码龄9年 67粉丝 119原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值