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

Python 梯度下降法(二):RMSProp Optimize

文章目录

  • Python 梯度下降法(二):RMSProp Optimize
    • 一、数学原理
      • 1.1 介绍
      • 1.2 公式
    • 二、代码实现
      • 2.1 函数代码
      • 2.2 总代码
    • 三、代码优化
      • 3.1 存在问题
      • 3.2 收敛判断
      • 3.3 函数代码
      • 3.4 总代码
    • 四、优缺点
      • 4.1 优点
      • 4.2 缺点

Python 梯度下降法(二):RMSProp Optimize

结合第一篇文章一起看:Python 梯度下降法(一):Gradient Descent-CSDN博客

一、数学原理

1.1 介绍

RMSProp(Root Mean Square Propagation)是一种自适应学习率优化算法,广泛用于深度学习中的梯度下降优化。它通过调整每个参数的学习率来解决传统梯度下降法中学习率固定的问题,从而加速收敛并提高性能。

RMSProp 的核心思想是对每个参数的学习率进行自适应调整。它通过维护一个指数加权移动平均(Exponential Moving Average, EMA)的梯度平方值来调整学习率:

  • 对于梯度较大的参数,降低其学习率。
  • 对于梯度较小的参数,增加其学习率。
    这种方法可以有效缓解梯度下降中的震荡问题,尤其是在非凸优化问题中。

1.2 公式

符号说明:

θ : 需要优化的参数向量 J ( θ ) : 损失函数 g t : 在第 t 次迭代时损失函数关于 θ 的梯度, ∇ θ J ( θ t ) ρ : 衰减率,常用值为 0.9 η : 学习率,需要手动设置 ϵ : 一个及小的参数,无限趋近于零,避免不会出现零 ( 1 0 − 8 ) s t : 指数加权移动平均 \begin{array}{l} \theta&:需要优化的参数向量 \\ J(\theta)&: 损失函数 \\ g_{t}&:在第t次迭代时损失函数关于\theta的梯度,\nabla_{\theta}J(\theta_{t}) \\ \rho &: 衰减率,常用值为0.9\\ \eta&:学习率,需要手动设置 \\ \epsilon&: 一个及小的参数,无限趋近于零,避免不会出现零(10^{-8}) \\ s_{t}&:指数加权移动平均 \end{array} θJ(θ)gtρηϵst:需要优化的参数向量:损失函数:在第t次迭代时损失函数关于θ的梯度,θJ(θt):衰减率,常用值为0.9:学习率,需要手动设置:一个及小的参数,无限趋近于零,避免不会出现零(108):指数加权移动平均

  1. 初始化参数为: θ 0 , s 0 = 0 \theta_{0},s_{0}=0 θ0,s0=0

  2. 迭代更新,每次迭代 t t t中,更新指数加权移动平均:
    s t = ρ s t − 1 + ( 1 − ρ ) g t ⊙ g t s_{t}=\rho s_{t-1}+(1-\rho)g_{t}\odot g_{t} st=ρst1+(1ρ)gtgt s t s_{t} st可以理解为对梯度平方的一个平滑估计,它更关注近期的梯度信息, ρ \rho ρ控制了历史信息的衰减程度。

  3. 计算自适应学习率,公式为 η s t + ϵ \frac{\eta}{\sqrt{ s_{t}+\epsilon }} st+ϵ η,其中,分母 s t + ϵ \sqrt{ s_{t}+\epsilon} st+ϵ 起到了归一化梯度的作用,使得学习率可以更具梯度的尺寸进行自适应的调整。

  4. 更新参数: θ t + 1 = θ t − η s t + ϵ g t \theta_{t+1}=\theta_{t}- \frac{\eta}{\sqrt{ s_{t}+\epsilon }}g_{t} θt+1=θtst+ϵ ηgt

二、代码实现

2.1 函数代码

RMSProp优化算法实现:

# 定义RMSProp优化算法
def rmsprop_optimizer(X, y, eta, num_iter=1000, epsilon=1e-5, rho=0.9):"""X: 数据 x  mxny: 数据 y  nx1eta: 学习率  num_iter: 迭代次数epsilon: 无穷小rho: 衰减率"""m, n = X.shape theta, s = np.zeros((n, 1)), np.zeros((n, 1))  # 初始参数 nx1,以及指数加权移动平均 nx1loss_ = []  # 存储损失率的变化,便于绘图for _ in range(num_iter):# 计算预测值h = np.dot(X, theta)# 计算误差error = h - yloss_.append(np.mean(error**2) / 2)# 计算梯度gradient = (1/m) * np.dot(X.T, error)s = rho * s + (1 - rho) * np.pow(gradient, 2)  # 利用广播机制来进行运算每个维度上的平滑估计theta = theta - np.multiply(eta / np.sqrt(s + epsilon), gradient)  # Hadamar productreturn theta, loss_

2.2 总代码

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 定义RMSProp优化算法
def rmsprop_optimizer(X, y, eta, num_iter=1000, epsilon=1e-5, rho=0.9):"""X: 数据 x  mxny: 数据 y  nx1eta: 学习率  num_iter: 迭代次数epsilon: 无穷小rho: 衰减率"""m, n = X.shape theta, s = np.zeros((n, 1)), np.zeros((n, 1))  # 初始参数 nx1,以及指数加权移动平均 nx1loss_ = []  # 存储损失率的变化,便于绘图for _ in range(num_iter):# 计算预测值h = np.dot(X, theta)# 计算误差error = h - yloss_.append(np.mean(error**2) / 2)# 计算梯度gradient = (1/m) * np.dot(X.T, error)s = rho * s + (1 - rho) * np.pow(gradient, 2)  # 利用广播机制来进行运算每个维度上的平滑估计theta = theta - np.multiply(eta / np.sqrt(s + epsilon), gradient)  # Hadamar productreturn 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.1# RMSProp优化算法
theta, loss_ = rmsprop_optimizer(X_b, y, eta)print("最优参数 theta:")
print(theta)
plt.plot(range(len(loss_)), loss_, label="损失函数图像")
plt.title("损失函数图像")
plt.xlabel("迭代次数")
plt.ylabel("损失值")
plt.show()

1738222496_l1dhye0o4j.png1738222495967.png

可以发现,其对于损失值的下降性能也较好,损失率也较为稳定。

三、代码优化

3.1 存在问题

  • 未使用小批量数据:该代码在每次迭代时使用了全部的训练数据 Xy 来计算梯度,这相当于批量梯度下降的方式。在处理大规模数据集时,这种方式可能会导致计算效率低下,并且可能会陷入局部最优解。可以参考之前小批量梯度下降的代码,引入小批量数据的处理,以提高算法的效率和泛化能力。
  • 缺乏数据预处理:在实际应用中,输入数据 X 可能需要进行预处理,例如归一化或标准化,以确保不同特征具有相似的尺度,从而加快算法的收敛速度。(这里不进行解决,参考特征缩放:数据归一化-CSDN博客)
  • 缺乏收敛判断:代码只是简单地进行了固定次数的迭代,没有设置收敛条件。在实际应用中,可以添加收敛判断,例如当损失值的变化小于某个阈值时提前停止迭代,以节省计算资源。

这里引入Mini-batch Gradient Descent,以及收敛判断,减少计算资源

3.2 收敛判断

# 收敛判断,设定阈值,进行收敛判断
# 满足条件即停止,减少系统资源的使用
if len(loss_) > 1 and abs(loss_[-1] - loss_[-2]) < threshold:print(f"Converged at iteration {_ + 1}")break  # 注意,这里不能使用return

3.3 函数代码

# 定义RMSProp优化算法
def rmsprop_optimizer(X, y, eta, batch_size=32, num_iter=1000, epsilon=1e-5, rho=0.9, threshold=1e-3):"""X: 数据 x  mxn,可以在传入数据之前进行数据的归一化y: 数据 y  nx1eta: 学习率  batch_size: 批量数据的大小num_iter: 迭代次数epsilon: 无穷小rho: 衰减率threshold: 收敛阈值"""m, n = X.shape theta, s = np.zeros((n, 1)), np.zeros((n, 1))  # 初始参数 nx1,以及指数加权移动平均 nx1loss_ = []  # 存储损失率的变化,便于绘图num_batchs = m // batch_sizefor _ in range(num_iter):# 打乱数据集shuffled_indices = np.random.permutation(m)X_shuffled = X[shuffled_indices]y_shuffled = y[shuffled_indices]loss_temp = []  # 存储每次小批量样本生成的值for batch in range(num_batchs):# 选取小批量样本start_index = batch * batch_sizeend_index = start_index + batch_sizexi = X_shuffled[start_index:end_index]yi = y_shuffled[start_index:end_index]# 计算预测值h = np.dot(xi, theta)# 计算误差error = h - yiloss_temp.append(np.mean(error**2) / 2)# 计算梯度gradient = (1/m) * np.dot(xi.T, error)s = rho * s + (1 - rho) * np.pow(gradient, 2)  # 利用广播机制来进行运算每个维度上的平滑估计theta = theta - np.multiply(eta / np.sqrt(s + epsilon), gradient)  # Hadamar productloss_.append(np.mean(loss_temp))# 收敛判断if len(loss_) > 1 and abs(loss_[-1] - loss_[-2]) < threshold:print(f"Converged at iteration {_ + 1}")breakreturn theta, loss_

3.4 总代码

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 定义RMSProp优化算法
def rmsprop_optimizer(X, y, eta, batch_size=32, num_iter=1000, epsilon=1e-5, rho=0.9, threshold=1e-3):"""X: 数据 x  mxn,可以在传入数据之前进行数据的归一化y: 数据 y  nx1eta: 学习率  batch_size: 批量数据的大小num_iter: 迭代次数epsilon: 无穷小rho: 衰减率threshold: 收敛阈值"""m, n = X.shape theta, s = np.zeros((n, 1)), np.zeros((n, 1))  # 初始参数 nx1,以及指数加权移动平均 nx1loss_ = []  # 存储损失率的变化,便于绘图num_batchs = m // batch_sizefor _ in range(num_iter):# 打乱数据集shuffled_indices = np.random.permutation(m)X_shuffled = X[shuffled_indices]y_shuffled = y[shuffled_indices]loss_temp = []  # 存储每次小批量样本生成的值for batch in range(num_batchs):# 选取小批量样本start_index = batch * batch_sizeend_index = start_index + batch_sizexi = X_shuffled[start_index:end_index]yi = y_shuffled[start_index:end_index]# 计算预测值h = np.dot(xi, theta)# 计算误差error = h - yiloss_temp.append(np.mean(error**2) / 2)# 计算梯度gradient = (1/m) * np.dot(xi.T, error)s = rho * s + (1 - rho) * np.pow(gradient, 2)  # 利用广播机制来进行运算每个维度上的平滑估计theta = theta - np.multiply(eta / np.sqrt(s + epsilon), gradient)  # Hadamar productloss_.append(np.mean(loss_temp))  # 使用平均值作为参考# 收敛判断if len(loss_) > 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.1# RMSProp优化算法
theta, loss_ = rmsprop_optimizer(X_b, y, eta)print("最优参数 theta:")
print(theta)
plt.plot(range(len(loss_)), loss_, label="损失函数图像")
plt.title("损失函数图像")
plt.xlabel("迭代次数")
plt.ylabel("损失值")
plt.show()

1738223819_x4hrij0zgr.png1738223818170.png

四、优缺点

4.1 优点

  • 自适应学习率:RMSProp 能够根据参数的梯度变化情况自适应地调整学习率。对于梯度较大的参数,学习率会自动减小;对于梯度较小的参数,学习率会相对增大。这使得算法在处理不同尺度的梯度时更加稳定,有助于加快收敛速度。
  • 缓解 Adagrad 学习率衰减过快问题:与 Adagrad 算法不同,RMSProp 使用指数加权移动平均来计算梯度平方的累积值,避免了 Adagrad 中学习率单调递减且后期学习率过小的问题,使得算法在训练后期仍然能够继续更新参数。

4.2 缺点

  • 对超参数敏感:RMSProp 的性能依赖于超参数 η \eta η ρ \rho ρ的选择。如果超参数设置不当,可能会导致算法收敛速度慢或者无法收敛到最优解。
  • 可能陷入局部最优:和其他基于梯度的优化算法一样,RMSProp 仍然有可能陷入局部最优解,尤其是在损失函数具有复杂的地形时。
http://www.lryc.cn/news/529191.html

相关文章:

  • Android Studio 正式版 10 周年回顾,承载 Androider 的峥嵘十年
  • sem_wait的概念和使用案列
  • 集合的奇妙世界:Python集合的经典、避坑与实战
  • 专业视角深度解析:DeepSeek的核心优势何在?
  • MySQL 索引存储结构
  • 【ComfyUI专栏】如何使用Git命令行安装非Manager收录节点
  • python算法和数据结构刷题[1]:数组、矩阵、字符串
  • 数据分析系列--④RapidMiner进行关联分析(案例)
  • 1/30每日一题
  • vim的多文件操作
  • 设计转换Apache Hive的HQL语句为Snowflake SQL语句的Python程序方法
  • CAPL与外部接口
  • 无公网IP 外网访问 本地部署夫人 hello-algo
  • 实验四 XML
  • Autosar-Os是怎么运行的?(内存保护)
  • 题单:冒泡排序1
  • 多目标优化策略之一:非支配排序
  • Go学习:字符、字符串需注意的点
  • Linux文件原生操作
  • 解决Oracle SQL语句性能问题(10.5)——常用Hint及语法(7)(其他Hint)
  • JavaScript系列(50)--编译器实现详解
  • 大数据相关职位 职业进阶路径
  • 基础项目实战——学生管理系统(c++)
  • C++,STL,【目录篇】
  • 【Rust自学】15.3. Deref trait Pt.2:隐式解引用转化与可变性
  • 密码强度验证代码解析:C语言实现与细节剖析
  • arkts bridge使用示例
  • LINUX部署微服务项目步骤
  • zsh安装插件
  • 网站如何正式上线(运维详解)