【深度学习】 自动微分
自动微分
正如上节所说,求导是几乎所有深度学习优化算法的关键步骤。
虽然求导的计算很简单,只需要一些基本的微积分。
但对于复杂的模型,手工进行更新是一件很痛苦的事情(而且经常容易出错)。
深度学习框架通过自动计算导数,即自动微分(automatic differentiation)来加快求导。
实际中,根据设计好的模型,系统会构建一个计算图(computational graph),
来跟踪计算是哪些数据通过哪些操作组合起来产生输出。
自动微分使系统能够随后反向传播梯度。
这里,反向传播(backpropagate)意味着跟踪整个计算图,填充关于每个参数的偏导数。
一个简单的例子
作为一个演示例子,(假设我们想对函数 y = 2 x ⊤ x y=2\mathbf{x}^{\top}\mathbf{x} y=2x⊤x关于列向量 x \mathbf{x} x求导)。
首先,我们创建变量x
并为其分配一个初始值。
import torchx = torch.arange(4.0)
x
[在我们计算 y y y关于 x \mathbf{x} x的梯度之前,需要一个地方来存储梯度。]
重要的是,我们不会在每次对一个参数求导时都分配新的内存。
因为我们经常会成千上万次地更新相同的参数,每次都分配新的内存可能很快就会将内存耗尽。
注意,一个标量函数关于向量 x \mathbf{x} x的梯度是向量,并且与 x \mathbf{x} x具有相同的形状。
x.requires_grad_(True) # 等价于x=torch.arange(4.0,requires_grad=True)
x.grad # 默认值是None
在 PyTorch 里,requires_grad 是张量(Tensor)的一个属性,用于表明是否要对该张量进行梯度计算。若 requires_grad 为 True,那么在后续的计算中,PyTorch 会自动追踪与该张量相关的所有运算,并且可以通过反向传播算法计算其梯度。
(现在计算 y y y。)
y = 2 * torch.dot(x, x)
y
在 PyTorch 里,
torch.dot
函数用于计算两个一维张量(也就是向量)的点积。点积的计算规则是将两个向量对应位置的元素相乘,然后把这些乘积相加。在代码里,torch.dot(x, x)
计算的是向量x
与自身的点积。假设x = [x₁, x₂, x₃, ..., xₙ]
,那么torch.dot(x, x)
的结果就是 x 1 2 + x 2 2 + x 3 2 + . . . + x n 2 x_1^2 + x_2^2 + x_3^2 + ... + x_n^2 x12+x22+x32+...+xn2
grad_fn=<MulBackward0>
表明y
是经过乘法操作得到的,并且可以进行反向传播来计算梯度。
x
是一个长度为4的向量,计算x
和x
的点积,得到了我们赋值给y
的标量输出。接下来,[通过调用反向传播函数来自动计算y
关于x
每个分量的梯度],并打印这些梯度。
y.backward()#计算并存储 y 关于 x 的梯度
x.grad#访问梯度值
y.backward()
这行代码的作用是执行反向传播算法。反向传播的核心目的是计算标量 y 关于所有具有requires_grad=True
的输入张量(这里就是 x)的梯度。它会根据链式法则,从 y 开始逆向计算每个中间变量和输入变量的梯度,并将这些梯度存储在相应张量的 grad 属性中。
x.grad
用于获取张量 x 的梯度。在调用y.backward()
之前,x.grad
的值通常为None
。调用y.backward()
之后,PyTorch 会计算并存储 y 关于 x 的梯度,此时通过x.grad
就可以访问到这些梯度值。
函数 y = 2 x ⊤ x y=2\mathbf{x}^{\top}\mathbf{x} y=2x⊤x关于 x \mathbf{x} x的梯度应为 4 x 4\mathbf{x} 4x。
让我们快速验证这个梯度是否计算正确。
x.grad == 4 * x
[现在计算x
的另一个函数。]
# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
y = x.sum()
y.backward()
x.grad
x.grad.zero_()
在 PyTorch 里,当我们进行多次反向传播时,梯度会累积在 x.grad 中。x.grad.zero_() 这行代码是一个原地操作,其作用是将 x 的梯度清零,以避免之前的梯度对当前计算产生影响。
非标量变量的反向传播
当y
不是标量时,向量y
关于向量x
的导数的最自然解释是一个矩阵。
对于高阶和高维的y
和x
,求导的结果可以是一个高阶张量。
然而,虽然这些更奇特的对象确实出现在高级机器学习中(包括[深度学习中]),
但当调用向量的反向计算时,我们通常会试图计算一批训练样本中每个组成部分的损失函数的导数。
这里(我们的目的不是计算微分矩阵,而是单独计算批量中每个样本的偏导数之和。)
# 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。
# 本例只想求偏导数的和,所以传递一个1的梯度是合适的
x.grad.zero_()
y = x * x
# 等价于y.backward(torch.ones(len(x)))
y.sum().backward()
x.grad
分离计算
有时,我们希望[将某些计算移动到记录的计算图之外]。
例如,假设y
是作为x
的函数计算的,而z
则是作为y
和x
的函数计算的。
想象一下,我们想计算z
关于x
的梯度,但由于某种原因,希望将y
视为一个常数,
并且只考虑到x
在y
被计算后发挥的作用。
这里可以分离y
来返回一个新变量u
,该变量与y
具有相同的值,
但丢弃计算图中如何计算y
的任何信息。
换句话说,梯度不会向后流经u
到x
。
因此,下面的反向传播函数计算z=u*x
关于x
的偏导数,同时将u
作为常数处理,
而不是z=x*x*x
关于x
的偏导数。
x.grad.zero_()
y = x * x
u = y.detach()
z = u * xz.sum().backward()
x.grad == u
detach() 方法用于从计算图中分离出一个张量。调用 y.detach() 会返回一个新的张量 u,这个新张量和 y 具有相同的数据,但它不会再与原计算图产生关联,即不会再参与反向传播。也就是说,在后续的计算中,PyTorch 不会追踪 u 的梯度。
由于记录了y
的计算结果,我们可以随后在y
上调用反向传播,
得到y=x*x
关于的x
的导数,即2*x
。
x.grad.zero_()
y.sum().backward()
x.grad == 2 * x
Python控制流的梯度计算
使用自动微分的一个好处是:
[即使构建函数的计算图需要通过Python控制流(例如,条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度]。
在下面的代码中,while
循环的迭代次数和if
语句的结果都取决于输入a
的值。
def f(a):b = a * 2while b.norm() < 1000:b = b * 2if b.sum() > 0:c = belse:c = 100 * breturn c
b.norm() 若不指定参数,默认计算的是 2 - 范数(也被称作欧几里得范数)。对于向量而言,2 - 范数是向量各个元素平方和的平方根;对于矩阵来说,2 - 范数是矩阵的最大奇异值
让我们计算梯度。
a = torch.randn(size=(), requires_grad=True)
d = f(a)
d.backward()
torch.randn 是 PyTorch 里用于生成服从标准正态分布(均值为 0,标准差为 1)的随机数的函数。其语法格式通常为 torch.randn(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False),其中 size 参数用于指定生成张量的形状。
我们现在可以分析上面定义的f
函数。
请注意,它在其输入a
中是分段线性的。
换言之,对于任何a
,存在某个常量标量k
,使得f(a)=k*a
,其中k
的值取决于输入a
,因此可以用d/a
验证梯度是否正确。
a.grad == d / a
相关文章:

【深度学习】 自动微分
自动微分 正如上节所说,求导是几乎所有深度学习优化算法的关键步骤。 虽然求导的计算很简单,只需要一些基本的微积分。 但对于复杂的模型,手工进行更新是一件很痛苦的事情(而且经常容易出错)。 深度学习框架通过自动…...

字节跳动自研HTTP开源框架Hertz简介附使用示例
字节跳动自研 HTTP 框架 Hertz Hertz 是字节跳动自研的高性能 HTTP 框架,专为高并发、低延迟的场景设计。它基于 Go 语言开发,结合了字节跳动在微服务架构中的实践经验,旨在提供更高效的 HTTP 服务开发体验。 1. 背景介绍 随着字节跳动业务…...
skynet 源码阅读 -- 核心概念服务 skynet_context
本文从 Skynet 源码层面深入解读 服务(Service) 的创建流程。从最基础的概念出发,逐步深入 skynet_context_new 函数、相关数据结构(skynet_context, skynet_module, message_queue 等),并通过流程图、结构…...

每日十题八股-2025年1月23日
1.快排为什么时间复杂度最差是O(n^2) 2.快排这么强,那冒泡排序还有必要吗? 3.如果要对一个很大的数据集,进行排序,而没办法一次性在内存排序,这时候怎么办? 4.面试官:你的…...

MongoDB部署模式
目录 单节点模式(Standalone) 副本集模式(Replica Set) 分片集群模式(Sharded Cluster) MongoDB有多种部署模式,可以根据业务需求选择适合的架构和部署方式。 单节点模式(Standa…...

opencv笔记2
图像灰度 彩色图像转化为灰度图像的过程是图像的灰度化处理。彩色图像中的每个像素的颜色由R,G,B三个分量决定,而每个分量中可取值0-255,这样一个像素点可以有256*256*256变化。而灰度图像是R,G,B三个分量…...
springboot使用ssl连接elasticsearch
使用es时ssl证书报错 unable to find valid certification path to requested target 1.依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>2…...
Linux内核中的InfiniBand核心驱动:verbs.c分析
InfiniBand(IB)是一种高性能、低延迟的网络互连技术,广泛应用于高性能计算(HPC)、数据中心和云计算等领域。Linux内核中的InfiniBand子系统通过提供一组核心API(称为Verbs API)来支持InfiniBand设备的操作。drivers/infiniband/core/verbs.c是InfiniBand核心驱动的重要组…...
把网站程序数据上传到服务器的方法和注意事项
将网站程序数据上传到服务器是一个常见的网站开发和部署流程。主要涉及到FTP上传、FileZilla、rsync(在Linux下)、或其他相关的文件同步工具。以下是一般步骤和方法: 使用FTP: 1. 选择FTP客户端软件: - 常见的FTP客户端包括FileZilla(开源)、…...

完全平方数——唯一分解定理
文章目录 一、唯一分解定理是什么?1.定义2.示例3.代码模板 二、例题1>问题描述(2021蓝桥杯省赛)输入格式输出格式样例输入 1样例输出 1样例输入 2样例输出 2评测用例规模与约定 2>解题思路3>假娃3>C嘎嘎 一、唯一分解定理是什么&…...

(详细)Springboot 整合动态多数据源 这里有mysql(分为master 和 slave) 和oracle,根据不同路径适配不同数据源
文章目录 Springboot 整合多动态数据源 这里有mysql(分为master 和 slave) 和oracle1. 引入相关的依赖2. 创建相关配置文件3. 在相关目录下进行编码,不同路径会使用不同数据源 Springboot 整合多动态数据源 这里有mysql(分为maste…...

mock可视化生成前端代码
介绍:mock是我们前后端分离的必要一环、ts、axios编写起来也很麻烦。我们就可以使用以下插件,来解决我们的问题。目前支持vite和webpack。(配置超级简单!) 欢迎小伙伴们提issues、我们共建。提升我们的开发体验。 vi…...

Spring Boot(6)解决ruoyi框架连续快速发送post请求时,弹出“数据正在处理,请勿重复提交”提醒的问题
一、整个前言 在基于 Ruoyi 框架进行系统开发的过程中,我们常常会遇到各种有趣且具有挑战性的问题。今天,我们就来深入探讨一个在实际开发中较为常见的问题:当连续快速发送 Post 请求时,前端会弹出 “数据正在处理,请…...

鸿蒙Harmony json转对象(1)
案例1 运行代码如下 上图的运行结果如下: 附加1 Json_msg interface 案例2 import {JSON } from kit.ArkTS; export interface commonRes {status: numberreturnJSON: ESObject;time: string } export interface returnRes {uid: stringuserType: number; }Entry Component …...
常见的RocketMQ面试题及其简要答案
以下是一些常见的RocketMQ面试题及其简要答案: 一、基础概念与架构 简述RocketMQ是什么,并说明其主要作用。 答案: RocketMQ:是阿里巴巴在2012年开源的一款分布式消息中间件,目前已经捐赠给Apache软件基金会ÿ…...
C#Object类型的索引,序列化和反序列化
前言 最近在编写一篇关于标准Mes接口框架的文章。其中有一个非常需要考究的内容时如果实现数据灵活和可使用性强。因为考虑数据灵活性,所以我一开始选取了Object类型作为数据类型,Object作为数据Value字段,String作为数据Key字段,…...
Unity3D项目开发中的资源加密详解
前言 在Unity3D游戏开发中,保护游戏资源不被非法获取和篡改是至关重要的一环。资源加密作为一种有效的技术手段,可以帮助开发者维护游戏的知识产权和安全性。本文将详细介绍Unity3D项目中如何进行资源加密,并提供相应的技术详解和代码实现。…...

微调Qwen2:7B模型,加入未知信息语料
对于QWen2这样的模型,在微调的时候,语料的投喂格式满足ChatML这样的格式!!! OpenAI - ChatML: 下面是ChatML格式的介绍: https://github.com/openai/openai-python/blob/release-v0.28.0/chatml.mdhttps://github.com/openai/openai-python/blob/release-v0.28.0/chat…...

【Ubuntu】安装SSH启用远程连接
【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端: sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端: sudo systemctl start ssh贰、配置SSH(可跳过) 配置文件 …...

【理论】测试开发工程师进阶路线
一、腾讯与阿里的质量保证服务参考 阿里云效测试能力与架构 腾讯 WeTest 测试能力全景图 二、测试开发技术体系 1.用户端测试: Web/App 测试 Web/App 自动化测试 用户端专项测试 用户端安全测试 2.服务端测试: 接口协议与 Mock 接口自动化测试 服务端…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...