Python 梯度下降法(五):Adam Optimize
文章目录
- Python 梯度下降法(五):Adam Optimize
- 一、数学原理
- 1.1 介绍
- 1.2 符号说明
- 1.3 实现流程
- 二、代码实现
- 2.1 函数代码
- 2.2 总代码
- 2.3 遇到的问题
- 2.4 算法优化
- 三、优缺点
- 3.1 优点
- 3.2 缺点
- 四、相关链接
Python 梯度下降法(五):Adam Optimize
一、数学原理
1.1 介绍
Adam 算法结合了 Adagrad 和 RMSProp 算法的优点。Adagrad 算法会根据每个参数的历史梯度信息来调整学习率,对于出现频率较低的参数会给予较大的学习率,而对于出现频率较高的参数则给予较小的学习率。RMSProp 算法则是对 Adagrad 算法的改进,它通过使用移动平均的方式来计算梯度的平方,从而避免了 Adagrad 算法中学习率单调下降的问题。
1.2 符号说明
| 参数 | 意义 |
|---|---|
| g t = ∇ θ J ( θ t ) g_{t}=\nabla_{\theta}J(\theta_{t}) gt=∇θJ(θt) | 第 t t t时刻的梯度 |
| m t m_{t} mt | 梯度的一阶矩(均值) |
| β 1 \beta_{1} β1 | 一阶矩衰减率,一般取0.9 |
| v t v_{t} vt | 梯度的二阶矩(未中心化的方差) |
| β 2 \beta_{2} β2 | 二阶矩衰减率,一般取0.99 |
| θ \theta θ | 线性拟合参数 |
| η \eta η | 学习率 |
| ϵ \epsilon ϵ | 无穷小量,一般取 1 0 − 8 10^{-8} 10−8 |
1.3 实现流程
- 初始化: θ \theta θ、 η \eta η、 m 0 ⃗ = 0 \vec{m_{0}}=0 m0=0、 v 0 ⃗ = 0 \vec{v_{0}}=0 v0=0
- 计算梯度: g t = ∇ θ J ( θ t ) = 1 m X T L g_{t}=\nabla_{\theta}J(\theta_{t})=\frac{1}{m}X^{T}L gt=∇θJ(θt)=m1XTL
- 梯度的一阶矩估计(均值): m t = β 1 m t − 1 + ( 1 − β 1 ) g t m_{t}=\beta_{1}m_{t-1}+(1-\beta_{1})g_{t} mt=β1mt−1+(1−β1)gt
- 梯度的二阶矩估计(未中心化的方差): v t = β 2 v t − 1 + ( 1 − β 2 ) g t 2 v_{t}=\beta_{2}v_{t-1}+(1-\beta_{2})g_{t}^{2} vt=β2vt−1+(1−β2)gt2
- 偏差修正: m t ^ = m t 1 − β 1 t 、 v t ^ = v t 1 − β 2 t \hat{m_{t}}=\frac{m_{t}}{1-\beta_{1}^{t}}、\hat{v_{t}}=\frac{v_{t}}{1-\beta_{2}^{t}} mt^=1−β1tmt、vt^=1−β2tvt
- 更新参数: θ t = θ t − 1 − η m t ^ v t ^ + ϵ \theta_{t}=\theta_{t-1}-\frac{\eta \hat{m_{t}}}{\sqrt{ \hat{v_{t}} }+\epsilon} θt=θt−1−vt^+ϵηmt^
二、代码实现
2.1 函数代码
# 定义 Adam 函数
def adam_optimizer(X, y, eta, num_iter=1000, beta1=0.8, beta2=0.8, epsilon=1e-8, threshold=1e-8):"""X: 数据 x mxn,可以在传入数据之前进行数据的归一化y: 数据 y mx1eta: 学习率num_iter: 迭代次数beta: 衰减率epsilon: 无穷小threshold: 阈值"""m, n = X.shapetheta, mt, vt, loss_ = np.random.randn(n, 1), np.zeros((n, 1)), np.zeros((n, 1)), [] # 初始化数据for iter in range(num_iter):h = X.dot(theta)err = h - yloss_.append(np.mean((err ** 2) / 2))g = (1 / m ) * X.T.dot(err)# 一阶矩估计mt = beta1 * mt + (1 - beta1) * g# 二阶矩估计vt = beta2 * vt + (1 - beta2) * g ** 2# 偏差修正mt_ = mt / (1 - pow(beta1, (iter + 1))) # 得 + 1 不然在 iter = 0 时,分母为零vt_ = np.abs(vt / (1 - pow(beta2, (iter + 1))))# 更新参数theta = theta - (eta * mt_) / (np.sqrt(vt_) + epsilon)# 检查是否收敛if iter > 1 and abs(loss_[-1] - loss_[-2]) < threshold:print(f"Converged at iteration {iter + 1}")breakreturn theta.flatten(), loss_
2.2 总代码
import numpy as np
import matplotlib.pyplot as plt# 设置 matplotlib 支持中文
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False# 定义 Adam 函数
def adam_optimizer(X, y, eta, num_iter=1000, beta1=0.8, beta2=0.8, epsilon=1e-8, threshold=1e-8):"""X: 数据 x mxn,可以在传入数据之前进行数据的归一化y: 数据 y mx1eta: 学习率num_iter: 迭代次数beta: 衰减率epsilon: 无穷小threshold: 阈值"""m, n = X.shapetheta, mt, vt, loss_ = np.random.randn(n, 1), np.zeros((n, 1)), np.zeros((n, 1)), [] # 初始化数据for iter in range(num_iter):h = X.dot(theta)err = h - yloss_.append(np.mean((err ** 2) / 2))g = (1 / m ) * X.T.dot(err)# 一阶矩估计mt = beta1 * mt + (1 - beta1) * g# 二阶矩估计vt = beta2 * vt + (1 - beta2) * g ** 2# 偏差修正mt_ = mt / (1 - pow(beta1, (iter + 1))) # 得 + 1 不然在 iter = 0 时,分母为零vt_ = np.abs(vt / (1 - pow(beta2, (iter + 1))))# 更新参数theta = theta - (eta * mt_) / (np.sqrt(vt_) + epsilon)# 检查是否收敛if iter > 1 and abs(loss_[-1] - loss_[-2]) < threshold:print(f"Converged at iteration {iter + 1}")breakreturn theta.flatten(), loss_# 生成一些示例数据
np.random.seed(42)
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.01# 运行 Adam 优化器
theta, loss_ = adam_optimizer(X_b, y, eta)print("最优参数 theta:")
print(theta)# 绘制损失函数图像
plt.plot(range(len(loss_)), loss_, label="损失函数图像")
plt.title("损失函数图像")
plt.xlabel("迭代次数")
plt.ylabel("损失值")
plt.legend() # 显示图例
plt.grid(True) # 显示网格线
plt.show()

2.3 遇到的问题
当偏差修正为以下算法时,出现报错:
# 偏差修正mt_ = mt / (1 - pow(beta1, (iter)))vt_ = np.abs(vt / (1 - pow(beta2, (iter))))

进行检验时,我们发现:

mt_,vt_ \text{mt\_,vt\_} mt_,vt_为无穷量,因此考虑分母为零的情况,而当 iter = 0 \text{iter}=0 iter=0时, 1 − β iter = 0 1- \beta^{\text{iter}}=0 1−βiter=0,故说明索引不能从0开始,而应该从1开始,因此引入 iter + 1 \text{iter}+1 iter+1,防止分母的无穷大引入。
2.4 算法优化
由于算法过程中,如果数据量太多会引起资源的严重浪费,因此我们引入小批量梯度下降法的类似方法,批量截取数据来进行拟合。
# 定义 Adam 函数
def adam_optimizer(X, y, eta, num_iter=1000, batch_size=32, beta1=0.8, beta2=0.8, epsilon=1e-8, threshold=1e-8):"""X: 数据 x mxn,可以在传入数据之前进行数据的归一化y: 数据 y mx1eta: 学习率num_iter: 迭代次数batch_size: 小批量分支法的批量数beta: 衰减率epsilon: 无穷小threshold: 阈值"""m, n = X.shapetheta, mt, vt, loss_ = np.random.randn(n, 1), np.zeros((n, 1)), np.zeros((n, 1)), [] # 初始化数据num_batchs = m // batch_sizefor _ in range(num_iter):range_shuffle = np.random.permutation(m)X_shuffled = X[range_shuffle]y_shuffled = y[range_shuffle]loss_temp = []for iter in range(num_batchs):start_index = batch_size * iterend_index = start_index + batch_sizexi = X_shuffled[start_index:end_index]yi = y_shuffled[start_index:end_index]h = xi.dot(theta)err = h - yiloss_temp.append(np.mean((err ** 2) / 2))g = (1 / m ) * xi.T.dot(err)# 一阶矩估计mt = beta1 * mt + (1 - beta1) * g# 二阶矩估计vt = beta2 * vt + (1 - beta2) * g ** 2# 偏差修正mt_ = mt / (1 - pow(beta1, (iter + 1)))vt_ = np.abs(vt / (1 - pow(beta2, (iter + 1))))# 更新参数theta = theta - (eta * mt_) / (np.sqrt(vt_) + epsilon)loss_.append(np.mean(loss_temp))# 检查是否收敛if _ > 1 and abs(loss_[-1] - loss_[-2]) < threshold:print(f"Converged at iteration {iter + 1}")breakreturn theta.flatten(), loss_

使用小批量进行Adam优化,可以大大节省系统的资源。
三、优缺点
3.1 优点
对不同参数调整学习率:Adam 能够为模型的每个参数自适应地调整学习率。它会根据参数的梯度历史信息,对出现频率较低的参数给予较大的学习率,对出现频率较高的参数给予较小的学习率。这使得模型在训练过程中能够更好地处理不同尺度和变化频率的参数,加速收敛过程。
无需手动精细调整:在很多情况下,Adam 算法提供的默认超参数就能取得不错的效果,不需要像传统优化算法那样进行大量的手动调参,节省了时间和精力。
低内存需求:Adam 只需要存储梯度的一阶矩估计(均值)和二阶矩估计(未中心化的方差),不需要像一些二阶优化方法那样存储复杂的海森矩阵(Hessian matrix),因此内存占用相对较小,适合处理大规模数据集和深度神经网络。
快速收敛:通过结合梯度的一阶矩和二阶矩信息,Adam 能够更准确地估计梯度的方向和大小,从而在大多数情况下比传统的随机梯度下降(SGD)算法更快地收敛到最优解。
利用稀疏信息:在处理稀疏数据(如自然语言处理中的词向量)时,Adam 能够根据数据的稀疏性调整学习率。对于那些很少出现的特征,算法会给予较大的学习率,使得模型能够更有效地学习这些特征,避免因数据稀疏而导致的学习困难
偏差修正机制:Adam 算法引入了偏差修正机制,用于修正一阶矩和二阶矩估计在训练初期的偏差。这使得算法在训练的早期阶段更加稳定,能够避免因初始估计不准确而导致的训练波动或不收敛问题。
3.2 缺点
自适应特性的局限性:虽然 Adam 能够自适应地调整学习率,但在某些情况下,这种自适应特性可能会导致算法陷入局部最优解。由于学习率会随着训练过程自动调整,可能会在接近局部最优解时过早地降低学习率,使得算法难以跳出局部最优区域,从而无法找到全局最优解。
需要一定的调参经验:尽管 Adam 提供了默认的超参数,但在某些复杂的任务或数据集上,这些默认参数可能不是最优的。例如, β \beta β、 ϵ \epsilon ϵ的取值会影响算法的性能,如果选择不当,可能会导致收敛速度变慢、模型性能下降等问题。因此,在实际应用中,可能仍然需要进行一定的超参数调优。
过度适应训练数据:由于 Adam 算法在训练过程中过于关注梯度的历史信息和自适应调整学习率,可能会导致模型过度适应训练数据,从而降低模型的泛化能力。在某些情况下,使用 Adam 训练的模型在测试集上的表现可能不如使用其他优化算法训练的模型。
四、相关链接
Python 梯度下降法合集:
- Python 梯度下降法(一):Gradient Descent-CSDN博客
- Python 梯度下降法(二):RMSProp Optimize-CSDN博客
- Python 梯度下降法(三):Adagrad Optimize-CSDN博客
- Python 梯度下降法(四):Adadelta Optimize-CSDN博客
- Python 梯度下降法(五):Adam Optimize-CSDN博客
- Python 梯度下降法(六):Nadam Optimize-CSDN博客
- Python 梯度下降法(七):Summary-CSDN博客
相关文章:
Python 梯度下降法(五):Adam Optimize
文章目录 Python 梯度下降法(五):Adam Optimize一、数学原理1.1 介绍1.2 符号说明1.3 实现流程 二、代码实现2.1 函数代码2.2 总代码2.3 遇到的问题2.4 算法优化 三、优缺点3.1 优点3.2 缺点 四、相关链接 Python 梯度下降法(五&a…...
笔试-二进制
应用题 将符合区间[l,r]内的十进制整数转换为二进制表示,请问不包含“101”的整数个数是多少? 实现 l int(input("请输入下限l,其值大于等于1:")) r int(input("请输入上限r,其值大于等于l&#x…...
springboot 2.7.6 security mysql redis jwt配置例子
数据库结构用的是若依的数据库基本结构,ruoyi.vip。 总体参考了文章:https://blog.csdn.net/qq_45847507/article/details/126681110 本文章只包含不同的地方,相同的不再赘述。 1、创建spring工程,jdk1.8,maven。 pom.xml中依赖部…...
FreeRTOS从入门到精通 第十六章(任务通知)
参考教程:【正点原子】手把手教你学FreeRTOS实时系统_哔哩哔哩_bilibili 一、任务通知简介 1、概述 (1)任务通知顾名思义是用来通知任务的,任务控制块中的结构体成员变量ulNotifiedValue就是这个通知值。 (2&#…...
TensorFlow 简单的二分类神经网络的训练和应用流程
展示了一个简单的二分类神经网络的训练和应用流程。主要步骤包括: 1. 数据准备与预处理 2. 构建模型 3. 编译模型 4. 训练模型 5. 评估模型 6. 模型应用与部署 加载和应用已训练的模型 1. 数据准备与预处理 在本例中,数据准备是通过两个 Numpy 数…...
无人机图传模块 wfb-ng openipc-fpv,4G
openipc 的定位是为各种模块提供底层的驱动和linux最小系统,openipc 是采用buildroot系统编译而成,因此二次开发能力有点麻烦。为啥openipc 会用于无人机图传呢?因为openipc可以将现有的网络摄像头ip-camera模块直接利用起来,从而…...
.cc扩展名是什么语言?C语言必须用.c为扩展名吗?主流编程语言扩展名?Java为什么不能用全数字的文件名?
.cc扩展名是什么语言? .cc是C语言使用的扩展名,一种说法是它是c with class的简写,当然C语言使用的扩展名不止.cc和.cpp, 还包含.cxx, .c, .C等,这些在不同编译器系统采用的默认设定不同,需要区分使用。当然,编译器提…...
【MyDB】4-VersionManager 之 3-死锁及超时检测
【MyDB】4-VersionManager 之 3-死锁及超时检测 死锁及超时检测案例背景LockTable锁请求与等待管理 addvm调用addputIntoList,isInList,removeFromList 死锁检测 hasDeadLock方法资源释放与重分配 参考资料 死锁及超时检测 本章涉及代码:top/…...
【Linux】使用管道实现一个简易版本的进程池
文章目录 使用管道实现一个简易版本的进程池流程图代码makefileTask.hppProcessPool.cc 程序流程: 使用管道实现一个简易版本的进程池 流程图 代码 makefile ProcessPool:ProcessPool.ccg -o $ $^ -g -stdc11 .PHONY:clean clean:rm -f ProcessPoolTask.hpp #pr…...
【OpenGL】OpenGL游戏案例(二)
文章目录 特殊效果数据结构生成逻辑更新逻辑 文本渲染类结构构造函数加载函数渲染函数 特殊效果 为提高游戏的趣味性,在游戏中提供了六种特殊效果。 数据结构 PowerUp 类只存储存活数据,实际逻辑在游戏代码中通过Type字段来区分执行 class PowerUp …...
28. 【.NET 8 实战--孢子记账--从单体到微服务】--简易报表--报表定时器与报表数据修正
这篇文章是《.NET 8 实战–孢子记账–从单体到微服务》系列专栏的《单体应用》专栏的最后一片和开发有关的文章。在这片文章中我们一起来实现一个数据统计的功能:报表数据汇总。这个功能为用户查看月度、年度、季度报表提供数据支持。 一、需求 数据统计方面&…...
Java 泛型<? extends Object>
在 Java 泛型中,<? extends Object> 和 <?> 都表示未知类型,但它们在某些情况下有细微的差异。泛型的引入是为了消除运行时错误并增强类型安全性,使代码更具可读性和可维护性。 在 JDK 5 中引入了泛型,以消除编译时…...
FPGA|使用quartus II通过AS下载POF固件
1、将开发板设置到AS下载挡位,或者把下载线插入到AS端口 2、打开quartus II,选择Tools→Programmer→ Mode选择Active Serial Programming 3、点击左侧Add file…,选择 .pof 文件 →start 4、勾选program和verify(可选࿰…...
“新月之智”智能战术头盔系统(CITHS)
新月人物传记:人物传记之新月篇-CSDN博客 相关文章链接(更新): 星际战争模拟系统:新月的编程之道-CSDN博客 新月智能护甲系统CMIA--未来战场的守护者-CSDN博客 目录 一、引言 二、智能头盔控制系统概述 三、系统架…...
php:代码中怎么搭建一个类似linux系统的crontab服务
一、前言 最近使用自己搭建的php框架写一些东西,需要用到异步脚本任务的执行,但是是因为自己搭建的框架没有现成的机制,所以想自己搭建一个类似linux系统的crontab服务的功能。 因为如果直接使用linux crontab的服务配置起来很麻烦࿰…...
【LeetCode: 958. 二叉树的完全性检验 + bfs + 二叉树】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
MinDoc 安装与部署
下载可执行文件 mindoc mindoc_linux_amd64.zip 上传并解压压缩包 cd /opt mkdir mindoc cd mindocunzip mindoc_linux_amd64.zip 创建数据库 CREATE DATABASE mindoc_db DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; 配置数据库 将解压目录下 conf/app.conf.exam…...
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(基础组件实现)
目录 基础组件实现 如何将图像和文字显示到OLED上 如何绘制图像 如何绘制文字 如何获取字体? 如何正确的访问字体 如何抽象字体 如何绘制字符串 绘制方案 文本绘制 更加方便的绘制 字体附录 ascii 6x8字体 ascii 8 x 16字体 基础组件实现 我们现在离手…...
windows系统如何检查是否开启了mongodb服务
windows系统如何检查是否开启了mongodb服务!我们有很多软件开发,网站开发时候需要使用到这个mongodb数据库,下面我们看看,如何在windows系统内排查,是否已经启动了本地服务。 在 Windows 系统上,您可以通过…...
VS安卓仿真器下载失败怎么办?
如果网络不稳定,则VS的安卓仿真器很容易下载失败,如下 Downloaded file <USER_HOME>\AppData\Local\Temp\xamarin-android-sdk\x86_64-35_r08.zip not found for Android SDK archive https://dl.google.com/android/repository/sys-img/google_a…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...
js 设置3秒后执行
如何在JavaScript中延迟3秒执行操作 在JavaScript中,要设置一个操作在指定延迟后(例如3秒)执行,可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法,它接受两个参数: 要执行的函数&…...
