【人工智能】神经网络的优化器optimizer(三):RMSProp动态自适应学习率优化器

一、算法核心原理

        RMSProp(Root Mean Square Propagation)是深度学习先驱Geoffrey Hinton在2012年提出的优化算法,它基于AdaGrad算法的改进,创新性地解决了传统梯度下降法中学习率固定不变的局限性。该算法的核心机制在于采用指数加权移动平均(EWMA,详情可参考连接:【深度学习】通俗易懂的基础知识:指数加权平均)方法,实现了对参数更新幅度的自适应动态调整。

二、RMSProp算法的公式推导

        AdaGrad算法(【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器)对于学习率的动态调整设计思路:把全部历史梯度一视同仁全部打包进行平方和,导致学习提早结束。

        RMSProp算法对于学习率的动态调整设计思路:通过将Momentum动量优化器(【人工智能】神经网络的优化器optimizer(一):Momentum动量优化器)中采用的指数加权平均(EWMA)应用到学习率动态调整中,以便于通过指数衰减将近期数据赋予高权重,历史数据逐渐“遗忘”,从而产生类似“滑动”的机制,避免学习率过早衰减的问题。

                                                v_{t}=\beta v_{t-1}+(1-\beta)x_{t}^{2}

        其中:

  • v_{t}:当前时刻的加权平均值

  • v_{t-1}:上一时刻的加权平均值(初始值 v_{0}=0

  • x_{t}:想要观察的时刻 t 的值,在该文章中代表 t 时间的梯度

  • \beta:衰减因子(0<β<1),控制历史数据的权重分布‌

        RMSProp为每个参数维护一个状态变量(通常记作 V),用于记录梯度平方的指数衰减平均值,剩下的其他公式就和AdaGrad算法是一样的了:

                ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        \theta _{t+1}=\theta _{t}-\frac{\eta }{\sqrt{v_{t}+\epsilon }}\cdot x_{t}

        其算法的特点也和AdaGrad算法差不多:

  1. 分母设计‌:v^{_{t}}近似为梯度的均方根(Root Mean Square),反映历史梯度的幅值

  2. 自适应效果‌:

    1. 梯度方向振荡剧烈(v^{_{t}}较大)→ 学习率降低,抑制震荡

    2. 梯度方向平缓(v^{_{t}}较小)→ 学习率增大,加速收敛‌

  3. 稳定常数:\varepsilon(如1e-8)用于数值稳定,防止分母为零‌

三、RMSProp算法和AdaGrad算法的对比

特性RMSPropAdaGrad
历史梯度累积方式指数衰减加权平均全局累积
学习率衰减趋势动态平衡,避免过早趋近零单调递减,后期更新停滞
适用场景非平稳目标、深层网络、RNN‌稀疏数据、浅层网络

        根据上述内容可以总结出几个特点:

  • 解决AdaGrad缺陷‌:AdaGrad累积所有历史梯度导致后期学习率过小,RMSProp通过衰减系数 γ 削弱早期梯度的影响,使学习率在训练中保持有效调整能力‌;

  • 适应非平稳目标‌:在RNN等动态系统中,梯度分布随时间变化,RMSProp的指数衰减能更快响应近期变化‌;

  • 超参数影响‌:γγ 过大易忽略新梯度信息,过小则退化为类似AdaGrad,通常取0.9经验值‌。

        综上所述,RMSProp的衰减机制通过加权平均平衡历史与当前梯度,实现学习率的稳定自适应调整,显著提升非凸优化问题的训练效率‌。

四、代码实现

        以下是使用python编写的两个算法的动画对比图,可以观察到RMSProp算法相比AdaGrad算法会快速往原点滑动,然后在原点附近来回滑动,通过修改超参可以调整算法的步幅以及方向,建议各位自行尝试:

        代码源码如下:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation# 生成样本数据
np.random.seed(42)
sample_data = np.random.randn(100, 2) * 2# 定义测试函数
def loss_func(x, y):return 0.1 * x ** 2 + 2 * y ** 2 + np.sin(x) * np.cos(y)# 优化器实现
class AdaGrad:def __init__(self, params, lr=0.1):self.params = params.copy()self.lr = lrself.cache = {k: 0 for k in params.keys()}self.history = {k: [v] for k, v in params.items()}def step(self, grads):for key in self.params:self.cache[key] += grads[key] ** 2self.params[key] -= self.lr * grads[key] / (np.sqrt(self.cache[key]) + 1e-8)self.history[key].append(self.params[key])class RMSProp:def __init__(self, params, lr=0.1, gamma=0.9):self.params = params.copy()self.lr = lrself.gamma = gammaself.cache = {k: 0 for k in params.keys()}self.history = {k: [v] for k, v in params.items()}def step(self, grads):for key in self.params:self.cache[key] = self.gamma * self.cache[key] + (1 - self.gamma) * grads[key] ** 2self.params[key] -= self.lr * grads[key] / (np.sqrt(self.cache[key]) + 1e-8)self.history[key].append(self.params[key])# 初始化优化器
initial_params = {'x': -4, 'y': 4}
adagrad = AdaGrad(initial_params.copy())
rmsprop = RMSProp(initial_params.copy())# 创建可视化
fig = plt.figure(figsize=(12, 5))
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)# 绘制样本数据
ax1.scatter(sample_data[:, 0], sample_data[:, 1], c='black', s=10)
ax2.scatter(sample_data[:, 0], sample_data[:, 1], c='black', s=10)# 绘制等高线
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = loss_func(X, Y)
ax1.contour(X, Y, Z, levels=20, alpha=0.5)
ax2.contour(X, Y, Z, levels=20, alpha=0.5)# 动画更新函数
def update(frame):# 计算梯度x_adagrad, y_adagrad = adagrad.params['x'], adagrad.params['y']grads = {'x': 0.2 * x_adagrad + np.cos(x_adagrad) * np.cos(y_adagrad),'y': 4 * y_adagrad - np.sin(x_adagrad) * np.sin(y_adagrad)}adagrad.step(grads)x_rmsprop, y_rmsprop = rmsprop.params['x'], rmsprop.params['y']grads = {'x': 0.2 * x_rmsprop + np.cos(x_rmsprop) * np.cos(y_rmsprop),'y': 4 * y_rmsprop - np.sin(x_rmsprop) * np.sin(y_rmsprop)}rmsprop.step(grads)# 更新轨迹ax1.plot(adagrad.history['x'], adagrad.history['y'], 'b-', lw=1)ax2.plot(rmsprop.history['x'], rmsprop.history['y'], 'r-', lw=1)return ax1, ax2# 运行动画
ani = FuncAnimation(fig, update, frames=100, interval=200)
ax1.set_title('AdaGrad (Blue)')
ax2.set_title('RMSProp (Red)')
plt.tight_layout()
plt.show()

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

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

相关文章

全面解析了Java微服务架构的设计模式

一、引言&#xff1a;微服务架构的背景与优势随着互联网应用的复杂度不断提升&#xff0c;传统的单体架构&#xff08;Monolithic Architecture&#xff09;在可维护性、可扩展性、部署灵活性等方面逐渐暴露出瓶颈。微服务架构&#xff08;Microservices Architecture&#xff…

本地组策略编辑器图形化工具

本地组策略图形化工具&#xff0c;添加用户权限分配功能。这将包括常见的用户权限策略设置&#xff1a; 目前版本在优化中&#xff0c;后续会添加更多功能。 # GroupPolicyGUI.ps1 # 需要以管理员权限运行Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName …

深度学习卷积神经网络项目实战——超市商品分类

卷积神经网络项目实战 1.项目简介 1.1项目名称 ​ 基于CNN实现超市商品的混合颗粒度分类&#xff08;500分类&#xff09; 1.2 项目简介 ​ 该项目旨在通过卷积神经网络&#xff08;CNN&#xff09;实现超市商品的混合颗粒度分类&#xff0c;主要针对商品的不同种类进行分…

网站如何被搜索引擎收录(Google、Bing、百度等)

1. 【Google 收录】注册 Google Search Console&#xff1a; https://search.google.com/search-console添加网站&#xff08;主域名、子域名都加&#xff09;验证所有权&#xff08;用 DNS、HTML 文件、Meta Tag 都可以&#xff09;提交 Sitemap&#xff08;/sitemap.xml&…

JDK 8 → JDK 17 升级说明书(面向 Spring Boot / Spring Cloud / Spring )

自从 JDK 8 发布以来&#xff0c;Java 语言在持续进化&#xff0c;带来了许多新的功能和性能改进。而 JDK 17 作为一个长期支持版本&#xff08;LTS&#xff09;&#xff0c;在许多方面超越了 JDK 8&#xff0c;不仅提升了语言本身的能力&#xff0c;还进一步提高了性能、可维护…

【ElasticSearch】使用docker compose,通过编写yml安装es8.15和kibana可视化界面操作,go连接es

使用 Docker 安装 Elasticsearch Docker 搭建 Elasticsearch Kibana 环境&#xff0c;并在过程中标注常见问题和解决方案。 1. 准备工作 在开始之前&#xff0c;请确认你本地已经安装了&#xff1a; 工具版本建议检查方式Docker≥ 20.xdocker -vDocker Compose≥ 2.xdocker …

《C 语言文件操作补充:字符串格式化与随机读写全解析》

目录 一. sprintf函数和sscanf函数 1.1 sprintf 函数&#xff1a;将格式化数据写入字符串 1.2 sscanf 函数&#xff1a;从字符串中格式化读取数据 二. 文件的随机读写 2.1 fseek 函数&#xff1a;移动文件读写指针 2.2 ftell 函数&#xff1a;获取当前指针位置 2.3 rew…

SOME/IP-SD报文中 Entry Format(条目格式)-理解笔记4

逐字段解析 AUTOSAR SOME/IP Service Discovery 中的 Entry 格式。我们将它拆解成几个部分&#xff0c;并用清晰的排版和比喻来确保每个字段都得到解释。&#x1f4dc; Entry 的完整结构&#xff1a;三层蛋糕 一条完整的 SD Entry 信息就像一块三层蛋糕&#xff0c;从上到下分别…

在 vue3 和 vue2 中,computed 计算属性和 methods 方法区别是什么

在 Vue 2 和 Vue 3 中&#xff0c;computed&#xff08;计算属性&#xff09;和 methods&#xff08;方法&#xff09;都是处理数据逻辑的方式&#xff0c;但它们在缓存机制、使用场景、执行时机等方面有显著区别&#xff0c;且这些区别在两个版本中保持一致。 1. 缓存机制&…

android 改机系列之-虚拟摄像头-替换相机预览画面

Android Native 层实现跨进程 YUV 视频帧共享&#xff1a;基于抽象 Unix Socket 的高效通信方案。基于AOSP13源码或者lineage20 或相近版本。非hook 或者lsp 等插件方案。 1.引言 在某些定制化 Android 应用场景中&#xff0c;我们可能需要动态替换系统相机的预览画面 —— 例…

SSM从入门到实战:2.5 SQL映射文件与动态SQL

&#x1f44b; 大家好&#xff0c;我是 阿问学长&#xff01;专注于分享优质开源项目解析、毕业设计项目指导支持、幼小初高的教辅资料推荐等&#xff0c;欢迎关注交流&#xff01;&#x1f680; 12-SQL映射文件与动态SQL &#x1f4d6; 本文概述 本文是SSM框架系列MyBatis进…

vue+vite打包后的文件希望放在一个子目录下

比如我们常规操作是打包的项目文件直接放在域名下面。如果我们希望把项目放在子域名下面应该怎么处理呢&#xff1f;需要两个步骤vite.config.js里面指定base的路径假设我们希望放在子目录加做call那么我们可以这样base:/call/,注意不是build目录哈。return的最外层。如果本地和…

Java:Docx4j类库简介及使用

1.简介 Docx4j 是一个功能强大的 Java 类库&#xff0c;专门用于创建和操作 Microsoft Open XML 格式&#xff08;如 Word DOCX、PowerPoint PPTX 和 Excel XLSX&#xff09;的文件。它深受 Java 开发者喜爱&#xff0c;特别是在需要自动化处理 Office 文档的场景下。 下面是一…

【机械故障】旋转机械故障引起的振动信号调制效应概述

系列文章目录 提示&#xff1a;学习笔记 机械故障信号分析 共振峰 旋转机械故障引起的振动信号调制效应概述系列文章目录一、研究背景与意义二、故障引起的调制效应分类三、非平稳信号分析方法3.1 时频分析方法3.2 信号分解方法一、研究背景与意义 在工程实践中&#xff0c;可…

密码安全隐形基石:随机数、熵源与DRBG核心解析与技术关联

前言&#xff1a;密码安全的 “隐形基石” 在数字化浪潮席卷全球的今天&#xff0c;从金融交易的密钥生成到区块链的共识机制&#xff0c;从量子通信的加密协议到智能汽车的身份认证&#xff0c;随机数如同空气般渗透在信息系统的每一个安全节点。然而&#xff0c;看似简单的 …

Vue3 + Element Plus实现表格多行文本截断与智能Tooltip提示

在实际开发中&#xff0c;我们经常需要在表格中展示较长的文本内容&#xff0c;但又希望保持界面的整洁美观。本文将介绍如何在Vue3 和 Element Plus中实现表格多行文本截断&#xff0c;并智能控制Tooltip的显示——只有当文本被截断时才显示Tooltip&#xff0c;否则不显示。 需…

使用powerquery处理数据,取时间或者日期之前的

Table.AddColumn(#"已更改列类型 1", "自定义 (2)", each letcleanText Text.Replace([备注], "#(lf)", " "),hasTime Text.Contains(cleanText, "时间&#xff1a;"),hasDate Text.Contains(cleanText, "日期&…

Java面试全栈技术解析:从Spring Cloud到Kafka的实战演练

面试官&#xff1a;请简单介绍一下Spring Cloud的核心组件&#xff1f; 谢飞机&#xff1a;嗯...Spring Cloud主要是基于Spring Boot的&#xff0c;然后有Eureka做服务发现&#xff0c;Feign做声明式REST调用&#xff0c;还有Config做配置中心... 面试官&#xff1a;那在电商场…

极简 useState:手写 20 行,支持多次 setState 合并

不依赖 React&#xff0c;用 闭包 批处理队列 实现可合并更新的 useState。一、20 行完整代码 function createUseState(initialValue) {let state initialValue;let pending null; // 合并队列let listeners [];const flush () > {if (pending ! null) {…

LabVIEW Vision视觉引导撑簧圈智能插装

为解决人工插装连接器撑簧圈时劳动强度大、效率低、一致性差的问题&#xff0c;例以 LabVIEW为开发平台&#xff0c;结合 IMAQ Vision 机器视觉库&#xff0c;搭配精密硬件搭建智能插装系统。系统可适配 9 芯、13 芯、25 芯、66 芯、128 芯 5 种规格工件&#xff0c;经 100 只产…