理解pytorch的广播语义

news2025/1/16 21:48:42

目录

什么是广播运算

广播的条件

示例

示例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.coloradmin.cn/o/1569367.html

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

相关文章

Java | Leetcode Java题解之第8题字符串转换整数atoi

题目&#xff1a; 题解&#xff1a; class Solution {public int myAtoi(String str) {Automaton automaton new Automaton();int length str.length();for (int i 0; i < length; i) {automaton.get(str.charAt(i));}return (int) (automaton.sign * automaton.ans);} …

Scala第二十章节(Akka并发编程框架、Akka入门案例、Akka定时任务代码实现、两个进程间通信的案例以及简易版spark通信框架案例)

Scala第二十章节 章节目标 理解Akka并发编程框架简介掌握Akka入门案例掌握Akka定时任务代码实现掌握两个进程间通信的案例掌握简易版spark通信框架案例 1. Akka并发编程框架简介 1.1 Akka概述 Akka是一个用于构建高并发、分布式和可扩展的基于事件驱动的应用工具包。Akka是…

MySQL 导入库/建表时/出现乱码

问题描述&#xff1a; 新建不久的项目在使用Navicat for MySQL进行查看数据&#xff0c;发现表中注释的部分乱码&#xff0c;但是项目中获取的数据使用不会。 猜测因为是数据库编码和项目中使用的不一样&#xff0c;又因为项目的连接语句定义了需要编码&#xff0c;故项目运行…

Golang实现一个聊天工具

简介 聊天工具作为实时通讯的必要工具&#xff0c;在现代互联网世界中扮演着重要的角色。本博客将指导如何使用 Golang 构建一个简单但功能完善的聊天工具&#xff0c;利用 WebSocket 技术实现即时通讯的功能。 项目源码 点击下载 为什么选择 Golang Golang 是一种高效、简…

win10+Intel显卡安装配置stable-diffusion-webui绘画网页

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

【opencv】教程代码 —video(3) 视频背景剔除

bg_sub.cpp 这段代码的功能是把视频中的背景和前景分离&#xff0c;提取出前景的运动物体。根据用户选择的不同的模式&#xff0c;可以选择基于MOG2或者基于KNN的方法来进行背景减除。在处理每一帧图像的过程中&#xff0c;首先使用背景减除模型对图像帧进行处理&#xff0c;得…

ChatGPT 与 OpenAI 的现代生成式 AI(下)

原文&#xff1a;Modern Generative AI with ChatGPT and OpenAI Models 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 七、通过 ChatGPT 掌握营销技巧 在本章中&#xff0c;我们将重点介绍营销人员如何利用 ChatGPT&#xff0c;在这一领域中查看 ChatGPT 的主要用例…

[RK3128_LINUX5.1] 关于 RetroArch 使用

问题描述 查看文档 docs\cn\Linux\ApplicationNote\Rockchip_Use_Guide_Linux_RetroArch_CN.pdf&#xff0c;描述为实验 make menuconfig 后勾选选项 Libretro cores and retroarch -> retroarch 但是SDK中并没有这个选项 解决方案&#xff1a; 目前发布的buildroot SDK…

4核8G服务器配置性能怎么样?4核8G12M配置服务器能干啥?

腾讯云4核8G服务器多少钱&#xff1f;腾讯云4核8G轻量应用服务器12M带宽租用价格646元15个月&#xff0c;活动页面 txybk.com/go/txy 活动链接打开如下图所示&#xff1a; 腾讯云4核8G服务器优惠价格 这台4核8G服务器是轻量应用服务器&#xff0c;详细配置为&#xff1a;轻量4核…

flex:1是干嘛的

直接上图&#xff1a; flex:1实际代表的是三个属性的简写&#xff0c;如上图所示。 其中flex-grow是用来增大盒子的&#xff0c;比如&#xff0c;当子盒子的宽度小于父盒子的宽度&#xff0c;父盒子的剩余空间可以 利用flex-grow来设置子盒子增大的占比&#xff1b; flex-shri…

每日五道java面试题之ZooKeeper篇(二)

目录&#xff1a; 第一题. 客户端注册 Watcher 实现第二题. 服务端处理 Watcher 实现第三题. ACL 权限控制机制第四题. Chroot 特性第五题. 客户端回调 Watcher 第一题. 客户端注册 Watcher 实现 &#xff08;1&#xff09;调用 getData()/getChildren()/exist()三个 API&…

腾讯云4核8g服务器价格,CVM和轻量哪个优惠?

2024年腾讯云4核8G服务器租用优惠价格&#xff1a;轻量应用服务器4核8G12M带宽646元15个月&#xff0c;CVM云服务器S5实例优惠价格1437.24元买一年送3个月&#xff0c;腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器优惠价格 轻…

竞赛 Yolov安全帽佩戴检测 危险区域进入检测 - 深度学习 opencv

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; Yolov安全帽佩戴检测 危险区域进入检测 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&am…

PTA L2-046 天梯赛的赛场安排

天梯赛使用 OMS 监考系统&#xff0c;需要将参赛队员安排到系统中的虚拟赛场里&#xff0c;并为每个赛场分配一位监考老师。每位监考老师需要联系自己赛场内队员对应的教练们&#xff0c;以便发放比赛账号。为了尽可能减少教练和监考的沟通负担&#xff0c;我们要求赛场的安排满…

深入浅出 -- 系统架构之单体架构

单体架构&#xff08;Monolithic Architecture&#xff09; 单体架构的定义 单体架构&#xff08;Monolithic Architecture&#xff09;是一种传统的软件架构模式&#xff0c;将整个应用程序作为一个单一的、统一的单元进行开发、部署和扩展。在单体架构中&#xff0c;所有的功…

Linux 关闭防火墙命令(新手)

关闭防火墙 查看防火墙状态 systemctl status firewalld.service 临时关闭防火墙&#xff08;重启失效&#xff09; systemctl stop firewalld.service 永久关闭防火墙 systemctl disable firewalld.servicesudo systemctl enable firewalld&#xff0c;这种方式输入命令…

设计模式——抽象工厂模式02

如果是工厂模式是对同一类商品进行抽象然后生产。 那么抽象工厂模式是对工厂的抽象&#xff0c;每个工厂都能生产多种产品&#xff0c;不同工厂生产的商品性质相同&#xff0c;但外观&#xff0c;品牌会略有差异。 设计模式&#xff0c;一定要敲代码理解 商品抽象 public in…

0基础安装配置Linux-ubuntu环境

Vmtools的安装参见 0基础教你安装VM 17PRO-直接就是专业许可证版_vm17许可证-CSDN博客 在vmtools中安装ubuntu 等待安装 这时候发现没有继续按钮&#xff0c;我们关闭这个界面&#xff0c;进入系统中&#xff0c;先更改分辨率 点击这个三角&#xff0c;因为还么有安装成功&am…

【opencv】教程代码 —video(2) optical_flow (稀疏光流、稠密光流)

1. optical_flow.cpp 稀疏光流 #include <iostream> // 引入输入输出流库 #include <opencv2/core.hpp> // 引入OpenCV的核心功能模块 #include <opencv2/highgui.hpp> // 引入OpenCV的高级GUI模块&#xff0c;提供显示图像的功能 #include <opencv2/imgp…

微信小程序python+uniapp高校图书馆图书借阅管理系统ljr9i

根据日常实际需要&#xff0c;一方面需要在系统中实现基础信息的管理&#xff0c;同时还需要结合实际情况的需要&#xff0c;提供图书信息管理功能&#xff0c;方便图书管理工作的展开&#xff0c;综合考虑&#xff0c;本套系统应该满足如下要求&#xff1a; 首先&#xff0c;在…