13.梯度下降法的代码实战——举足轻重的模型优化算法

news2025/4/11 14:44:26

引言

通过12.梯度下降法的具体解析——举足轻重的模型优化算法-CSDN博客的学习,我们已经了解到了梯度下降法的整体流程与不同分类。归根结底,我们最终是要使用代码实现梯度下降法。

通过阅读本篇博客,你可以:

1.知晓轮次和批次的定义

2.使用代码实现不同的梯度下降法

一、轮次和批次

1.轮次的定义

轮次(epoch)指的是整个训练数据集被完整使用一次的过程。一个轮次就是指所有的训练样本训练模型一次。在这里就表明了我们使用梯度下降法中模型遍历整个训练样本的次数。

2.轮次在梯度下降法中的应用

通常情况下,一个训练过程会设置多个轮次。例如,如果我们设定进行10个轮次,模型就会遍历整个训练集10次,每次都尝试优化参数以降低损失函数。

3.批次的定义

批次(batch)是指在一次参数更新中使用的样本数量。在训练过程中,批次可以根据数据集的大小和内存的限制进行调整。一个批次通常只包括训练集的一部分。

4.批次在梯度下降法中的应用

在梯度下降法中,批次指我们已有的训练集数据较多的时候,一轮要学习太多的数据,那就把一轮此的数据分成多个批次,一批一批的学习。

二、全量梯度下降的代码实现

1.创建数据集

import numpy as np
#创建数据集
X = np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]

我们导入numpy模块,使用其中的 random 方法创建数据集 X 和 y ,由于 \omega_{0} 的存在,我们需要拼接一列全为1的数据到矩阵上去,最后就形成了数据集 X_b 。(代码中 \omega_{0} = 4 , \omega _{1} = 3 )

2.设置超参数

# 创建超参数
learning_rate = 0.0001
n_iterations = 10000

我们通常将学习率设置为0.001,0.0001等较为小的数字。通过较大的迭代次数保证函数能够收敛。

3.初始化theta

#初始化theta,W0,...Wn,标准正太分布创建W
theta = np.random.randn(2, 1)

 由于数据集中只有 \omega_{1} 一个维度,再算上截距项 \omega_{0} 。我们就可以使用 random 方法随机创建一个两行一列的 \theta 作为梯度下降的参数。

4.进行参数更新迭代

#进行迭代
for _ in range(n_iterations):
    # 求梯度,计算gradient
    gradients = X_b.T.dot(X_b.dot(theta) - y)
    # 应用梯度下降法的公式调整theta值 theta_t+1 = theta_t - η * gradient
    theta = theta - learning_rate * gradients

 我们开始进行参数更新的迭代,每次迭代中,我们要计算梯度的大小和更新参数。由梯度计算公式 gradient_{j} = (h_{\theta}x - y ) \cdot x_{j} 可以得出代码中梯度计算的实现(由于同行同列的矩阵运算不能直接相乘,所以我们使用 X_b 的转置相乘)。由梯度下降法公式 W_{j}^{t+1} = W_{j}^{t} - \eta \cdot gradient_{j} 可以得出代码中的参数更新的实现。(公式的原理请参考12.梯度下降法的具体解析——举足轻重的模型优化算法-CSDN博客)

5.整体代码

import numpy as np

# 创建数据集X,y
X = np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# 创建超参数
learning_rate = 0.0001
n_iterations = 10000
# 初始化theta,W0,...Wn,标准正太分布创建W
theta = np.random.randn(2, 1)
print(theta)
# 判断是否收敛,一般不会设定阈值,而是直接采用设置相对大的迭代次数保证收敛
for _ in range(n_iterations):
    # 求梯度,计算gradient
    gradients = X_b.T.dot(X_b.dot(theta) - y)
    # 应用梯度下降法的公式调整theta值 theta_t+1 = theta_t - η * gradient
    theta = theta - learning_rate * gradients
print(theta)

三、随机梯度下降的代码实现

1.创建数据集

import numpy as np

# 创建数据集X,y
X = 2 * np.random.rand(100, 1)
y = 5 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]

创建数据集这边的代码实现原理与全量梯度下降一模一样。

2.设置超参数

# 设置超参数
n_epochs = 10000
m = 100
learning_rate = 0.001

同样地,我们仍将轮次设置为10000。不同地是,随机梯度下降每个批次只使用一个随机的样本,所以我们要使用 m 来代表总样本数100,以代表每个轮次下批次的总数。

3.初始化theta

theta = np.random.randn(2, 1)

与全量梯度下降一致。 

4.进行参数更新迭代

# 每一个轮次
for epoch in range(n_epochs):
    # 在每个轮次开始之前分彼此迭代之前打乱数据索引顺序
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    # 每一个批次
    for i in range(m):
        xi = X_b[i: i + 1]
        yi = y[i: i + 1]
        # 求梯度
        gradients = xi.T.dot(xi.dot(theta) - yi)
        theta = theta - learning_rate * gradients

 随机梯度下降除了每个轮次需要遍历,还要对每个批次进行遍历。那么这里就会产生一个值得思考的问题:"我们有什么方法在每一个轮次遍历到所有样本的情况下还保持随机性呢?"。在提出这个问题之后,我想到了一种解决方案,就是在批次遍历之前,使用 random.shuffle 方法将数组的索引进行随机打乱,在每个批次遍历的时候按照打乱索引的顺序进行遍历。这样就可以取巧的解决这个问题。

5.整体代码

import numpy as np

# 创建数据集X,y
X = 2 * np.random.rand(100, 1)
y = 5 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# 设置超参数
n_epochs = 10000
m = 100
learning_rate = 0.001
# 初始化theta
theta = np.random.randn(2, 1)
# 每一个轮次
for epoch in range(n_epochs):
    # 在每个轮次开始之前分彼此迭代之前打乱数据索引顺序
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    # 每一个批次
    for i in range(m):
        xi = X_b[i: i + 1]
        yi = y[i: i + 1]
        # 求梯度
        gradients = xi.T.dot(xi.dot(theta) - yi)
        theta = theta - learning_rate * gradients
print(theta)

四、小批量梯度下降的代码实现

1.创建数据集

import numpy as np

# 设置数据集X,y
X = 3 * np.random.rand(100, 1)
y = 10 + 4 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]

大同小异,不再赘述。 

2.设置超参数

# 设置超参数
n_epochs = 10000
m = 100
batch_size = 10
num_batches = int(m / batch_size)
learning_rate = 0.001

小批量梯度下降要设置每个批次中批量的大小,这里我们将其设置为 batch size = 10 。那么每个轮次中需要批次遍历的次数就是 numbatchs = int(m/batchsize) 。使用 int() 的原因是如果无法正好整除,那么我们可以舍弃掉一些多余的样本。这样处理减少了一个多余批次的消耗,并且少量样本的减少并不会对结果产生影响。

3.初始化theta

# 初始化theta
theta = np.random.randn(2, 1)

4.进行参数更新迭代

# 每个轮次
for epoch in range(n_epochs):
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    # 每个批次
    for i in range(num_batches):
        x_batch = X_b[i*batch_size:i*batch_size + batch_size]
        y_batch = y[i*batch_size:i*batch_size + batch_size]
        # 求梯度
        gradients = x_batch.T.dot(x_batch.dot(theta) - y_batch)
        theta = theta - learning_rate * gradients

小批量梯度下降中的参数更新迭代其实与随机梯度下降很类似。改变的只有批次遍历数量和每个批次中数据量的大小与索引。

5.整体代码

import numpy as np

# 设置数据集X,y
X = 3 * np.random.rand(100, 1)
y = 10 + 4 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
# 设置超参数
n_epochs = 10000
m = 100
batch_size = 10
num_batches = int(m / batch_size)
learning_rate = 0.001
# 初始化theta
theta = np.random.randn(2, 1)
# 每个轮次
for epoch in range(n_epochs):
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    # 每个批次
    for i in range(num_batches):
        x_batch = X_b[i*batch_size:i*batch_size + batch_size]
        y_batch = y[i*batch_size:i*batch_size + batch_size]
        # 求梯度
        gradients = x_batch.T.dot(x_batch.dot(theta) - y_batch)
        theta = theta - learning_rate * gradients
print(theta)

总结

本篇博客重点讲解了三种梯度下降法的不同代码实现。希望可以对大家起到作用,谢谢。


关注我,内容持续更新(后续内容在作者专栏《从零基础到AI算法工程师》)!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2211734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity URP 如何实现遮挡显示 (全流程教程)

嗨~~!,熊猫老师又来了 ,这次为大家分享项目中非常实用的一个技术点:遮挡显示。 老规矩,上才艺: 实现原理 :对模型渲染两次。 第一次: 正常渲染物体,深度测试不通过的情况…

【工具】HTTrack:网站一键克隆下载,实现离线浏览与备份的利器

什么是 HTTrack? HTTrack 是一款用于复制完整网站的开源工具,它可以从服务器下载整个网站的内容,包括 HTML 文件、图像、样式表、脚本等资源。通过这种方式,你可以在离线状态下浏览网站,就像在线一样。 HTTrack 支持…

设备台账管理是什么

设备管理对企业至关重要。比如在电子加工企业,高效的设备管理能减少设备故障,提升生产效率,为企业赢得市场竞争优势。设备台账管理作为设备管理的一个核心部分,起着重要的作用。 让我们一起从本篇文章中探索设备台账管理是什么&a…

[STM32] 简单介绍 (一)

文章目录 1.STM32简介2.ARM3.STM32F103ZET6/STM32F103C8T64.STM32命名规则5.STM32最小系统板6.STM32开发方式7.STM32系统架构8.STM32时钟系统9.STM32中断系统10.STM32定时器 1.STM32简介 STM32是ST公司基于ARM Cortex-M内核开发的32位微控制器; STM32常应用在嵌入式…

【最新华为OD机试E卷-支持在线评测】高矮个子排队(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

基于rk356x u-boot版本功能分析及编译相关(一)

🎏技术驱动源于热爱,祝各位学有所成。 文章目录 uboot的分支是next-dev历史版本v2017-09uboot支持DM框架uboot前级pre-loader支持及引导下级uboot分区支持uboot支持固件格式secure bootuboot编译脚本位置build.shuboot/make.shrkbin仓库uboot的分支是next-dev历史版本v2017-…

Xilinx远程固件升级(一)——QuickBoot方案

Xilinx 7系FPGA远程更新方案——QuickBoot方式远程更新bit 一、远程更新背景和架构 对于非ZYNQ系列的常规FPGA来说,对于bit的更新一般使用JTAG进行烧录。而作为商用产品,想要进行OTA升级时,使用JTAG的升级方式显然不适合,因此&a…

数据结构与算法:数组与链表的扩展与应用

数据结构与算法:数组与链表的扩展与应用 数组和链表是数据结构中的基础内容,但它们的变体和扩展在实际应用中同样至关重要。通过深入理解数组和链表的内存布局、动态管理以及高级操作,我们可以更有效地选择和设计适合特定应用场景的数据结构…

分布式事务管理-Seata从入门到精通

一、基本概念 什么是数据库事务? 1、一个操作数据库数据的执行单元 2、到围从开始到结束的多个操作组成 3、事务内的多个操作要么都成功,要么都失败 什么是分布式事务? 1.分布式场景下,完成某一个业务功能可能需要横跨多个服务&#xff0…

NFT Insider #151:The Sandbox 推出 Alpha 第4季;腾讯或将收购育碧

市场数据 加密艺术及收藏品新闻 Beeple 将于 11 月在南京德基美术馆举办个人首展 著名数字艺术家 Beeple 近日在X平台发布视频,宣布将于 2024 年 11 月 14 日在南京德基美术馆举办个人首次展览,名为《Beeple:来自合成未来的故事》。该展览将…

JavaScript进阶--深入面向对象

深入面向对象 编程思想 面向过程:多个步骤> 解决问题 性能较高,适合跟硬件联系很紧密的东西,如单片机 但代码维护成本高,扩展性差 面向对象:问题所需功能分解为一个一个的对象(分工合作)>…

科研杂谈:24年诺奖颁布,AI竟是最终赢家?!

前言 2024年诺贝尔奖的公布引发了全球科学界的广泛关注,尤其是在人工智能(AI)领域的突破性获奖。诺贝尔物理学奖和化学奖相继颁给了在机器学习和蛋白质结构预测上取得重大进展的科学家们,让人们惊讶地看到AI正在迅速改变传统科研…

[Hbase]一 HBase基础

1. HBase简介 1.1 HBase定义 HBase数据模型的关键在于 稀疏、分布式、多维、排序 的映射。其中映射 map指代非关系型数据库的 key-Value结构。 1.2 HBase数据模型 1)Name Space 命名空间,类似于关系型数据库的database 概念,每个命名空间下有多个表。HBase 两个自…

【AI】AIGC浅析

引言 人工智能生成内容(AIGC)正迅速改变我们的生活、学习以及工作的方式。在计算机科学与技术领域、软件开发、大数据、智能网联汽车和车路云一体化行业,AIGC的应用已经成为行业发展的新动力。探讨AIGC对这些领域的影响、对职业技能需求的变化…

[Javase]封装、继承、多态与异常处理

文章目录 一、前言二、封装1、封装的思想2、封装代码层面的体现 三、继承1、继承的概念和好处2、继承代码层面的体现 四、多态1、多态的概念2、多态的好处和三要素2、多态代码层面的体现 五、异常处理1、try-catch-finally结构详解2、throw\throws 一、前言 本文章适合有一定面…

CMake 教程跟做与翻译 4

目录 添加一个option! 添加一个option! option,正如其意,就是选项的意思。我们这里需要演示一下option的做法。 option对于大型的工程必然是非常常见的:一些模块会被要求编译,另一些客户不准备需要这些模块。option就是将这种需…

【LLM KG】浅尝基于LLM的三阶段自动知识图谱构建方法

文章指出,在以前的方法中,使用LLM生成三元组时,必须预定义好schema,假如schema数量很多/复杂,很容易超过LLM的上下文窗口长度。并且,在某些情况下,没有可用的固定预定义schema。 方法 一、EDC…

计算机网络:数据链路层 —— 网络适配器与 MAC 地址

文章目录 网络适配器使用网络适配器网络适配器类型 MAC 地址MAC 地址格式MAC 地址类型MAC 地址发送顺序数据接收MAC 地址泄露问题 网络适配器 要将计算机连接到以太网,需要使用相应的网络适配器(Adapter),网络适配器一般简称为“网卡”。在计…

通信工程学习:什么是SRAM静态随机存取存储器

SRAM:静态随机存取存储器 SRAM,全称为Static Random-Access Memory,即静态随机存取存储器,是一种重要的随机存取存储器类型。以下是对SRAM的详细介绍: 一、定义与特点 定义: SRAM是一种只要保持通电&#…

CSS @规则(At-rules)系列详解___@import规则使用方法

CSS 规则(At-rules)系列详解 ___import规则使用方法 本文目录: 零、时光宝盒 一、import规则定义和用法 二、CSS import语法 2.1、语法格式 2.2、常见形式 2.3、语法说明 三、import使用方法例子 3.1、导入 CSS 规则 3.2、根据媒体查询条件导入 CSS 规则 …