理解pytorch的广播语义

目录

什么是广播运算

广播的条件

示例

示例1

示例2

示例3 补1

示例4 原位运算

示例5 参与广播运算的两个tensor,必须是从右向左对齐

总结规律

两个tensor可以做广播运算的条件:

两个可以互相广播的tensor运算的步骤:

例子:


什么是广播运算

广播发生的场景很广泛,tensor加法、乘法等都适用广播语义。广播的意思就是,在某些条件下,两个形状不同的tensor仍可以完成运算。

广播的条件

两个tensor可以相互广播的条件是:

1 每一个tensor至少有一个维度(torch.empty((0,))就是一个没有维度的tensor,见下面的例子)

2 从最后一个维度(下面解释何为最后一个维度)开始,逐一比较两个tensor的各个维度,这两个被比较的维度,要么相等,要么有一个是1,要么有一个不存在。

何为最后一个维度?看下面的例子

X 是一个2行3列的tensor。从它最外面那一层[]括号来看,里面有2个元素:

[1,2,3]和[4,5,6]

所以,X的“首维度”就是从[1,2,3],[4,5,6]--->这个方向

再往里一层,是1,2,3的数列,也可以说是4,5,6的数列。这就是X的下一个维度。由于X只有两个维度,所以1,2,3(4,5,6)数列的维度就是x的尾维度,或者说是最后一个维度。

由于x.shape=([2,3]),可见,有两个元素的维度([1,2,3],[4,5,6]这个维度)排在左边,有3个元素的维度(1,2,3(或者说,4,5,6)这个维度)排在右面。故,“首维度”排在shape的最左边,“尾维度”排在最右边

示例

示例1

准备两个tensor

X形状是5,7,3所有元素都是0

Y形状是5,7,3 所有元素都是1

运算结果:

可见,add_操作后,x的每个元素都加1.

示例2

X没有维度,Y是2行2列

可见,两者不能相加

示例3 补1

X是一个3x2x2的tensor,而y是一个只有两个元素的矢量。

这时有人会有疑问:x的维度有俩个“2”,y的“2”应该对应哪一个?

根据官网Broadcasting semantics — PyTorch 2.2 documentation的说法“If the number of dimensions of x and y are not equal, prepend 1 to the dimensions of the tensor with fewer dimensions to make them equal length.”---把1插在维度较少的tensor的前面。说明pytorch是尽量保持尾部维度对齐的,也就是下面的对齐:

3     2     2   x

              2   y

然后在y的前面插1:

3     2     2

1     1     2

y前面的维度补了两个“1”,每一次补1,y的外面加一层[]。所以补两个1之后,y变成[ [ [20,30] ] ]

对齐后,沿着第一维度计算:

将x视为一个3元矢量,矢量的每一个元素是一个2x2 tensor;将y视为一个1元矢量,矢量唯一的元素是一个1x2的tensor[[20,30]]。接下来,让这个3元矢量的每一个元素与这个1x2的tensor相加。

把这个2x2的tensor再看成一个二元矢量,每个元素又都是一个2元矢量。而把1x2的tensor看成只有一个元素的矢量,且元素本身又是一个2元矢量[20,30]。于是2x2的tensor加1x2的tensor又可以分解成两个二元矢量分别加一个二元矢量[20,30]。举例看[[1,2], [3,4]] + [20,30],就是[1,2] + [20,30] 和[3,4] + [20,30].

重复上述操作给[[5,6],[7,8]]和[[9,10],[11,12]],所以就有了最后的结果:x的每一个元素都加上了[20,30]

示例4 原位运算

所谓原位运算,指的是运算返回值保存在某一个输入变量中,而不是保存在新的变量里。在Karpathy的视频教程中提到,P /= … 就是一个原位运算。示例2的add_操作也是一个原位运算。

如下图所示,x.add_(y)成立,但是y.add_(x)不成立:

 原因是,x与y相加时,x的维度不需要变化,而y的规模要变化,才能适配x的形状。由于x.add_(y)的结果保存在x,而不是y中,所以y的形状变化是暂时的,运算结束后,就回到原状态。但是反过来则不行:y.add_(x)导致结果保存在y中,导致运算后y的规模和运算前不同,这是不允许的。

示例5 参与广播运算的两个tensor,必须是从右向左对齐

这个例子说明参与广播运算的两个tensor,必须是从右对齐:

从上面的例子x+y失败,可以看出,虽然y(5x2的tensor)可以在最右边补一个1,变为5x2x1,适配x的规模5x2x4,但是广播语义要求参与运算的两个tensor首先把最右边的维度对齐,然后再补充维度。所以x的最右边维度4是无法匹配y的最右边维度2的,故失败。

总结规律

两个tensor可以做广播运算的条件:

1 两个tensor都至少有一个维度;

2 两个tensor的维度个数要么完全一样,那个维度较少的tensor可以把自己缺少的维度补充为1;

3 补齐可以补充多个维度,但是只能发生在所有已有维度的左边,不能插在已有维度之间,也不能出现在已有维度右边。

4 假如运算是原位运算,则保存运算结果的变量的尺寸不应在运算前后发生变化。

两个可以互相广播的tensor运算的步骤:

1 假如两者维度个数、对应维度的尺寸都相同,则直接对应元素做运算,得出结果即可

2 假如两者维度不同,则

2.1 首先让两个变量的最右边维度对齐

2.2 维度较少的那个变量的左边必然缺少维度,缺少几个,就从最左边开始补几个1

2.3 从最左边开始运算(即是说,先处理x1,y1这一对)。变量x = [x1, x2, x3, … xn]和变量y = [y1, y2, y3,….yn]。把[x2,x3,x4…xn]看作一个元素,把[y2,y3,y4,…yn]看作一个元素。这样,x就被看作是一个含有x1个元素的矢量,y被看作是有y1个元素的矢量。根据前面的描述,不难发现,x1与y1要么相等,要么有一个是1.

2.4 假如x1==y1,则只要把各自对应元素相加即可。每个对应元素又是一个[x2,x3,x4...xn]和[y2,3,y4,..yn],于是计算[x2,x3,x4...xn]+ [y2,3,y4,..yn]。如果对应元素可以直接相加,就返回结果,否则回到2.3

2.5 假如x1!=y1,那么其中必有一个是1。比如说y1==1。那么x+y可以看成是一个x1维矢量加一个标量。矢量加标量,只要把标量加到矢量的每一个元素即可。矢量的每个元素都是一个[x2,x3,x4….xn],标量是y1这个维度的元素(y1既然等于1,就只有一个元素)。这两者的加法又回到2.3

重复以上步骤,直到最后的维度(也就是最右边的维度)。

例子:

X = [  [[1,2,3],[4,5,6]],   [[1,1,1],[2,2,2]],  [[3,3,3],[4,4,4]]   ]

Y = [10,20,30]

根据步骤2.1与2.2,y要补齐为一个1x1x3的tensor。补齐后:

Y = [[[10,20,30]]]

除了最里面的维度以外,外面的维度都是1.

根据第2.3步,从最左边运算,所以x被视为一个三元矢量:

而Y只有一个元素:[[10,20,30]]。所以这个元素要跟上面三者分别做加法。

来看[[1,2,3],[4,5,6]] + [[10,20,30]]

显然,第一个加数又是一个二元矢量,所以回到步骤2.3

Y只有一个元素[10,20,30]。所以用[10,20,30]与上面两个元素分别相加。

于是得出[11,22,33]和[14,25,36]把这两个结果组合起来,最终结果的第一个元素就是

[[11,22,33],[14,25,36]]

第二个和第三个元素的计算同理,不再赘述。

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

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

相关文章

[C#]OpenCvSharp改变图像的对比度和亮度

目的 访问像素值mat.At<T>(y,x) 用0初始化矩阵Mat.Zeros 饱和操作SaturateCast.ToByte 亮度和对比度调整 g(x)αf(x)β 用α(>0)和β一般称作增益(gain)和偏置(bias)&#xff0c;分别控制对比度和亮度 把f(x)看成源图像像素&#xff0c;把g(x)看成输出图像像素…

蓝桥杯—DS1302

目录 1.管脚 2.时序&官方提供的读写函数 3.如何使用读写函数 4.如何在数码管中显示在DS1302中读取出的数据&#xff1f; 1.管脚 2.时序&官方提供的读写函数 /* # DS1302代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行…

如何锁定鼠标光标在水平、垂直或45度对角线模式下移动 - 鼠标水平垂直移动锁定器简易教程

在我们进行精细工作例如如创建图标和图形设计时&#xff0c;通常需要我们对鼠标移动进行精确控制。一旦向左或向右轻微移动&#xff0c;都可能导致设计出错。若出现不必要的错误&#xff0c;我们极有可能不得不重新开始&#xff0c;这会令人感到非常沮丧。这种情况下&#xff0…

RabbitMQ3.x之九_Docker中安装RabbitMQ

RabbitMQ3.x之_Docker中安装RabbitMQ 文章目录 RabbitMQ3.x之_Docker中安装RabbitMQ1. 官网2. 安装1 .拉取镜像2. 运行容器 3. 访问 1. 官网 rabbitmq - Official Image | Docker Hub 2. 安装 1 .拉取镜像 docker pull rabbitmq:3.13.0-management2. 运行容器 # latest Rabb…

单元测试 mockito(二)

1.返回指定值 2.void返回值指定插桩 3.插桩的两种方式 when(obj.someMethod()).thenXxx():其中obj可以是mock对象 doXxx().wien(obj).someMethod():其中obj可以是mock/spy对象 spy对象在没有插桩时是调用真实方法的,写在when中会导致先执行一次原方法,达不到mock的目的&#x…

模块化编程:AMD 和 CMD 的魅力

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

2024 年最新使用 Wechaty 开源框架搭建部署微信机器人(微信群智能客服案例)

读取联系人信息 获取当前机器人账号全部联系人信息 bot.on(ready, async () > {console.log("机器人准备完毕&#xff01;&#xff01;&#xff01;")let contactList await bot.Contact.findAll()for (let index 0; index < contactList.length; index) {…

RabbitMQ Tutorial

参考API : Overview (RabbitMQ Java Client 5.20.0 API) 参考文档: RabbitMQ: One broker to queue them all | RabbitMQ 目录 结构 Hello World consumer producer 创建连接API解析 创建连接工厂 生产者生产消息 消费者消费消息 队列声明 工作队列Work Queues 公平…

gpt国内怎么用?最新版本来了

claude 3 opus面世后&#xff0c;这几天已经有许多应用&#xff0c;而其精确以及从不偷懒&#xff08;截止到2024年3月11日还没有偷懒&#xff09;的个性&#xff0c;也使得我们可以用它来首次完成各种需要多轮对话的尝试。 今天我们想要进行的一项尝试就是—— 如何从一个不知…

Outlook会议邀请邮件在答复后就不见了

时常会有同事找到我说&#xff0c;Outlook答复会议邀请邮件后收件箱就找不到会议邀请的邮件了。 这其实是Outlook的的一个机制&#xff0c;会把应答后的会议邀请邮件从收件箱自动删除&#xff0c;到已删除的邮件那里就能找到。如果不想要自动删除&#xff0c;改一个设置即可。…

LeetCode-124. 二叉树中的最大路径和【树 深度优先搜索 动态规划 二叉树】

LeetCode-124. 二叉树中的最大路径和【树 深度优先搜索 动态规划 二叉树】 题目描述&#xff1a;解题思路一&#xff1a;递归。return max(max(l_val, r_val) node.val, 0)解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&#xff1a; 二叉树中的 路径 被定义为一条…

iOS-App:App Store新的审核政策,在应用隐私清单中声明和解释使用特定API的原因

App Store新的审核政策&#xff0c;在应用隐私清单中声明和解释使用特定API的原因 设备/引擎&#xff1a;Mac&#xff08;11.6&#xff09;/Mac Mini 开发工具&#xff1a;终端 开发需求&#xff1a;苹果官方邮件通知&#xff0c; App Store新的审核政策&#xff0c;在应用隐…

面试总结------2024/04/04

1.面试官提问&#xff1a;你说你在项目中使用springsecurity jwt 实现了登录功能&#xff0c;能简单讲一下怎么实现的吗&#xff1f; 2.使用RabbitMQ实现订单超时取消功能 订单状态定义 首先&#xff0c;我们需要定义订单的不同状态。在这个示例中&#xff0c;我们可以定义以下…

Unity:2D SpriteShape

1.1 简介 Sprite Shape 可以很灵活的更改sprite的轮廓。比如&#xff1a; 它由两部分组成&#xff1a;Sprite Shape Profile、Sprite Shape Controller&#xff0c;需要导入2D Sprite Shape Package. 1.1.1 Sprite导入要求 Texture Type - ‘Sprite (2D and UI)’.Sprite Mo…

面试题:MySQL 高可用

&#x1f496; 主从同步 原理 核心&#xff1a;二进制日志 binlog 是 MySQL 的日志&#xff0c;redolog 和 undolog 是 innodo 引擎的日志。 &#x1f496; 分库分表 分类 问题和技术 数据一致性问题 使用分布式事务管理组件&#xff0c;如ShardingSphere的分布式事务功能&…

目标检测——监控下的汽车

一、重要性及意义 首先&#xff0c;车辆检测技术是保证视频监控系统正常运行的基础。通过监控摄像头实时获取的图像&#xff0c;可以自动检测出图像中的车辆&#xff0c;并进行车辆类型的分类和识别。这对于优化城市交通管理、实现智能交通系统具有重要意义。此外&#xff0c;…

通用分布式锁组件

通用分布式锁组件 1 Redisson1.1介绍1.2 为什么要使用Redisson实现分布式锁1.2.1 锁续期的问题1.2.2 获取锁尝试的问题1.2.3 可重入问题 1.3 Wath Dog的自动延期机制1.4 快速了解1.5 项目集成 2 定义通用分布式锁组件2.1 实现思路分析2.2 定义注解2.3 定义切面2.4 使用锁2.5.工…

Macbook文件清理软件 Mac电脑清理垃圾文件怎么清理

为了维护Macbook电脑的系统健康&#xff0c;我们需要定期给电脑进行全面清理&#xff0c;清除系统垃圾文件、软件缓存和系统内存。那么好用的Macbook文件清理软件有哪些呢&#xff1f;今天就给大家介绍几款好用的电脑清理软件并介绍Mac电脑清理垃圾文件怎么清理。 一、Macbook…

代码审计-PHP原生开发篇SQL注入数据库监控正则搜索文件定位静态分析

文章目录 前言1、Bluecms-CNVD-1Day-常规注入审计分析2、emlog-CNVD-1Day-常规注入审计分析3、emlog-CNVD-1Day-2次注入审计分析 前言 挖掘技巧&#xff1a; -语句监控-数据库SQL监控排查可利用语句定向分析 -功能追踪-功能点文件SQL执行代码函数调用链追踪 -正则搜索-(update…

[C#]OpenCvSharp实现直方图均衡化全局直方图局部直方图自适应直方图

【什么是直方图均衡化】 直方图均衡化是一种简单而有效的图像处理技术&#xff0c;它旨在改善图像的视觉效果&#xff0c;使图像变得更加清晰和对比度更高。其核心原理是将原始图像的灰度直方图从可能较为集中的某个灰度区间转变为在全部灰度范围内的均匀分布。通过这种方法&a…