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

【深度学习】—— 自动微分、非标量变量的反向传播、 分离计算、 Python控制流的梯度计算

【深度学习】—— 自动微分

  • 自动微分
    • 一个简单的例子
  • 非标量变量的反向传播
  • 分离计算
  • Python控制流的梯度计算

自动微分

求导是⼏乎所有深度学习优化算法的关键步骤。虽然求导的计算很简单,只需要⼀些基本的微积分。但对于复杂的模型,⼿⼯进⾏更新是⼀件很痛苦的事情(⽽且经常容易出错)。深度学习框架通过⾃动计算导数,即⾃动微分(automatic differentiation)来加快求导。实际中,根据我们设计的模型,系统会构建⼀个计算图(computational graph),来跟踪计算是哪些数据通过哪些操作组合起来产⽣输出。⾃动微分使系统能够随后反向传播梯度。这⾥,反向传播(backpropagate)意味着跟踪整个计算图,填充关于每个参数的偏导数。

一个简单的例子

作为一个演示例子,假设我们想对函数 y = 2 x ⊤ x y = 2\mathbf{x}^\top \mathbf{x} y=2xx 关于列向量 x \mathbf{x} x 求导。首先,我们创建列向量 x \mathbf{x} x 并为其分配一个初始值。

import torch
x = torch.arange(4.0).view(-1, 1)  # 将 x 转换为列向量
x

输出:

tensor([0., 1., 2., 3.])

在我们计算 y y y 关于 x \mathbf{x} x 的梯度之前,我们需要一个地方来存储梯度。重要的是,我们不会在每次对一个参数求导时都分配新的内存。因为我们经常会成千上万次地更新相同的参数,每次都分配新的内存可能很快就会将内存耗尽。注意,一个标量函数关于向量 x \mathbf{x} x 的梯度是向量,并且与 x \mathbf{x} x 具有相同的形状。

x.requires_grad_(True)  # 等价于 x = torch.arange(4.0).view(-1, 1).requires_grad_(True)
x.grad  # 默认值是 None

现在让我们计算 y y y

y = 2 * torch.dot(x, x)  
y

输出:

tensor(28., grad_fn=<MulBackward0>)

x \mathbf{x} x 是一个 4×1 的列向量,计算 x ⊤ x \mathbf{x}^\top \mathbf{x} xx 得到一个标量输出。接下来,我们通过调用反向传播函数来自动计算 y y y 关于 x \mathbf{x} x 每个分量的梯度,并打印这些梯度。

y.backward()
x.grad

输出:

tensor([ 0.,  4.,  8., 12.])

函数 y = 2 x ⊤ x y = 2\mathbf{x}^\top \mathbf{x} y=2xx 关于 x \mathbf{x} x 的梯度应为 4 x 4\mathbf{x} 4x。让我们快速验证这个梯度是否计算正确。

x.grad == 4 * x

输出:

tensor([[True],[True],[True],[True]])

现在让我们计算 x \mathbf{x} x 的另一个函数。

# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
y = x.sum()
y.backward()
x.grad

输出:

tensor([[1.],[1.],[1.],[1.]])

非标量变量的反向传播

y y y 不是标量时,向量 y \mathbf{y} y 关于向量 x \mathbf{x} x 的导数的最自然解释是一个矩阵。对于高阶和高维的 y \mathbf{y} y x \mathbf{x} x,求导的结果可以是一个高阶张量。

然而,虽然这些更奇特的对象确实出现在高级机器学习中(包括深度学习中),但当我们调用向量的反向计算时,我们通常会试图计算一批训练样本中每个组成部分的损失函数的导数。在这里,我们的目的不是计算微分矩阵,而是单独计算批量中每个样本的偏导数之和。

对非标量调用 backward 需要传入一个 gradient 参数,该参数指定微分函数关于 self 的梯度
在我们的例子中,我们只想求偏导数的和,所以传递一个 1 的梯度是合适的。

x.grad.zero_()
y = x * x
# 等价于 y.backward(torch.ones(len(x)))
y.sum().backward()
x.grad

分离计算

有时,我们希望将某些计算移动到记录的计算图之外。例如,假设 y y y 是作为 x x x 的函数计算的,而 z z z 则是作为 y y y x x x 的函数计算的。想象一下,我们想计算 z z z 关于 x x x 的梯度,但由于某种原因,我们希望将 y y y 视为一个常数,并且只考虑到 x x x y y y 被计算后发挥的作用。

在这里,我们可以分离 y y y 来返回一个新变量 u u u,该变量与 y y y 具有相同的值,但丢弃计算图中如何计算 y y y 的任何信息。换句话说,梯度不会向后流经 u u u x x x。因此,下面的反向传播函数计算 z = u ⋅ x z = u \cdot x z=ux 关于 x x x 的偏导数,同时将 u u u 作为常数处理,而不是 z = x ⋅ x ⋅ x z = x \cdot x \cdot x z=xxx 关于 x x x 的偏导数。

x.grad.zero_()
y = x * x
u = y.detach()
z = u * x
z.sum().backward()
x.grad == u

输出:

tensor([True, True, True, True])

由于记录了 y y y 的计算结果,我们可以随后在 y y y 上调用反向传播,得到 y = x ⋅ x y = x \cdot x y=xx 关于 x x x 的导数,即 2 ⋅ x 2 \cdot x 2x

x.grad.zero_()
y.sum().backward()
x.grad == 2 * x

输出:

tensor([True, True, True, True])

以下是根据您提供的内容整理成的 Markdown 源码,使用 LaTeX $ 包裹公式和符号,并确保代码格式正确:

Python控制流的梯度计算

使用自动微分的一个好处是:即使构建函数的计算图需要通过 Python 控制流(例如,条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度。在下面的代码中,while 循环的迭代次数和 if 语句的结果都取决于输入 a a a 的值。

def f(a):b = a * 2while b.norm() < 1000:b = b * 2if b.sum() > 0:c = belse:c = 100 * breturn c

让我们计算梯度。

a = torch.randn(size=(), requires_grad=True)
d = f(a)
d.backward()

我们现在可以分析上面定义的 f f f 函数。请注意,它在其输入 a a a 中是分段线性的。换言之,对于任何 a a a,存在某个常量标量 k k k,使得 f ( a ) = k ⋅ a f(a) = k \cdot a f(a)=ka,其中 k k k 的值取决于输入 a a a。因此,我们可以用 d / a d / a d/a 验证梯度是否正确。

a.grad == d / a

输出:

tensor(True)

• 深度学习框架可以⾃动计算导数:我们⾸先将梯度附加到想要对其计算偏导数的变量上。然后我们记录⽬标值的计算,执⾏它的反向传播函数,并访问得到的梯度。

相关文章:

【深度学习】—— 自动微分、非标量变量的反向传播、 分离计算、 Python控制流的梯度计算

【深度学习】—— 自动微分 自动微分一个简单的例子 非标量变量的反向传播分离计算Python控制流的梯度计算 自动微分 求导是⼏乎所有深度学习优化算法的关键步骤。虽然求导的计算很简单&#xff0c;只需要⼀些基本的微积分。但对于复杂的模型&#xff0c;⼿⼯进⾏更新是⼀件很…...

Java项目实战II基于Java+Spring Boot+MySQL的大学城水电管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 随着大学城规模的不断扩大和学生数量的急剧增加&#xff0c;大学城内的水电管理面临着前所未有的挑战…...

Vue 组件的三大组成部分详解

文章目录 模板&#xff08;template&#xff09;脚本&#xff08;script&#xff09;样式&#xff08;style&#xff09;总结 在 Vue.js 中&#xff0c;组件是构建用户界面的重要基石。一个 Vue 组件通常由三个主要部分组成&#xff1a;模板&#xff08;template&#xff09;、…...

深入理解Java内部类

一、什么是内部类 内部类是定义在另一个类内部的类。内部类与外部类&#xff08;Enclosing Class&#xff09;之间存在着紧密的联系&#xff0c;可以访问外部类的成员变量和方法&#xff0c;这使得它们在某些场景下非常有用。 1.1 内部类的分类 Java中的内部类主要有以下几种…...

fiddler抓包12_篡改请求(请求前断点)

课程大纲 原理 正常“客户端-服务器”通信&#xff0c;即发送请求&#xff0c;接收返回。 Fiddler抓包是「客户端-浏览器」进行交互时&#xff0c;请求和响应都会从Fiddler通过&#xff0c;Fiddler可以捕获并展示。 请求前断点&#xff08;BreakPoint Before Request&#xff0…...

Webpack和GuIp打包原理以及不同

Webpack打包原理 Webpack的打包原理主要基于模块化的概念&#xff0c;它将应用程序中的所有资源&#xff08;如JS、CSS、图片等&#xff09;视为模块&#xff0c;并根据模块间的依赖关系进行静态分析。Webpack会递归地构建一个依赖关系图&#xff08;dependency graph&#xf…...

c++与Python用笛卡尔的心形函数输出爱心

我突然想到输出爱心是否可以用笛卡尔的心形函数 在IDLE里用Python输出下面这个图形 在小熊猫c里用c输出下面这个图形 如果当你要输出这些的时候会怎么办 低级:纯输出 print( ********* ********* ***************** ***************** …...

Mybatis 9种动态 sql 标签使用

MyBatis提供了9种动态SQL标签&#xff1a;trim、where、set、foreach、if、choose、when、otherwise、bind&#xff1b; 1.if 标签 <select id"getUser">select * from User<where><if test" age ! null ">and age > #{age}</if…...

OpenHarmony(鸿蒙南向)——平台驱动开发【PIN】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 PIN即管脚控制器&#xff0c;用于统一管理各SoC的…...

南平自闭症寄宿制学校:让孩子自信绽放

在繁华与喧嚣交织的都市之中&#xff0c;有一片静谧而充满希望的土地——广州星贝育园自闭症儿童寄宿制学校&#xff0c;这里不仅是知识的殿堂&#xff0c;更是自闭症儿童心灵成长的温馨家园。星贝育园&#xff0c;以其独特的教育理念与细致入微的关怀&#xff0c;为这些特殊的…...

汽车总线之---- LIN总线

Introduction LIN总线的简介&#xff0c;对于传统的这种点对点的连接方式&#xff0c;我们可以看到ECU相关的传感器和执行器是直接连接到ECU的&#xff0c;当传感器和执行器的数量较少时&#xff0c;这样的连接方式是能满足要求的&#xff0c;但是随着汽车电控功能数量的不断增…...

Android开发MPAndroidChart两条折线图

Android开发MPAndroidChart两条折线图 Android开发两条折线图效果&#xff0c;还是有一定难度的&#xff0c;难点它的起点不是坐标0的开始&#xff0c;还有数值上有背景图 一、思路&#xff1a; 用的是MPAndroidChart的BarChart 二、效果图&#xff1a; 三、关键代码&#…...

HTML-ES6.0核心技术

1.ES6简介 ECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff0c;是使得 JavaScript 语言可以用来编写复杂的大型应用程序&#xff0c;成为企业级开发语言。ECMAScript 和 JavaScri…...

车间调度问题数学建模与CPLEX优化

完成了这些基础研究工作&#xff0c;整理成文档以供参考 序言... i 第一章 引言... 1 1.1 车间调度问题概述... 1 1.2 车间调度问题分类表示法... 5 1.3 车间调度对制造企业的作用... 6 1.4 本章小结... 7 第二章 CPLEX基础... 8 2.1 CPLEX概述... 8 2.1.1 CPLEX简介.…...

< 基础物理 >

SI国际单位制 常见的公制单位 为什么需要单位&#xff0c;是统一衡量的标准 通过国际单位&#xff0c;以及单位的拓展&#xff0c;以及单位的组合&#xff0c;形成一系列新的测量单位 面积 m^2 速率 m/s 米每二次方秒&#xff0c;m / s, delta表示增量, 每秒移动多少米 加…...

【web开发】Spring Boot 快速搭建Web项目(三)

Date: 2024.08.31 18:01:20 author: lijianzhan 简述&#xff1a;根据上篇原文Spring Boot 快速搭建Web项目&#xff08;二&#xff09;&#xff0c;由于已经搭建好项目初始的框架&#xff0c;以及自动创建了一个启动类文件&#xff08;TestWebApplication.java&#xff09; …...

无人机之战斗机的详解!

一、高性能飞行能力 高速飞行&#xff1a;具备较高的巡航速度和最大飞行速度&#xff0c;以便快速抵达任务区域并灵活应对战场情况。 长航程&#xff1a;拥有足够的航程以执行远程任务&#xff0c;覆盖广阔的作战区域 高升限&#xff1a;能够飞行到较高的高度&#xff0c;以…...

Verilog基础:时序调度中的竞争(四)(描述时序逻辑时使用非阻塞赋值)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言&#xff0c;Verilog HDL常常需要使用语句描述并行执行的电路&#xff0c;但其实在仿真器的底层&#xff0c;这些并行执行的语句是有先后顺序…...

嵌入式边缘计算软硬件开发“1+X”考证建设方案

一、引言 随着物联网、大数据、人工智能等技术的飞速发展&#xff0c;嵌入式边缘计算作为连接物理世界与数字世界的桥梁&#xff0c;其重要性日益凸显。为了适应行业对高技能人才的需求&#xff0c;推动嵌入式边缘计算技术的普及与应用&#xff0c;特制定本“1X”考证建设方案…...

ES8的Java API client 8.0 简单示例操作 Elasticsearch

1.加入依赖 <dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.12.2</version></dependency>2.配置类 Slf4j Configuration public class ElasticSearchConfig {Valu…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...