李沐动手学深度学习Pytorch-v2笔记【07自动求导代码实现】

文章目录

    • 前言
    • 自动求导实现
    • 非标量变量的反向传播
    • 分离计算
    • Python控制流的梯度计算

前言

关于走动求导的理论知识个人有点难以理解,推荐大家去看https://blog.csdn.net/weixin_42831564/article/details/135658138这篇文章,讲的很好。

自动求导实现

import torchx = torch.arange(4.0)
print(x)

在这里插入图片描述

x.requires_grad_(True)

在这里插入图片描述

print(x.grad)

在这里插入图片描述

#计算y标量
y = 2 * torch.dot(x, x)
print(y)

在这里插入图片描述

y.backward()
print(x.grad)

在这里插入图片描述

print(x.grad == 4 * x)

在这里插入图片描述

x.grad.zero_(),x

在这里插入图片描述

y = x.sum()
y

在这里插入图片描述

y.backward(),y

在这里插入图片描述

print(x.grad)

在这里插入图片描述
为什么 y = x.sum() 的梯度是全 1?

在这里插入图片描述

非标量变量的反向传播

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

在这里插入图片描述
在这里插入图片描述

为什么 y = x * x 后需要 y.sum().backward()

在 PyTorch 中,backward() 只能对标量(scalar,即 0 维张量)进行反向传播,而不能直接对向量/矩阵进行反向传播。因此:

y = x * x 是一个逐元素乘法,得到的 y 仍然是和 x 形状相同的张量(如 [x₁², x₂², x₃², x₄²])。

如果直接调用 y.backward(),PyTorch 会报错,因为 y 不是标量。

解决方法:y.sum().backward()
为了计算 yx 的梯度,我们需要:

y 变成一个标量(通过 sum()mean() 或其他聚合操作)。

y.sum() 计算 x₁² + x₂² + x₃² + x₄²,得到一个标量。

调用 backward(),PyTorch 会自动计算梯度并存储到 x.grad

分离计算

在某层网络需要把参数固定的时候,会用到这个功能

在PyTorch中,y.detach()是一个用于从计算图中分离张量的方法。计算图是PyTorch用于自动微分的关键概念,用于构建和跟踪张量之间的操作。在计算图中,张量的计算历史被记录下来,以便在反向传播时计算梯度。但有时我们希望从计算图中分离出某个张量,使其不再与原始的计算历史关联。这在某些情况下是很有用的,例如当我们只关心使用该张量进行正向传播的结果,并且不需要计算梯度时。

当调用y.detach()时,将返回一个与y相同数据但不再与计算图关联的新张量。这意味着对返回的张量进行操作不会对原始计算图产生任何影响,也不会计算任何梯度。该方法可用于将张量作为输入传递给不允许梯度传播的函数或模型。

在这里插入图片描述

x.grad.zero_()
y = x * x
u = y.detach()  # 把y看成一个常数赋给u u与x无关,是一个常数
print(u)
z = u * x  # z对x的导数 
z.sum().backward()
print(x.grad)
print(u == x.grad)

在这里插入图片描述

# u是常数不是x的函数,y还是x的函数,还是可以对y求x的导数
x.grad.zero_()
y.sum().backward()
print(x.grad)
print(x.grad == 2*x)

在这里插入图片描述

Python控制流的梯度计算

在这里插入图片描述

def f(a):b = a * 2          # (1) b = 2awhile b.norm() < 1000:b = b * 2      # (2) 循环翻倍,直到 ||b|| ≥ 1000if b.sum() > 0:    # (3) 如果 b 的和 > 0,c = b;否则 c = 100*bc = belse:c = 100 * breturn c           # (4) 返回 ca = torch.randn(size=(), requires_grad=True)  # 随机初始化一个标量 a
d = f(a)                                     # 计算 d = f(a)
d.backward()                                 # 反向传播计算梯度
print(a)        # 打印 a 的值
print(d)        # 打印 d 的值
print(a.grad)   # 打印 a 的梯度
print(d / a)    # 计算 d / a
print(a.grad == d / a)  # 判断梯度是否等于 d / a

torch.randn()是一个用于生成服从标准正态分布(均值为0,标准差为1)的随机数的函数

为什么 a.grad == d / a?
关键在于 da 的关系:

da 的线性函数

无论 while 循环执行多少次,b 都是 a 的倍数(b = a * 2 * 2 * ... * 2)。

if-else 分支只是决定 c = bc = 100 * b,所以 c(即 d)仍然是 a 的倍数。

因此,d 可以表示为:d = k⋅a,其中 k 是一个常数(由 while 循环和 if-else 分支决定)。

梯度计算:

d = k * a 求导:在这里插入图片描述
由于 d = k * a,所以 k = d / a

因此:在这里插入图片描述
PyTorch 的 a.grad 存储的就是这个梯度值,所以 a.grad == d / a

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

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

相关文章

strchr 与 strstr 函数详解

一.strchr - 字符查找函数1.函数原型char *strchr(const char *str, int c);2.核心功能在字符串中查找特定字符的第一次出现位置3.参数说明参数 类型 说明str const char* 要搜索的字符串c int 要查找的字符&#xff08;自动转换为char&#xff09;4.返回值…

jakes信道模型

Jakes 模型 前面我们介绍了多径信道合成信号可表示为&#xff1a; r(t)Re{∑i0N(t)−1ai(t)u(t−τi(t))ej2πfc(t−τi(t))ϕDi(t)} r(t)Re \left\{\sum_{i0}^{N(t)-1}a_{i}(t)u(t-\tau_{i}(t))e^{j2\pi f_{c}(t-\tau_{i}(t))\phi_{D_{i}}(t)} \right\} r(t)…

JVM类加载机制解析

什么是类加载器&#xff1f; 类加载器是JVM的核心组件之一&#xff0c;负责将Java字节码文件&#xff08;.class文件&#xff09;加载到JVM内存中。由于JVM只能执行二进制字节码&#xff0c;类加载器的作用就是将编译后的.class文件转换为JVM可以理解和执行的格式&#xff0c;使…

用Python和OpenCV从零搭建一个完整的双目视觉系统(二)

本系列文章旨在系统性地阐述如何利用 Python 与 OpenCV 库&#xff0c;从零开始构建一个完整的双目立体视觉系统。 本项目github地址&#xff1a;https://github.com/present-cjn/stereo-vision-python.git 项目架构设计&#xff1a;蓝图、分工与工作流 在上一篇文章中&#…

亿级流量下的缓存架构设计:Redis+Caffeine多级缓存实战

亿级流量下的缓存架构设计&#xff1a;RedisCaffeine多级缓存实战 一、为什么需要多级缓存&#xff1f; 在亿级流量场景下&#xff0c;单纯依赖Redis会遇到三大瓶颈&#xff1a;网络延迟&#xff1a;Redis远程访问通常需要1-5ms&#xff0c;QPS超过10万时成为瓶颈资源成本&…

AI基建还能投多久?高盛:2-3年不是问题,回报窗口才刚开启

高盛表示&#xff0c;尽管AI商业化变现仍处早期阶段&#xff0c;但基于成本削减的第一阶段回报已经显现。预测到2030年AI自动化可为财富500强企业节省约9350亿美元成本。分析师认为&#xff0c;这一早期收益足以支撑当前AI基础设施投资水平&#xff0c;尽管增长率可能放缓。虽然…

【mac】快捷键使用指南

在Mac上&#xff0c;根据选择对象的不同&#xff0c;在选择时移动的方法也有所不同&#xff0c;以下是具体介绍&#xff1a; 移动文件或文件夹&#xff1a;可通过拖放操作移动。打开“访达”&#xff08;Finder&#xff09;&#xff0c;找到要移动的文件或文件夹&#xff0c;按…

CS144 lab2 tcp_receiver

1. 实验目的 lab2 的目的是实现tcp的接收端。 主要包括两方面 &#xff08;1&#xff09; 从发送端接收消息&#xff0c;使用Reassembler聚合字节流&#xff08;Bytestream&#xff09; &#xff08;2&#xff09;将确认号&#xff08;ackno&#xff09;和window size发回对端 …

【论文笔记】A Deep Reinforcement Learning Based Real-Time Solution Policy for the TSP

《基于 DRL 和 DCNN 的实时 TSP 求解策略》IEEE TRANSACTIONS ON INTELLIGENT TRANSPORTATION SYSTEMS, VOL. 24, NO. 6, JUNE 2023一段话总结本文提出了一种基于深度强化学习&#xff08;DRL&#xff09; 和深度卷积神经网络&#xff08;DCNN&#xff09; 的实时旅行商问题&am…

MMaDA:多模态大型扩散语言模型

集众家之所长&#xff0c;成大一统。普林斯顿大学、北京大学、清华大学、字节跳动的研究者将“文本推理、多模态分析、图像生成”三大方向融合在一个单一扩散模型里&#xff0c;并用恰当的优化策略来提升模型在各个方向的性能。 研究动机 研究人员致力于开发一个能够处理多种模…

容器技术入门与Docker环境部署

容器技术入门与Docker环境部署Docker概述什么是 DockerDocker 的优势Docker 的应用场景Docker 核心概念(1)镜像(2)容器(3)仓库Docker 安装1.关闭系统防火墙和内核2.下载Docker的repo文件3.替换仓库地址4.更新索引文件并安装Docker5.添加国内镜像站6.开启Docker服务7.优化内核参…

【01】MFC入门到精通—— MFC新建基于对话框的项目 介绍(工作界面、资源视图 、类视图)

文章目录1 创建工程2 运行3 工作界面介绍3. 1 类视图 Class View3.2 如何打开 类视图3.3 资源视图1 创建工程 选择菜单项 文件->新建->项目&#xff0c;弹出 “新项目” 对话框。 选择 MFC&#xff0c;点击下一步&#xff0c;然后键入工程名称&#xff0c;本例取名“Add…

2025!在Windows的Python中安装GDAL包(小白能成!)

最近更新 在2025.06.05日&#xff0c;GDAL发布预告&#xff1a;新版本将适配pipeline和向量读写功能。 直到2025.06.25日&#xff0c;最新的版本才算发行出来。 有朋友催我赶紧更新教程&#xff0c;我上次更新是3月份的时候了&#xff0c;恰好是GDAL上一个版本出来的时间。 前…

Python第一次作业

# 1.技术面试题**&#xff08;1&#xff09;TCP与UDP的区别是什么&#xff1f;****答&#xff1a;TCP 是 “可靠但较慢” 的协议&#xff0c;适合对数据完整性要求高的场景&#xff1b;UDP 是 “快速但不可靠” 的协议&#xff0c;适合对实时性要求高的场景。两者互补&#xff…

Linux【大数据运维】下制作Redis绿色免安装包(一)

linux下安装Redis比较繁琐&#xff0c;遇到内网部署环境更是麻烦。根据经验将Redis打包一个绿色版进行使用。 大体思路&#xff0c;在一台正常的机器上面制造好安装包&#xff0c;然后上传到内网服务器&#xff0c;解压使用。 下载&#xff1a; wget https://download.redis…

89104 PCIe Switch芯片国产替代 - PCIE5.0国产AI服务器高性能扩展,支持海光/龙芯/飞腾等

以下是针对89104 PCIe Switch芯片国产替代的高性能PCIe 5.0 AI服务器扩展方案的详细分析&#xff1a;一、核心国产替代芯片&#xff1a;TL63104控制器‌技术规格‌支持PCIe 5.0全速率&#xff08;32 GT/s&#xff09;&#xff0c;提供968 Lanes配置&#xff0c;聚合双向带宽达1…

Docker跨架构部署实操

需求场景 python项目&#xff0c;开发环境以及可供测试的环境为X86架构下的LINUX服务器&#xff0c;但正式环境需要部署在ARM架构下的麒麟服务器&#xff0c;且正式环境后续可能会长时间处于断网状态&#xff0c;需要一份跨架构的部署方案。 解决思路 在 X86 上打包、在 ARM&am…

JavaScript 树形菜单总结

树形菜单是前端开发中常见的交互组件,用于展示具有层级关系的数据(如文件目录、分类列表、组织架构等)。以下从核心概念、实现方式、常见功能及优化方向等方面进行总结。 一、核心概念 层级结构:数据以父子嵌套形式存在,如{ id: 1, children: [{ id: 2 }] }。节点:树形结…

【python实用小脚本-131】Python 实现 HTML 到 PDF 转换:解决文档处理痛点的高效工具

引言 在当今数字化办公环境中&#xff0c;文档格式的转换需求日益频繁。假设你是一位市场营销人员&#xff0c;需要将公司网站的产品介绍页面&#xff08;HTML 格式&#xff09;转换为 PDF 文档&#xff0c;以便用于线下宣传。然而&#xff0c;手动复制粘贴内容并调整格式不仅…

【Linux操作系统】简学深悟启示录:Linux基本指令

文章目录1.什么是操作系统&#xff1f;2.Xshell的使用3.常用指令3.1 ls指令3.2 pwd指令3.3 cd指令3.4 touch指令3.5 mkdir指令3.6 rmdir指令 && rm指令3.7 man指令3.8 cp指令3.9 mv指令3.10 cat指令3.11 echo指令&#xff08;重定向&#xff09;3.12 more指令3.13 less…