深度学习:PyTorch人工神经网络优化方法分享(1)

本文目录:

  • 一、从梯度角度入手
    • (一)梯度下降算法回顾
    • (二)常用优化算法
      • 1.SGD(Stochastic Gradient Descent)- 随机梯度下降
      • 2.BGD (Batch Gradient Descent) - 批量梯度下降
      • 3.MBGD (Mini-Batch Gradient Descent) - 小批量梯度下降
    • (三)梯度优化算法的不足与革新
      • 1.指数加权平均
      • 2.动量算法(Momentum)
      • 3.动量法(Momentum)有效克服 “平缓”、”鞍点”、”峡谷” 的问题
  • 二、从自适应学习率角度入手
    • (一)自适应梯度算法(AdaGrad)
      • 1.概念
      • 2.更新过程
    • (二)RMSProp优化算法
      • 1.概念
      • 2.更新过程
  • 三、自适应矩估计(Adam)
    • (一)概念
    • (二)Adam的更新过程
  • 附赠:
    • 1.BGD/SGD/MBGD三种梯度优化方法对比
    • 2.普通SGD与动量法(Momentum)的对比
    • 3.AdaGrad、RMSProp、Adam 优缺点对比

前言:前面讲述了PyTorch人工神经网络的激活函数、损失函数等内容,今天讲解优化方法。

简单来说,优化方法主要是从两个角度来入手,一个是梯度,一个是学习率

一、从梯度角度入手

(一)梯度下降算法回顾

梯度下降法简单来说就是一种寻找使损失函数最小化的方法**。

从数学角度来看,梯度的方向是函数增长速度最快的方向,那么梯度的反方向就是函数减少最快的方向,所以有:

在这里插入图片描述
其中,η是学习率,如果学习率太小,那么每次训练之后得到的效果都太小,增大训练的时间成本。如果,学习率太大,那就有可能直接跳过最优解,进入无限的训练中。解决的方法就是,学习率也需要随着训练的进行而变化。

(二)常用优化算法

在梯度角度优化算法中,SGD(随机梯度下降)、BGD(批量梯度下降) 和 SBGD(小批量梯度下降) 是三种基础但核心的优化方法,而它们的区别主要在于 每次参数更新时使用的数据量。

1.SGD(Stochastic Gradient Descent)- 随机梯度下降

在这里插入图片描述
PyTorch代码实现:将batch_size设为1:

train_loader = DataLoader(dataset, batch_size=1, shuffle=True)  # 逐样本加载

2.BGD (Batch Gradient Descent) - 批量梯度下降

在这里插入图片描述
PyTorch代码实现:直接对整个数据集计算平均梯度

for epoch in range(epochs):optimizer.zero_grad()outputs = model(train_inputs)  # 全量数据loss = criterion(outputs, train_labels)loss.backward()  # 计算全量梯度optimizer.step()

3.MBGD (Mini-Batch Gradient Descent) - 小批量梯度下降

在这里插入图片描述
PyTorch代码实现:设置合适的batch_size

train_loader = DataLoader(dataset, batch_size=64, shuffle=True)  # 小批量加载

(三)梯度优化算法的不足与革新

梯度下降优化算法中,可能会碰到以下情况:
在这里插入图片描述

  • 碰到平缓区域,梯度值较小,参数优化变慢;
  • 碰到 “鞍点” ,梯度为0,参数无法优化;
  • 碰到局部最小值,参数不是最优。

对于这些问题, 出现了一些对梯度下降算法的优化方法,例如:动量法

动量法(Momentum)详解:

简单来说,动量法是对SGD算法的改进,它运用了指数加权平均思想,最后起到减少震荡,加速收敛的效果。动量法尤其适用于高曲率、小但一致的梯度或带噪声的梯度场景。

1.指数加权平均

一种用于处理序列数据(如时间序列、梯度下降中的参数更新)的平滑方法,广泛应用于深度学习优化算法(如动量法(Momentum)、Adam、RMSprop等)。其核心思想是对历史数据赋予指数衰减的权重,从而平衡当前值与历史值的贡献。

在这里插入图片描述
在这里插入图片描述

注意·:通过调整 β,可以灵活平衡近期数据与历史数据的权重。

指数加权思想代码实现

例:
from matplotlib import pyplot  as plt
import torchx=torch.arange(1,31)
torch.manual_seed(1)
y=torch.randn(30)*10
y_ewa=[]
beta=0.9
for idx,t in enumerate(y,1):if idx==1:y_ewa.append(t)else:y_ewa.append(beta*y_ewa[idx-2]+(1-beta)*t)plt.scatter(x,y_ewa)
plt.show()

2.动量算法(Momentum)

首先,梯度计算公式(指数加权平均) s t = β s t − 1 + ( 1 − β ) g t s_t=βs_{t−1}+(1−β)g_t st=βst1+(1β)gt
参数更新公式 w t = w t − 1 − η s t w_t=w_{t−1}−ηs_t wt=wt1ηst
公式参数说明:

s t s_t st是当前时刻指数加权平均梯度值

s t − 1 s_{t-1} st1是历史指数加权平均梯度值

g t g_t gt是当前时刻的梯度值

β 是调节权重系数,通常取 0.9 或 0.99

η是学习率

w t w_t wt是当前时刻模型权重参数

PyTroch中编程实践如下:

例:
def test01():# 1 初始化权重参数w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)loss = ((w ** 2) / 2.0).sum()# 2 实例化优化方法:SGD 指定参数beta=0.9optimizer = torch.optim.SGD([w], lr=0.01, momentum=0.9)# 31次更新 计算梯度,并对参数进行更新optimizer.zero_grad()loss.backward()optimizer.step()print('第1次: 梯度w.grad: %f, 更新后的权重:%f' % (w.grad.numpy(), w.detach().numpy()))# 42次更新 计算梯度,并对参数进行更新# 使用更新后的参数机选输出结果loss = ((w ** 2) / 2.0).sum()optimizer.zero_grad()loss.backward()optimizer.step()print('第2次: 梯度w.grad: %f, 更新后的权重:%f' % (w.grad.numpy(), w.detach().numpy()))

3.动量法(Momentum)有效克服 “平缓”、”鞍点”、”峡谷” 的问题

在这里插入图片描述

  • 当处于鞍点位置时,由于当前的梯度为 0,参数无法更新。但是 Momentum 动量梯度下降算法已经在先前积累了一些梯度值,很有可能使得跨过鞍点;
  • mini-batch 每次选取少数的样本梯度确定前进方向,可能会出现震荡,使得训练时间变长,而Momentum 使用指数加权平均,平滑了梯度的变化,使得前进方向更加平缓,有利于加快训练过程,一定程度上也降低了 “峡谷” 问题的影响。
    在这里插入图片描述

二、从自适应学习率角度入手

(一)自适应梯度算法(AdaGrad)

1.概念

一种梯度下降算法,通过自适应调整每个参数的学习率。

核心思想是:对频繁更新的参数降低学习率,对不频繁更新的参数保持较大的学习率。

AdaGrad主要用于稀疏矩阵:对于稀疏特征(如NLP中的one-hot编码),其对应的参数更新频率低,梯度多为零或极小值,因此 G t,ii增长缓慢,使得自适应学习率 保持较大。而密集特征的参数因频繁更新导致 G t,ii快速增大,学习率显著下降。

在这里插入图片描述

2.更新过程

在这里插入图片描述
在这里插入图片描述

PyTroch中编程实践如下:

例:
def test02():# 1 初始化权重参数w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)loss = ((w ** 2) / 2.0).sum()# 2 实例化优化方法:adagrad优化方法optimizer = torch.optim.Adagrad([w], lr=0.01)# 31次更新 计算梯度,并对参数进行更新optimizer.zero_grad()loss.backward()optimizer.step()print('第1次: 梯度w.grad: %f, 更新后的权重:%f' % (w.grad.numpy(), w.detach().numpy()))# 42次更新 计算梯度,并对参数进行更新# 使用更新后的参数机选输出结果loss = ((w ** 2) / 2.0).sum()optimizer.zero_grad()loss.backward()optimizer.step()print('第2次: 梯度w.grad: %f, 更新后的权重:%f' % (w.grad.numpy(), w.detach().numpy()))

结果显示:

1: 梯度w.grad: 1.000000, 更新后的权重:0.9900002: 梯度w.grad: 0.990000, 更新后的权重:0.982965

(二)RMSProp优化算法

1.概念

**RMSProp 优化算法由Geoffrey Hinton提出,是对 AdaGrad 的优化:缓解AdaGrad的平方算法可能会使得学习率过早、过量的降低,导致模型训练后期学习率太小,较难找到最优解的情况

其使用指数加权平均梯度替换历史梯度的平方和。

相比AdaGrad有如下优势:1.因使得梯度平方和不再无限增长,从而避免了学习率持续下降;2.因近期梯度对学习率的影响更大,避免了快速适应最新梯度。

2.更新过程

在这里插入图片描述
在这里插入图片描述
RMSProp特点:
在这里插入图片描述
PyTroch中编程实践如下:

例:
def test03():# 1 初始化权重参数w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)loss = ((w ** 2) / 2.0).sum()# 2 实例化优化方法:RMSprop算法,其中alpha对应betaoptimizer = torch.optim.RMSprop([w], lr=0.01, alpha=0.9)# 31次更新 计算梯度,并对参数进行更新optimizer.zero_grad()loss.backward()optimizer.step()print('第1次: 梯度w.grad: %f, 更新后的权重:%f' % (w.grad.numpy(), w.detach().numpy()))# 42次更新 计算梯度,并对参数进行更新# 使用更新后的参数机选输出结果loss = ((w ** 2) / 2.0).sum()optimizer.zero_grad()loss.backward()optimizer.step()print('第2次: 梯度w.grad: %f, 更新后的权重:%f' % (w.grad.numpy(), w.detach().numpy()))

结果显示:

1: 梯度w.grad: 1.000000, 更新后的权重:0.9683772: 梯度w.grad: 0.968377, 更新后的权重:0.945788

三、自适应矩估计(Adam)

(一)概念

深度学习中最常用的优化算法之一,它结合了动量法(Momentum)和RMSProp的优点,通过自适应调整每个参数的学习率,并利用梯度的一阶矩(均值)和二阶矩(方差)估计,实现了高效、稳定的参数更新。

主要有以下特点:
在这里插入图片描述

(二)Adam的更新过程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
PyTroch中编程实践如下:

def test04():# 1 初始化权重参数w = torch.tensor([1.0], requires_grad=True)loss = ((w ** 2) / 2.0).sum()# 2 实例化优化方法:Adam算法,其中betas是指数加权的系数optimizer = torch.optim.Adam([w], lr=0.01, betas=[0.9, 0.99])# 3 第1次更新 计算梯度,并对参数进行更新optimizer.zero_grad()loss.backward()optimizer.step()print('第1次: 梯度w.grad: %f, 更新后的权重:%f' % (w.grad.numpy(), w.detach().numpy()))# 4 第2次更新 计算梯度,并对参数进行更新# 使用更新后的参数机选输出结果loss = ((w ** 2) / 2.0).sum()optimizer.zero_grad()loss.backward()optimizer.step()print('第2次: 梯度w.grad: %f, 更新后的权重:%f' % (w.grad.numpy(), w.detach().numpy()))

结果显示:

1: 梯度w.grad: 1.000000, 更新后的权重:0.9900002: 梯度w.grad: 0.990000, 更新后的权重:0.980003

附赠:

1.BGD/SGD/MBGD三种梯度优化方法对比

在这里插入图片描述

2.普通SGD与动量法(Momentum)的对比

在这里插入图片描述

3.AdaGrad、RMSProp、Adam 优缺点对比

在这里插入图片描述

今日的分享到此结束,下篇文章继续分享优化方法,敬请期待。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88166.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(三)yolov5——模型训练

一、准备数据 先准备一个MP4的视频 1.测试一帧 使用opencv来提取每一个视频的帧 先使用以下代码查看一帧的内容,是否符合预期 import cv2 import matplotlib.pyplot as plt# 打开视频文件 video cv2.VideoCapture("111.mp4") # 读取一帧 ret, frame…

008 Linux 开发工具(下) —— make、Makefile、git和gdb

🦄 个人主页: 小米里的大麦-CSDN博客 🎏 所属专栏: Linux_小米里的大麦的博客-CSDN博客 🎁 GitHub主页: 小米里的大麦的 GitHub ⚙️ 操作环境: Visual Studio 2022 文章目录 Linux 开发工具(下)Linux 项目自动化构建工…

前缀和题目:连续的子数组和

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:连续的子数组和 出处:523. 连续的子数组和 难度 5 级 题目描述 要求 给定一个整数数组 nums \texttt{nums} nums 和一个整数 k \tex…

队的简单介绍

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)的特点。 入队列:进行插入操作的一端称为队尾。 出队列:进行删除操作的一端称为队头。 入队列…

AI-Sphere-Butler之如何将豆包桌面版对接到AI全能管家~新玩法(一)

环境: AI-Sphere-Butler VBCABLE2.1.58 Win10专业版 豆包桌面版1.47.4 ubuntu22.04 英伟达4070ti 12G python3.10 问题描述: AI-Sphere-Butler之如何将豆包桌面版对接到AI全能管家~新玩法(一) 聊天视频: AI真…

【STM32】启动流程

1、.s启动文件解析 STM32的启动文件(一般是.s汇编文件,如startup_stm32f407xx.s)是STM32上电后执行的第一段代码,承担着“系统初始化化引导员”的角色。 它的主要作用是设置初始化栈指针(SP)、程序计数器&…

【vim】通过vim编辑器打开、修改、退出配置文件

通过vim编辑器打开任一配置文件 vim /etc/profile 英文输入下,按i键进入INSERT模式,修改配置文件 完成修改后,按esc键退出INSERT模式 英文输入下,输入":wq!",即可保存并退出 :q #不保存并退出 :q! …

Effective Modern C++ 条款6:当 auto 推导类型不符合预期时,使用显式类型初始化惯用法

在C开发中,auto关键字以其简洁性和高效性被广泛使用。然而,“自动推导”并非万能,尤其在某些特殊场景下,auto的推导结果可能与开发者预期不符,甚至导致未定义行为。今天,我们以《Effective Modern C》条款6…

学习Linux进程冻结技术

原文:蜗窝科技Linux进程冻结技术 功耗中经常需要用到,但是linux这块了解甚少,看到这个文章还蛮适合我阅读的 1 什么是进程冻结 进程冻结技术(freezing of tasks)是指在系统hibernate或者suspend的时候,将…

GitHub 趋势日报 (2025年06月22日)

📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 624 LLMs-from-scratch 523 ai-engineering-hub 501 n8n 320 data-engineer-handb…

kotlin中为什么新增扩展函数功能?

在 Kotlin 中,扩展函数的本质是「不修改原有类代码,为其新增功能」,这源自编程中「开闭原则」(对扩展开放,对修改关闭)的第一性原理。 核心需求:当需要给第三方库的类(如 Android 的…

excel 数据透视表介绍

Excel 数据透视表(PivotTable)就是你的数据分析神器!它能帮你快速汇总、分类、比较和分析 大量数据,从看似杂乱无章的表格中一键提取关键信息 ,生成交互式的汇总报告。无需复杂公式,只需拖拽几下,就能让数据“开口说话”&#xff…

半导体行业中的专用标准产品ASSP是什么?

半导体行业中的专用标准产品ASSP是什么? “专用标准产品”(ASSP - Application Specific Standard Product)是半导体集成电路中的一个重要分类。 你可以把它理解为介于通用标准产品和全定制ASIC之间的一种芯片。以下是它的核心定义和特点&a…

秋招Day14 - MySQL - 锁

MySQL中有几种类型的锁? 锁粒度来分,有表锁、页锁和行锁。 加锁机制划分,有乐观锁和悲观锁。 按兼容性划分,有共享锁和排他锁。 按锁模式划分,有记录锁,间隙锁,next-key锁,意向锁…

/var/lib/docker/overlay2目录过大怎么办

/var/lib/docker/overlay2 是 Docker 默认用于存储 容器镜像和容器运行时数据 的核心目录,基于 overlay2 存储驱动实现。以下是其具体作用和内容的详细解析: 1. overlay2 目录的作用 存储镜像分层结构: Docker 镜像采用分层设计,o…

JimuReport:一款免费的数据可视化报表工具

JimuReport(积木报表)是一款免费的企业级数据可视化报表软件,提供拖拽的方式像搭建积木一样完成在线设计,功能涵盖数据报表、打印设计、图表报表、门户设计、大屏设计等。 数据源 JimuReport 支持 30 多种数据源,包括…

Neo4j.5.X社区版创建数据库和切换数据库

在使用Neo4j数据库(版本:neo4j-community-5.22.0)时,系统自带的“neo4j”和“system”数据库适用于日常的简单学习和练习,但对于新的项目,将项目数据与练习数据混用会带来诸多不便,例如查询效率…

DAY33神经网络

浙大疏锦行 定义了一个简单的神经网络,主要是掌握pytorch框架

拼团系统多层限流架构详解

拼团系统多层限流架构详解 一、整体架构设计理念 多层限流采用"层层设防"思想,通过网关层全局流量控制→服务层接口粒度限流→本地资源隔离→热点参数精准防护的四级防御体系,实现从粗到细的流量治理,确保大促期间系统稳定性。 …

[ctfshow web入门] web92 `==`特性与intval特性

信息收集 和之前的题差不多,这次是使用了不严格相等的,详情看这篇博客: 和 在 PHP 中有何区别?一共包含哪些部分? 首先,不能使$num 4476,然后需要使intval($num,0)4476 include("flag…