当前位置: 首页 > news >正文

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

一.自适应梯度算法Adagrad概述

        Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通过累积历史梯度的平方信息,动态调整每个参数的学习率,使得频繁更新的参数学习率较小,稀疏更新的参数学习率较大。这种自适应特性使其在训练深度神经网络时表现优异,尤其在自然语言处理和推荐系统中广泛应用。

二.Adagrad的优缺点

        Adagrad的主要优势在于自适应学习率,尤其适合稀疏数据或非平稳目标的优化问题。其缺点在于累积的梯度平方会持续增长,导致后期学习率过小,可能过早停止训练。后续改进算法如RMSProp和Adam通过引入衰减机制解决了这一问题。尽管如此,Adagrad仍为自适应优化算法的发展奠定了基础。

三.算法原理与特性

3.1 基本核心思想

        自适应梯度算法(Adaptive Gradient Algorithm)通过累积历史梯度信息实现参数级学习率调整。其主要创新点在于:

$$g_{t,i} = \sum_{\tau=1}^t \nabla_\theta J(\theta_{\tau,i})^2$$

$$\theta_{t+1,i} = \theta_{t,i} - \frac{\eta}{\sqrt{g_{t,i} + \epsilon}} \nabla_\theta J(\theta_{t,i})$$

其中$$i$$表示参数索引,$$\eta$$为全局学习率, $$\epsilon$$为数值稳定常数(通常取 1e-8)

3.2 算法的特性

  • 参数级自适应:每个参数独立动态调整学习率,而不是固定学习率
  • 梯度敏感度:更新率较大的动态调整为较小的学习率,更新率较小的动态调整为较大的学习率
  • 累积记忆:通过历史梯度的平方和持续积累增长

3.3 更新规则

        Adagrad的更新公式基于参数的历史梯度信息,具体表现为对学习率的分母项进行累积。对于每个参数θᵢ,其更新规则如下:

# Adagrad更新公式
grad_squared += gradient ** 2
adjusted_lr = learning_rate / (sqrt(grad_squared) + epsilon)
theta -= adjusted_lr * gradient

        其中,grad_squared是梯度平方的累积,epsilon是为数值稳定性添加的常数,防止出现梯度为0导致分母变成无限大的情况,通常采用1e-8。Adagrad的累积特性使其对初始学习率的选择相对鲁棒,但长期训练可能导致学习率过小。

四、代码实现

4.1 测试函数设置

        使用非凸函数: f(x) = x**2 / 20.0 + y**2

4.2 收敛速度可视化

import numpy as np
from collections import OrderedDict
import matplotlib.pyplot as pltclass AdaGrad:"""AdaGrad"""def __init__(self, lr=1.5):self.lr = lrself.h = Nonedef 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)optimizers= AdaGrad()init_pos = (-7.0, 2.0)
params = {}
params['x'], params['y'] = init_pos[0], init_pos[1]
grads = {}
grads['x'], grads['y'] = 0, 0x_history = []
y_history = []def f(x, y):return x**2 / 20.0 + y**2def df(x, y):return x / 10.0, 2.0*yfor i in range(30):x_history.append(params['x'])y_history.append(params['y'])grads['x'], grads['y'] = df(params['x'], params['y'])optimizers.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] = 0idx = 1# 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("AdaGrad")
plt.xlabel("x")
plt.ylabel("y")plt.show()

        收敛效果如下:

五、Adagrad算法优缺点分析

5.1 优势特征

  1. 稀疏梯度优化:适合NLP等稀疏数据场景
  2. 自动学习率调整:减少超参调优成本
  3. 早期快速收敛:梯度累积未饱和时效率高

5.2 局限与改进

  1. 学习率单调衰减:后期更新停滞
  2. 内存消耗:需存储历史梯度平方和
  3. 梯度突变敏感:可能错过最优解

5.3 常用场景以及建议

  1. 推荐场景:自然语言处理、推荐系统
  2. 参数设置:
    • 初始学习率:0.01-0.1
    • 批量大小:128-512
  3. 配合技术:梯度裁剪+权重衰减

六. 各优化器对比

优化器收敛速度震荡幅度超参敏感性内存消耗
SGD
Momentum中等中等中等
Adagrad快(初期)
RMSProp稳定较小中等
Adam最快最小

七、全部优化器的对比代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cmdef test_function(x, y):return x ** 2 / 20.0 + y ** 2def compare_optimizers():# 初始化参数init_params = np.array([3.0, 4.0])epochs = 200optimizers = {'SGD': SGD(lr=0.1),'Momentum': Momentum(lr=0.1, momentum=0.9),'Adagrad': Adagrad(lr=0.1),'RMSProp': RMSProp(lr=0.001, decay=0.9),'Adam': Adam(lr=0.1, beta1=0.9, beta2=0.999)}# 训练过程plt.figure(figsize=(14,10))ax = plt.axes(projection='3d')X = np.linspace(-4, 4, 100)Y = np.linspace(-4, 4, 100)X, Y = np.meshgrid(X, Y)Z = test_function(X, Y)ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, alpha=0.6)for name, opt in optimizers.items():params = init_params.copy()trajectory = []for _ in range(epochs):grad = compute_gradient(params)params = opt.update(params, grad)trajectory.append(params.copy())trajectory = np.array(trajectory)ax.plot3D(trajectory[:,0], trajectory[:,1], test_function(trajectory[:,0], trajectory[:,1]), label=name, linewidth=2)ax.legend()ax.set_xlabel('x')ax.set_ylabel('y')ax.set_zlabel('z')plt.show()def compute_gradient(params):x, y = paramsdx = x / 10.0dy = 2.0*yreturn np.array([dx, dy])# 各优化器实现类
class SGD:def __init__(self, lr=0.01):self.lr = lrdef update(self, params, grads):return params - self.lr * gradsclass Momentum:def __init__(self, lr=0.01, momentum=0.9):self.lr = lrself.momentum = momentumself.v = Nonedef update(self, params, grads):if self.v is None:self.v = np.zeros_like(params)self.v = self.momentum*self.v + self.lr*gradsreturn params - self.vclass Adagrad:def __init__(self, lr=0.01, eps=1e-8):self.lr = lrself.eps = epsself.cache = Nonedef update(self, params, grads):if self.cache is None:self.cache = np.zeros_like(params)self.cache += grads**2return params - self.lr / (np.sqrt(self.cache) + self.eps) * gradsclass RMSProp:def __init__(self, lr=0.001, decay=0.9, eps=1e-8):self.lr = lrself.decay = decayself.eps = epsself.cache = Nonedef update(self, params, grads):if self.cache is None:self.cache = np.zeros_like(params)self.cache = self.decay*self.cache + (1-self.decay)*grads**2return params - self.lr / (np.sqrt(self.cache) + self.eps) * gradsclass Adam:def __init__(self, lr=0.001, beta1=0.9, beta2=0.999, eps=1e-8):self.lr = lrself.beta1 = beta1self.beta2 = beta2self.eps = epsself.m = Noneself.v = Noneself.t = 0def update(self, params, grads):if self.m is None:self.m = np.zeros_like(params)self.v = np.zeros_like(params)self.t += 1self.m = self.beta1*self.m + (1-self.beta1)*gradsself.v = self.beta2*self.v + (1-self.beta2)*grads**2m_hat = self.m / (1 - self.beta1**self.t)v_hat = self.v / (1 - self.beta2**self.t)return params - self.lr * m_hat / (np.sqrt(v_hat) + self.eps)if __name__ == "__main__":compare_optimizers()

        效果图如下:

        观察图示可以得出以下结论:

  • Adagrad初期收敛速度明显快于SGD
  • 中后期被Adam、RMSProp超越
  • 在平坦区域表现出更稳定的更新方向
  • 对于陡峭方向能自动减小步长
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dtcms.com/a/234950.html

相关文章:

  • 视频监控平台建设方案
  • 精益数据分析(95/126):Socialight的定价转型启示——B2B商业模式的价格策略与利润优化
  • 智能制造数字孪生全要素交付一张网:智造中枢,孪生领航,共建智造生态共同体
  • 大模型安全测试报告:千问、GPT 全系列、豆包、Claude 表现优异,DeepSeek、Grok-3 与 Kimi 存在安全隐患
  • yolo 训练 中间可视化
  • 视频监控管理平台EasyCVR与V4分析网关对接后告警照片的清理优化方案
  • Fullstack 面试复习笔记:Spring / Spring Boot / Spring Data / Security 整理
  • 本地部署企业邮箱,让企业办公更安全高效
  • 华为云Flexus+DeepSeek征文|基于华为云Flexus X和DeepSeek-R1打造个人知识库问答系统
  • Github 2025-06-06 Java开源项目日报Top10
  • [BIOS]VSCode zx-6000 编译问题
  • (一)上市企业实施IPD成功案例分享之——方太
  • OpenCV 图像色彩空间转换与抠图
  • 网络流学习笔记 - 最大流最小割
  • JVM——打开JVM后门的钥匙:反射机制
  • Javascript 编程基础(5)面向对象 | 5.1、构造函数实例化对象
  • RFID推动新能源汽车零部件生产系统管理应用案例
  • 汽车免拆诊断案例 | 2010款捷豹XFL车制动警告灯、DSC警告灯异常点亮
  • 算法打卡16天
  • CANFD 数据记录仪在汽车售后解决偶发问题故障的应用
  • 电脑同时连接内网和外网的方法,附外网连接局域网的操作设置
  • 六级作文模板笔记
  • AC68U刷梅林384/386版本后不能 降级回380,升降级解决办法
  • AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
  • 「基于连续小波变换(CWT)和卷积神经网络(CNN)的心律失常分类算法——ECG信号处理-第十五课」2025年6月6日
  • 柴油发电机组接地电阻柜的作用
  • 【Maven打包错误】 Fatal error compiling: 错误: 不支持发行版本 21
  • figma 和蓝湖 有什么区别
  • Caliper 配置文件解析:config.yaml
  • 35.成功解决编写关于“江协科技”编写技巧第二期标志位积累的问题