《动手学深度学习(PyTorch版)》笔记2

Chapter2 Preliminaries

2.1 Automatic Differentiation

让计算机实现微分功能, 有以下四种方式:
- 手工计算出微分, 然后编码进代码
- 数值微分 (numerical differentiation)
- 符号微分 (symbolic differentiation)
- 自动微分(automatic differentiation)
在这里插入图片描述

深度学习框架通过自动微分来加快求导。
实际中,根据设计好的模型,系统会构建一个计算图(computational graph),来跟踪计算是哪些数据通过哪些操作组合起来产生输出。自动微分使系统能够随后反向传播梯度。这里,反向传播(backpropagate)意味着跟踪整个计算图,填充关于每个参数的偏导数。自动微分以链式法则为基础,将一个复杂的数学运算过程分解为一系列简单的基本运算,把公式中一些部分整理出来成为一些新变量,然后用这些新变量整体替换这个公式,而且每一项基本运算都可以通过查表得出来。自动微分有两种形式

- 前向模式 (forward mode)
- 反向模式 (reverse mode)

前向模式是在计算图前向传播的同时计算微分。下面的前向模式微分中, v i ˙ = ∂ v i ∂ x 1 \dot{v_i}=\frac{\partial v_i}{\partial x_1} vi˙=x1vi
在这里插入图片描述

反向模式需要对计算图进行一次正向计算, 得出输出值,再进行反向传播, 其中 v i ˉ = ∂ y j ∂ v i \bar{v_i}=\frac{\partial y_j}{\partial v_i} viˉ=viyj
在这里插入图片描述

前向模式的一次正向传播能够计算出输出值以及导数值, 而反向模式需要先进行正向传播计算出输出值, 然后进行反向传播计算导数值,所以反向模式的内存开销要大一点, 因为它需要保存正向传播中的中间变量值,这些变量值用于反向传播的时候计算导数。当输出的维度大于输入的时候,适宜使用前向模式微分;当输出维度远远小于输入的时候,适宜使用反向模式微分。

从矩阵乘法次数的角度来看,前向模式和反向模式的不同之处在于矩阵相乘的起始之处不同。当输出维度小于输入维度,反向模式的乘法次数要小于前向模式。
在这里插入图片描述

2.1.1 一个简单的例子

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

import torch
x = torch.arange(4.0)
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,requires_grad=True)
x.grad  # 
y = 2 * torch.dot(x, x)
y

结果:

tensor(28., grad_fn=<MulBackward0>)

x \mathbf{x} x是一个长度为4的向量,计算 x \mathbf{x} x x \mathbf{x} x的点积,得到了我们赋值给y的标量输出。
接下来,通过调用反向传播函数来自动计算y关于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 \mathbf{x} x的另一个函数。

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

结果:

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

2.1.2 非标量变量的反向传播

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

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

# 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。
# 本例只想求偏导数的和,所以传递一个1的梯度是合适的
x.grad.zero_()
y = x * x
y.sum().backward()#等价于y.backward(torch.ones(len(x)))
x.grad

结果:

tensor([0., 2., 4., 6.])

2.1.3 分离计算

有时,我们希望将某些计算移动到记录的计算图之外。例如,假设y是作为x的函数计算的,而z则是作为yx的函数计算的。想象一下,我们想计算z关于x的梯度,但由于某种原因,希望将y视为一个常数,并且只考虑到xy被计算后发挥的作用。这里可以分离y来返回一个新变量u,该变量与y具有相同的值,但丢弃计算图中如何计算y的任何信息。换句话说,梯度不会向后流经ux。因此,下面的反向传播函数计算z=u*x关于x的偏导数,同时将u作为常数处理,而不是z=x*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=x*x关于的x的导数,即2*x

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

结果:

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

2.1.4 Python控制流的梯度计算

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

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

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

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

结果:

    tensor(True)

2.1.5 小结

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

2.1.6 参考文献

  • 一文看懂AD原理
  • AD的正反向模式
  • AD的常用实现方案
  • 反向OO实现自动微分(Pytroch核心机制)
  • Automatic differentiation in machine learning: a survey

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

搜维尔科技:【简报】元宇宙数字人赛道,《莉思菱娜》

个性有些古灵精怪时儿安静时而吵闹&#xff0c;虽然以人类寿命来算已经200多岁但在 吸血鬼中还只是个小毛头&#xff0c;从中学开始喜欢打扮偏爱黑白灰色系的服装喜欢时 尚圈&#xff0c;立志想成为美妆或时尚网红不过目前还是学生&#xff0c;脸上的浅色血迹是纹身 贴纸&#…

Javat集合之Lis---(ArrayList和LinkedList)

文章目录 一、 List概述1.1概念1.2list体系结构图1.3 通用方法测试代码 二、List的特点三、遍历方式foreachfor循环迭代器 四、ArrayListArrayList概述概念数据结构 ArrayList的特点 ArrayList去重字符串去重对象去重 五、LinkedListLinkedList概述概念数据结构LinkedList的特点…

一键轻松,免费创造:QuickQR带你体验AI二维码的轻松生成!

当今时代&#xff0c;将信息快速转变为可扫描图案&#xff0c;以简化人们的生活和工作方式&#xff0c;二维码技术展现了它强大的功能。特别是在分享链接、联系信息或进行支付时&#xff0c;二维码已成为现代社会一个不可或缺的部分。本文将探讨生成AI二维码的一种工具&#xf…

线性表--队列

1.什么是队列&#xff1f; 队列是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先 进先出FIFO(First In First Out) &#xff1b; 入队列&#xff1a;进行插入操作的一端称为队尾&#xff1b; 出队列&#xff1a;进行…

幻兽帕鲁服务器搭建,包教包会

服务器搭建 幻兽帕鲁服务器搭建&#xff0c;包教包会&#xff0c;不会评论区评论手把手帮忙搭建 一、steamCMD安装 1、安装screen&#xff1a; yum install screen -y 2、切换用户&#xff1a; su -ls /bin/bash steam 3、切换至steam用户目录&#xff1a; cd ~ 4、下载ste…

如何在docker容器中安装Elasticsearch中的IK分词器

目录 &#xff08;1&#xff09;准备IK分词器的压缩包 &#xff08;2&#xff09;进入docker容器 &#xff08;3&#xff09;移动ik分词器到指定文件夹 &#xff08;4&#xff09;解压分词器压缩包 &#xff08;5&#xff09;测试IK分词器是否安装成功 &#xff08;1&#…

Redis核心技术与实战【学习笔记】 - 3.Redis服务高可靠

1.数据同步&#xff1a;主从库如何实现数据一致&#xff1f; 前面我们学习了 AOF 和 RDB&#xff0c;如果 Redis 发生了宕机&#xff0c;它们可以分别通过回放日志和重新读入 RDB 文件的方式恢复数据&#xff0c;从而保证尽量较少丢失数据&#xff0c;提升可靠性。 不过&…

vue3 + antd 封装动态表单组件(二)

传送带&#xff1a; vue3 antd 封装动态表单组件&#xff08;一&#xff09; 前置条件&#xff1a; vue版本 v3.3.11 ant-design-vue版本 v4.1.1 vue3 antd 封装动态表单组件&#xff08;一&#xff09;是基础版本&#xff0c;但是并不好用&#xff0c; 因为需要配置很多表…

VR拍摄+制作

1.VR制作需要的图片宽高是2:1&#xff0c;需要360✖️180的图片&#xff0c;拍摄设备主要有两种&#xff1a; 1&#xff09;通过鱼眼相机拍摄&#xff0c;拍摄一组图片&#xff0c;然后通过PTGui来合成(拍摄复杂) 2&#xff09;全景相机&#xff0c;一键拍摄直接就能合成需要的…

Android颜色选择器

Android颜色选择器&#xff0c;弹框提示选择颜色。效果如图。点击或者滑动圆环和底部横向渐变色调整颜色&#xff0c;中间圆圈的颜色就是最终选中的颜色。点击圆圈确认颜色。 使用 //颜色选择Dialogprivate void showColorPickDialog(int position, int colorInt){ColorPickerD…

数据结构(绪论+算法的基本概念)

文章目录 一、绪论1.1、数据结构的基本概念1.2、数据结构三要素1.2.1、逻辑结构1.2.2、数据的运算1.2.3、物理结构&#xff08;存储结构&#xff09;1.2.4、数据类型和抽象数据类型 二、算法的基本概念2.1、算法的特性2.2、“好”算法的特质2.2.1、算法时间复杂度2.2.2、算法空…

【Linux】:线程安全的单例模式

线程安全的单例模式 一.STL和智能指针的安全二.单例模式1.基本概念2.懒汉和饿汉的实现方式 三.常见的其它锁四.读者写者模型 一.STL和智能指针的安全 1.STL中的容器是否是线程安全的? 不是. 原因是, STL 的设计初衷是将性能挖掘到极致, 而一旦涉及到加锁保证线程安全, 会对性…

[SwiftUI]系统弹窗和自定义弹窗

一、系统弹窗 在 SwiftUI 中&#xff0c;.alert 是一个修饰符&#xff0c;用于在某些条件下显示一个警告对话框。Alert 可以配置标题、消息和一系列的按钮。每个按钮可以是默认样式、取消样式&#xff0c;或者是破坏性的样式&#xff0c;它们分别对应不同的用户操作。 1.Aler…

Spring 的存储和获取Bean

文章目录 获取 Spring 上下文对象的方式存储 Bean 对象的方式类注解配置扫描路径&#xff08;必须&#xff09;Controller&#xff08;控制器存储&#xff09;Service&#xff08;服务&#xff09;Repository&#xff08;持久层&#xff09;Component&#xff08;工具&#xff…

【Spring】Spring简介、IOC、DI

目录 Spring简介 Spring Framework五大功能模块 IOC容器 IOC思想 IOC容器在Spring中的实现 基于XML管理bean 配置bean 获取bean 依赖注入之setter注入 依赖注入之构造器注入 特殊值处理 字面量赋值 null值 xml实体 CDATA节 为类类型属性赋值 为数组类型属性赋值 为集合类型属性…

JavaScript 学习笔记(JS进阶 Day1)

「写在前面」 本文为 b 站黑马程序员 pink 老师 JavaScript 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容&#xff1a; 1. JavaScript 学习笔记&#xff08;Day1&#xff09; 2. JavaSc…

适用于 Windows 11 的 12 个最佳免费 PDF 编辑器

除了绘图等基本功能外&#xff0c;一些适用于 Windows 11 的免费 PDF 编辑器还具有 AI、OCR 识别和书签等高级功能。 我们的列表包含易于立即下载的 PDF 编辑软件工具。 这些工具不仅可以帮助转换 PDF、编辑、上传、删除、裁剪、分割、提取等。 PDF 是指便携式文档格式&…

单片机学习笔记---独立按键控制LED亮灭

直接进入正题&#xff01; 今天开始我们要学习一个新的模块&#xff1a;独立按键&#xff01; 先说独立按键的内部结构&#xff1a; 它相当于一种电子开关&#xff0c;按下时开关接通&#xff0c;松开时开关断开&#xff0c;实现原理是通过轻触按键内部的金属弹片受力弹动来实…

剧本杀小程序开发:打造沉浸式推理体验

随着社交娱乐形式的多样化&#xff0c;剧本杀逐渐成为年轻人喜爱的聚会活动。而随着技术的发展&#xff0c;剧本杀小程序的开发也成为了可能。本文将探讨剧本杀小程序开发的必要性、功能特点、开发流程以及市场前景。 一、剧本杀小程序开发的必要性 剧本杀是一种角色扮演的推…

鸿蒙端云一体化简单项目

文章目录 前言端云一体化服务端客户端云数据库总结 一、前言 鸿蒙系统在不断地成熟&#xff0c;现在有了鸿蒙端云一体化开发模式。什么是端云一体化呢&#xff0c;简单点就是你原本是客户端开发的&#xff0c;项目中只是客户端的代码&#xff0c;端云一体化呢&#xff0c;就…