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

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

文章目录

  • 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 函数代码

# 定义Adagrad函数
def adagrad_optimizer(X, y, eta, num_iter=1000, epsilon=1e-8, threshold=1e-8):
    """
    X: 数据 x  mxn,可以在传入数据之前进行数据的归一化
    y: 数据 y  nx1
    eta: 学习率  
    num_iter: 迭代次数
    epsilon: 无穷小
    threshold: 阈值
    """
    # 初始化参数
    m, n = X.shape
    theta, 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 - y
        loss_.append(np.mean(error ** 2) / 2)
        # 计算梯度
        gradient = (1/m) * X.T.dot(error)
        # 更新累计梯度平方和
        G_sum = G_sum + np.pow(gradient, 2)  # 利用广播机制,进行逐元素相乘
        # 更新参数theta
        
        theta = 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}")
            break
    return theta, loss_

2.2 总代码

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  nx1
    eta: 学习率  
    num_iter: 迭代次数
    epsilon: 无穷小
    threshold: 阈值
    """
    # 初始化参数
    m, n = X.shape
    theta, 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 - y
        loss_.append(np.mean(error ** 2) / 2)
        # 计算梯度
        gradient = (1/m) * X.T.dot(error)
        # 更新累计梯度平方和
        G_sum = G_sum + np.pow(gradient, 2)  # 利用广播机制,进行逐元素相乘
        # 更新参数theta
        
        theta = 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}")
            break
    return 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.kler.cn/a/526461.html

相关文章:

  • Ubuntu安装VMware17
  • 论文阅读(九):通过概率图模型建立连锁不平衡模型和进行关联研究:最新进展访问之旅
  • 基于Flask的旅游系统的设计与实现
  • STM32 TIM输入捕获 测量频率
  • 7. 马科维茨资产组合模型+金融研报AI长文本智能体(Qwen-Long)增强方案(理论+Python实战)
  • LeetCode热题100中 17. 20. 53. 78. 215.
  • 第27章 苏睿所长的关键沟通
  • CS1.5在Win10下有声音黑屏无图像如何设置
  • dify实现原理分析-rag-数据检索的实现
  • 基于强化学习的机器人自主导航与避障
  • 初阶数据结构:链表(二)
  • 电梯系统的UML文档14
  • 10.共享内存 信号量集 消息队列
  • 【2】阿里面试题整理
  • windows怎么查看进程运行时的参数?
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.22 形状操控者:转置与轴交换的奥秘
  • (●ˇ∀ˇ●)思维导图计划~~~
  • 进阶数据结构——高精度运算
  • 探索性测试与自动化测试的结合
  • android 音视频系列引导
  • Python3 【集合】项目实战:3 个新颖的学习案例
  • 【笑着写算法系列】二分查找
  • 在 WSL2 中重启 Ubuntu 实例
  • 特殊Token区域与共享区域
  • 分享|借鉴传统操作系统中分层内存系统的理念(虚拟上下文管理技术)提升LLMs在长上下文中的表现
  • LINUX部署微服务项目步骤