Python 梯度下降法(三):Adagrad Optimize

news/2025/2/1 8:52:48/

文章目录

  • Python 梯度下降法(三):Adagrad Optimize
    • 一、数学原理
      • 1.1 介绍
      • 1.2 符号定义
      • 1.3 实现流程
    • 二、代码实现
      • 2.1 函数代码
      • 2.2 总代码
    • 三、优缺点
      • 3.1 优点
      • 3.2 缺点

Python 梯度下降法(三):Adagrad Optimize

Python 梯度下降法(一):Gradient Descent-CSDN博客
Python 梯度下降法(二):RMSProp优化算法-CSDN博客

一、数学原理

1.1 介绍

Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,常用于机器学习中模型参数的优化,能根据每个参数的历史梯度信息自适应地调整学习率。

1.2 符号定义

符号意义
θ \theta θ模型待优化的参数向量( n × 1 n\times 1 n×1)
J ( θ ) J(\theta) J(θ)模型的损失函数
g t = ∇ θ J ( θ t ) g_{t}=\nabla_{\theta}J(\theta_{t}) gt=θJ(θt)模型在第 t t t次迭代时的梯度( n × 1 n\times 1 n×1)
η \eta η全局学习率,控制整体学习的步长
ϵ \epsilon ϵ无穷小量,防止分母为0,一般为 1 0 − 8 10^{-8} 108
G t G_{t} Gt每个参数对应的累积梯度平方和( n × 1 n\times 1 n×1)

1.3 实现流程

  1. 初始化 θ \theta θ:全部初始化为0,或者初始化为随机小值
    初始化每个参数对应的累计梯度平方和, G 0 , i = 0 , i ∈ ( 1 , 2 , ⋯ , n ) G_{0, i}=0,i\in(1,2,\cdots,n) G0,i=0,i(1,2,,n) G t , i G_{t,i} Gt,i用于记录第 i i i个参数从开始到第 t t t次迭代的梯度平方的累计值。
  2. 迭代更新累计梯度平方和: G t = G t − 1 + g t ⊙ g t G_{t}=G_{t-1}+g_{t}\odot g_{t} Gt=Gt1+gtgt ⊙ \odot 为Hadamard product.
  3. 更新参数向量 θ \theta θ θ t = θ t − 1 − η G t + ϵ ⊙ g t \theta_{t}=\theta_{t-1}-\frac{\eta}{\sqrt{G_{t}+\epsilon }}\odot g_{t} θt=θt1Gt+ϵ ηgt。使用numpy的广播机制进行更新。

二、代码实现

2.1 函数代码

python"># 定义Adagrad函数
def adagrad_optimizer(X, y, eta, num_iter=1000, epsilon=1e-8, threshold=1e-8):"""X: 数据 x  mxn,可以在传入数据之前进行数据的归一化y: 数据 y  nx1eta: 学习率  num_iter: 迭代次数epsilon: 无穷小threshold: 阈值"""# 初始化参数m, n = X.shapetheta, G_sum, loss_ = np.random.rand(n, 1), np.zeros((n, 1)), []  # n x 1, loss_存储损失率的变化for _ in range(num_iter):# 开始迭代# 使用点积计算预测值h = X.dot(theta)# 计算误差error = h - yloss_.append(np.mean(error ** 2) / 2)# 计算梯度gradient = (1/m) * X.T.dot(error)# 更新累计梯度平方和G_sum = G_sum + np.pow(gradient, 2)  # 利用广播机制,进行逐元素相乘# 更新参数thetatheta = theta - np.multiply(eta / np.sqrt(G_sum + epsilon), gradient)if (_ > 1) and (abs(loss_[-1] - loss_[-2]) < threshold):print(f"Converged at iteration {_ + 1}")breakreturn theta, loss_

2.2 总代码

python">import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 定义Adagrad函数
def adagrad_optimizer(X, y, eta, num_iter=1000, epsilon=1e-8, threshold=1e-8):"""X: 数据 x  mxn,可以在传入数据之前进行数据的归一化y: 数据 y  nx1eta: 学习率  num_iter: 迭代次数epsilon: 无穷小threshold: 阈值"""# 初始化参数m, n = X.shapetheta, G_sum, loss_ = np.random.rand(n, 1), np.zeros((n, 1)), []  # n x 1, loss_存储损失率的变化for _ in range(num_iter):# 开始迭代# 使用点积计算预测值h = X.dot(theta)# 计算误差error = h - yloss_.append(np.mean(error ** 2) / 2)# 计算梯度gradient = (1/m) * X.T.dot(error)# 更新累计梯度平方和G_sum = G_sum + np.pow(gradient, 2)  # 利用广播机制,进行逐元素相乘# 更新参数thetatheta = theta - np.multiply(eta / np.sqrt(G_sum + epsilon), gradient)if (_ > 1) and (abs(loss_[-1] - loss_[-2]) < threshold):print(f"Converged at iteration {_ + 1}")breakreturn theta, loss_# 生成一些示例数据
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
# 添加偏置项
X_b = np.c_[np.ones((100, 1)), X]# 设置超参数
eta = 0.91  # 更具损失函数图像进行调整# Adagrad优化算法
theta, loss_ = adagrad_optimizer(X_b, y, eta)print("最优参数 theta:")
print(theta)
plt.plot(range(len(loss_)), loss_, label="损失函数图像")
plt.title("损失函数图像")
plt.xlabel("迭代次数")
plt.ylabel("损失值")
plt.show()

1738230390_jlm84d84ze.png1738230389690.png

三、优缺点

3.1 优点

自适应学习率调整Adagrad:能够根据每个参数的历史梯度信息自适应地调整学习率。对于经常更新的参数,其梯度累积平方和会不断增大,导致学习率逐渐减小,避免该参数更新过快;而对于不经常更新的参数,梯度累积平方和相对较小,学习率会相对较大,使得这些参数能够更快地更新。这种特性使得 Adagrad 在处理稀疏数据时表现出色,因为稀疏数据中某些特征的出现频率较低,对应的参数更新不频繁,Adagrad 可以为这些参数分配更大的学习率,从而更有效地学习到数据中的信息。

无需手动频繁调整学习率:在很多情况下,Adagrad 可以使用固定的全局学习率,算法会自动根据参数的梯度历史来调整每个参数的实际学习率。这减少了手动调整学习率的工作量,尤其对于复杂的模型和大规模数据集,手动调参往往是一个耗时且困难的过程。使用 Adagrad 可以在一定程度上简化调参过程,提高开发效率。

理论保证收敛性:在一定的条件下,Adagrad 算法具有理论上的收敛保证。对于凸优化问题,只要满足适当的条件,Adagrad 能够收敛到全局最优解;对于非凸优化问题,也能收敛到局部最优解。这种理论上的保障使得 Adagrad 在实际应用中具有一定的可靠性。

3.2 缺点

学习率单调递减问题:随着迭代次数的增加,累积梯度平方和会不断增大,导致学习率不断减小。在训练后期,学习率可能会变得非常小,使得参数更新变得极其缓慢,甚至可能导致算法提前收敛到局部最优解,无法继续优化。这种学习率单调递减的特性限制了 Adagrad 在某些问题上的性能,尤其是对于需要长时间训练才能达到最优解的复杂模型。随着训练轮数的增加,Adagrad 的学习率会急剧下降,导致模型在后期几乎停止学习,难以进一步提高性能。

对初始学习率敏感:Adagrad 算法对初始学习率的选择比较敏感。如果初始学习率设置过大,在训练初期可能会导致参数更新步长过大,使得算法无法收敛甚至发散;如果初始学习率设置过小,在训练前期参数更新会非常缓慢,增加训练时间。因此,需要仔细调整初始学习率才能使算法达到较好的性能,这在一定程度上增加了使用 Adagrad 的难度。

内存需求较大:Adagrad 需要为每个参数维护一个累积梯度平方和,这意味着在处理高维数据或大规模模型时,需要额外的内存来存储这些累积值。对于一些内存受限的设备或应用场景,这可能会成为一个问题。例如,在处理具有数百万甚至数十亿参数的深度学习模型时,Adagrad 的内存开销可能会变得难以承受。


http://www.ppmy.cn/news/1568384.html

相关文章

VMware安装win10记录

(1)下载vmware&#xff0c;这个pro现在也免费的&#xff0c;下载地址&#xff1a;https://support.broadcom.com/group/ecx/productfiles?subFamilyVMware%20Workstation%20Pro&displayGroupVMware%20Workstation%20Pro%2017.0%20for%20Windows&release17.6.2&os&…

Vue.js 路由懒加载

Vue.js 路由懒加载 在 Vue.js 开发中&#xff0c;随着应用规模的扩大&#xff0c;打包后的 JavaScript 文件可能会变得相当庞大&#xff0c;影响页面的加载速度和性能。为了解决这个问题&#xff0c;Vue Router 提供了路由懒加载功能&#xff0c;可以将不同路由对应的组件分割…

「pandas」python pandas 初步、数据结构Series、DataFrame、MultiIndex

「pandas」python pandas 初步、数据结构Series、DataFrame、MultiIndex 更多内容请关注本人【pandas】专栏 【目录】 pandas简介 为什么使用pandas pandas数据结构 Series 创建属性索引 DataFrame 创建属性索引 MultiIndex 一、pandas简介 以numpy为基础、借力numpy模块…

JRE、JVM 和 JDK 的区别

Java 的运行和开发环境中&#xff0c;有三个重要的概念&#xff1a;JRE、JVM 和 JDK。 1. JVM (Java Virtual Machine) 定义&#xff1a;Java 虚拟机&#xff0c;是运行 Java 程序的虚拟环境。作用&#xff1a; 执行 .class 字节码文件。提供内存管理、垃圾回收和安全机制。不…

Rust 条件语句

Rust 条件语句 在编程语言中&#xff0c;条件语句是进行决策和实现分支逻辑的关键。Rust 语言作为一门系统编程语言&#xff0c;其条件语句的使用同样至关重要。本文将详细介绍 Rust 中的条件语句&#xff0c;包括其基本用法、常见场景以及如何避免常见错误。 基本用法 Rust…

记录一个连不上docker中的mysql的问题

引言 使用的debian12,不同发行版可能有些许差异&#xff0c;连接使用的工具是navicat lite 本来是毫无思绪的&#xff0c;以前在云服务器上可能是防火墙的问题&#xff0c;但是这个桌面环境我压根没有使用防火墙。 直到 ying192:~$ mysql -h127.0.0.1 -uroot ERROR 1045 (28…

【2024年华为OD机试】(A卷,200分)- 农场施肥 (JavaScriptJava PythonC/C++)

一、问题描述 题目描述 某农场主管理了一大片果园,fields[i] 表示不同果林的面积,单位:平方米(m)。现在需要为所有的果林施肥,且必须在 n 天之内完成,否则会影响收成。小布是果林的工作人员,他每次选择一片果林进行施肥,且一片果林施肥完后当天不再进行施肥作业。 …

大模型高频知识汇总:查漏补缺参考大全

大模型技术深度剖析与面试指南 在人工智能领域蓬勃发展的当下&#xff0c;大模型技术成为了核心驱动力&#xff0c;相关岗位的面试也对求职者提出了极高的要求。本文将围绕大模型的关键技术领域展开&#xff0c;深入探讨其中的原理、应用及面试要点&#xff0c;助力读者查漏补…