深度学习中的张量 - 使用PyTorch进行广播和元素级操作
深度学习中的张量 - 使用PyTorch进行广播和元素级操作
元素级是什么意思?
元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。
一个_元素级_操作是在两个张量之间进行的操作,它作用于各自张量中的相应元素。
一个_元素级_操作在张量之间的相应元素上进行操作。
如果两个元素被认为在张量中占据相同的位置,那么这两个元素就被称为相应的元素。位置由用来定位每个元素的索引决定。
假设我们有以下两个张量:
> t1 = torch.tensor([[1,2],[3,4]
], dtype=torch.float32)> t2 = torch.tensor([[9,8],[7,6]
], dtype=torch.float32)
这两个张量都是秩为2的张量,形状为2 x 2
。
这意味着我们有两个长度为二的轴。第一个轴的元素是数组,第二个轴的元素是数字。
> print(t1[0])
tensor([1., 2.])> print(t1[0][0])
tensor(1.)
这是我们现在在这个系列中用来看到的东西。好了,让我们在此基础上进一步讨论。
我们知道,如果两个元素占据张量中的相同位置,那么它们就被认为是相应的元素,位置由用来定位每个元素的索引决定。让我们看看相应元素的例子。
> t1[0][0]
tensor(1.)> t2[0][0]
tensor(9.)
这使我们能够看到,t1
中1
的相应元素是t2
中的9
。
通过索引定义的对应关系很重要,因为它揭示了元素级操作的一个重要特征。我们可以推断出,为了执行元素级操作,张量必须具有相同数量的元素。
我们将进一步限制这个陈述。为了在它们上执行元素级操作,两个张量必须具有相同的形状。
加法是一个元素级操作
让我们看看我们的第一个元素级操作,加法。别担心,它会变得更有趣。
> t1 + t2
tensor([[10., 10.],[10., 10.]])
这使我们能够看到,张量之间的加法是一个元素级操作。相应位置的每对元素都被加在一起,产生一个形状相同的新张量。
所以,加法是一个元素级操作,实际上,所有的算术操作,加、减、乘和除都是元素级操作。
算术操作是元素级操作
我们经常看到的张量操作是使用标量值的算术操作。我们可以用两种方式进行这种操作:
(1) 使用这些符号操作:
> print(t + 2)
tensor([[3., 4.],[5., 6.]])> print(t - 2)
tensor([[-1., 0.],[ 1., 2.]])> print(t * 2)
tensor([[2., 4.],[6., 8.]])> print(t / 2)
tensor([[0.5000, 1.0000],[1.5000, 2.0000]])
或者等效地,(2) 使用这些内置于张量对象的方法:
> print(t1.add(2))
tensor([[3., 4.],[5., 6.]])> print(t1.sub(2))
tensor([[-1., 0.],[ 1., 2.]])> print(t1.mul(2))
tensor([[2., 4.],[6., 8.]])> print(t1.div(2))
tensor([[0.5000, 1.0000],[1.5000, 2.0000]])
这两种选项都有效。我们可以看到,在这两种情况下,标量值2
都应用于每个元素和相应的算术操作。
这里似乎有些问题。这些例子打破了我们之前所说的元素级操作必须在形状相同的张量上进行的规则。
标量是秩为0的张量,这意味着它们没有形状,而我们的张量t1
是一个形状为2 x 2
的秩为2的张量。
那么这如何适应呢?让我们分解一下。
首先想到的解决方案可能是,操作只是使用单个标量值,并对张量中的每个元素进行操作。
这种逻辑是可行的。然而,这有点误导,当我们在更一般的情况下使用标量时,它就崩溃了。
要不同地考虑这些操作,我们需要引入_张量广播_或广播的概念。
广播张量
广播描述了在元素级操作期间如何处理形状不同的张量。
广播是一个概念,其实现允许我们将标量添加到更高维的张量。
让我们考虑t1 + 2
操作。在这里,标量值张量被广播到t1
的形状,然后执行元素级操作。
我们可以使用broadcast_to()
NumPy函数查看广播后的标量值是什么样子:
> np.broadcast_to(2, t1.shape)
array([[2, 2],[2, 2]], dtype=float32)
这意味着标量值被转换为一个像t1
一样的秩为2的张量,就像那样,形状匹配,具有相同形状的元素级规则再次发挥作用。这当然是在幕后进行的。
这段代码在这里描绘了画面。这个
> t1 + 2
tensor([[3., 4.],[5., 6.]])
实际上是这样的:
> t1 + torch.tensor(np.broadcast_to(2, t1.shape),dtype=torch.float32
)
tensor([[3., 4.],[5., 6.]])
此时,你可能会认为这似乎很复杂,所以让我们看一个更巧妙的例子来强调这一点。假设我们有以下两个张量。
广播的更巧妙的例子
让我们看一个更巧妙的例子来强调这一点。假设我们有以下张量。
t1 = torch.tensor([[1,1],[1,1]
], dtype=torch.float32)t2 = torch.tensor([2,4], dtype=torch.float32)
这个元素级加法操作的结果会是什么?考虑到元素级操作的相同形状规则,这甚至可能吗?
> t1.shape
torch.Size([2, 2])> t2.shape
torch.Size([2])
尽管这两个张量的形状不同,元素级操作是可能的,广播是使操作成为可能的关键。秩为低的张量t2
将通过广播转换以匹配秩为高的张量t1
的形状,然后像往常一样执行元素级操作。
理解广播的概念是理解这个操作如何进行的关键。和以前一样,我们可以使用NumPy的broadcast_to()
函数检查广播转换。
> np.broadcast_to(t2.numpy(), t1.shape)
array([[2., 4.],[2., 4.]], dtype=float32)> t1 + t2
tensor([[3., 5.],[3., 5.]])
广播后,这两个张量之间的加法操作是一个形状相同的张量之间的常规元素级操作。
广播是一个比基本元素级操作更高级的话题,所以如果需要更长时间来适应这个概念,不要担心。
我们何时实际使用广播?当我们预处理数据时,尤其是进行归一化程序时,我们经常需要使用广播。
在Keras课程的TensorFlow.js部分中,有一篇文章更详细地介绍了广播。那里有一个实际的例子,并且也涵盖了确定如何广播特定张量的算法,所以请查看那篇文章,以获得关于广播的更深入讨论。
不用担心不了解TensorFlow.js。这不是一个要求,我强烈推荐那里关于广播的内容。
比较操作是元素级的
比较操作也是元素级操作。
对于两个张量之间的给定比较操作,将返回一个形状相同的新张量,每个元素包含一个torch.bool
值的True
或False
。
PyTorch 1.2.0版本中的行为变化
比较操作返回的数据类型已从torch.uint8
变更为torch.bool
(在版本21113中)。
版本1.1:
> torch.tensor([1, 2, 3]) < torch.tensor([3, 1, 2])
tensor([1, 0, 0], dtype=torch.uint8)
版本1.2:
> torch.tensor([1, 2, 3]) < torch.tensor([3, 1, 2])
tensor([True, False, False])
以下示例展示了PyTorch版本1.2.0及更高版本中的输出。
元素级比较操作示例
假设我们有以下张量:
> t = torch.tensor([[0,5,0],[6,0,7],[0,8,0]
], dtype=torch.float32)
让我们看看这些比较操作。
> t.eq(0)
tensor([[True, False, True],[False, True, False],[True, False, True]])> t.ge(0)
tensor([[True, True, True],[True, True, True],[True, True, True]])> t.gt(0)
tensor([[False, True, False],[True, False, True],[False, True, False]])> t.lt(0)
tensor([[False, False, False],[False, False, False],[False, False, False]])> t.le(7)
tensor([[True, True, True],[True, True, True],[True, False, True]])
从广播的角度考虑这些操作,我们可以看到最后一个操作t.le(7)
实际上是这样的:
> t <= torch.tensor(np.broadcast_to(7, t.shape),dtype=torch.float32
)
tensor([[True, True, True],[True, True, True],[True, False, True]])
相应地,这也可以表示为:
> t <= torch.tensor([[7,7,7],[7,7,7],[7,7,7]
], dtype=torch.float32)
tensor([[True, True, True],[True, True, True],[True, False, True]])
使用函数进行元素级操作
对于元素级操作,这些操作是函数形式的,可以假设函数被应用于张量的每个元素。
以下是一些示例:
> t.abs()
tensor([[0., 5., 0.],[6., 0., 7.],[0., 8., 0.]])> t.sqrt()
tensor([[0.0000, 2.2361, 0.0000],[2.4495, 0.0000, 2.6458],[0.0000, 2.8284, 0.0000]])> t.neg()
tensor([[-0., -5., -0.],[-6., -0., -7.],[-0., -8., -0.]])> t.neg().abs()
tensor([[0., 5., 0.],[6., 0., 7.],[0., 8., 0.]])
一些术语
还有其他一些方式来指代元素级操作,所以我只想提一下,所有这些术语都意味着相同的事情:
- 元素级
- 组件级
- 点级
如果在其他地方遇到这些术语,请记住这一点。
总结
现在,我们应该对元素级操作有了很好的理解,以及它们如何应用于神经网络和深度学习的张量操作。在下一篇文章中,我们将涵盖张量操作的最后两个类别:
- 重塑操作
- 元素级操作
- 归约操作
- 访问操作
相关文章:

深度学习中的张量 - 使用PyTorch进行广播和元素级操作
深度学习中的张量 - 使用PyTorch进行广播和元素级操作 元素级是什么意思? 元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。 一个_元素级_操作是在两个张量之间进行的操作,它作用于各自张量中的相应元素…...
gitignore忽略已经提交过的
已经在.gitignore文件中添加了过滤规则来忽略bin和obj等文件夹,但这些文件夹仍然出现在提交中,可能是因为这些文件夹在添加.gitignore规则之前已经被提交到Git仓库中了。要解决这个问题,您需要从Git的索引中移除这些文件夹,并确保…...
h5使用video播放时关掉vant弹窗视频声音还在后台播放
现象: 1、点击遮罩弹窗关闭,弹窗的视频已经用v-if销毁,但是后台会自己从头开始播放视频声音。但是此时已经没有视频dom 2、定时器在打开弹窗后3秒自动关闭弹窗,则正常没有问题。 原来的代码: //页面 <a click&quo…...

Widows搭建sqli-labs
使用ms17_010渗透win7 ms17_010针对windows445端口(共享文件), 现有一台win7虚拟机IP 192.168.80.129, 开放445端口, 使用msf渗透该虚拟机 auxiliary 使用auxiliary判断目标主机是否适用smb17_010漏洞 这里发现80网段, 有一台主机适用 exploit 使用search ms17_010 type:expl…...
为AI聊天工具添加一个知识系统 之46 蒙板程序设计(第一版):Facet六边形【意识形态:操纵】
本文要点 要点 (原先标题冒号后只有 “Facet”后改为“Face六边形【意识形态】” ,是 事后想到的,本文并未明确提出。备忘在这里作为后续的“后期制作”的备忘) 前面讨论的(“之41 纯粹的思维”)中 说到,“意识”三…...
ASP.NET Core WebApi接口IP限流实践技术指南
在当今的Web开发中,接口的安全性和稳定性至关重要。面对恶意请求或频繁访问,我们需要采取有效的措施来保护我们的WebApi接口。IP限流是一种常见的技术手段,通过对来自同一IP地址的请求进行频率控制,可以有效地防止恶意攻击和过度消…...
文件移动工具 (File Mover)
这是一个简单但功能强大的Python脚本,用于递归遍历目录并将指定格式的文件移动到目标目录。默认支持移动PDF文件,但也可以通过参数指定其他文件格式。 功能特点 递归遍历源目录及其所有子目录支持移动任意指定格式的文件自动处理目标目录中的文件重名情…...
PTA L1-039 古风排版
中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。 输入格式: 输入在第一行给出一个正整数N(<100),是每一列的字符数。第二行给出一个长度不超过1000的非空字符串&a…...
Docker 镜像加速的配置
解决拉取镜像报错:Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while 在使用 Docker 过程中,拉取镜像的速度常常会受到网络状况的影响,尤其是在国内网络环境下,…...

简历_使用优化的Redis自增ID策略生成分布式环境下全局唯一ID,用于用户上传数据的命名以及多种ID的生成
系列博客目录 文章目录 系列博客目录WhyRedis自增ID策略 Why 我们需要设置全局唯一ID。原因:当用户抢购时,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增ID就存在一些问题。 问题:id的规律性太明显、…...
PHP的HMAC_SHA1和HMAC_MD5算法方法
很多做对接的小伙伴们都会遇到签名加密的问题,常用的就是hmac_sha1加密和hmac_md5加密,最开始用的是sha1加密,后来用到了md5加密,我以为直接把sha1改为md5就好了,结果试来试去跟文档提示的示例结果都对不上,…...

二进制/源码编译安装mysql 8.0
二进制方式: 1.下载或上传安装包至设备: 2.创建组与用户: [rootopenEuler-1 ~]# groupadd mysql [rootopenEuler-1 ~]# useradd -r -g mysql -s /bin/false mysql 3.解压安装包: tar xf mysql-8.0.36-linux-glibc2.12-x86_64.ta…...
2025-1-15-十大经典排序算法 C++与python
文章目录 十大经典排序算法比较排序1. 冒泡排序2. 选择排序3. 插入排序4. 希尔排序5. 归并排序6. 快速排序7. 堆排序 非比较排序8. 计数排序9. 桶排序10. 基数排序 十大经典排序算法 十大经典排序算法可以分为比较排序和非比较排序: 前者包括冒泡排序、选择排序、插入排序、希…...

头盔识别技术
本项目参考b站视频https://www.bilibili.com/video/BV1EhkiY2Epg/?spm_id_from333.999.0.0&vd_source6c722ac1eba24d4cbadc587e4d1892a7 1.下载miniconda 使用 Miniconda 来管理 Python 环境(如 yolov8),就可以通过 conda create -n y…...
DeepSeek-v3在训练和推理方面的优化
1. 基础架构:MLA,大幅减少了KV cache大小。(计算量能不能减少?) 2. 基础架构:MoE,同等参数量(模型的”能力“)下,训练、推理的计算量大幅减少。 3. MoE的load…...

将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(3 纯python的经济方案)
前情: 将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(1)-CSDN博客 将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(2)-CSDN博客 python脚本实现 厉害的小伙伴最终使用python脚本免费…...

1️⃣Java中的集合体系学习汇总(List/Map/Set 详解)
目录 01. Java中的集合体系 02. 单列集合体系 1. Collection系列集合的遍历方式 (1)迭代器遍历(2)增强for遍历编辑(3)Lambda表达式遍历 03.List集合详解 04.Set集合详解 05.总结 Collection系列…...

闪豆多平台视频批量下载器
1. 视频链接获取与解析 首先,在哔哩哔哩网页中随意点击一个视频,比如你最近迷上了一个UP主的美食制作视频,想要下载下来慢慢学。点击视频后,复制视频页面的链接。复制完成后,不要急着关闭浏览器,因为接下来…...
深入解析:如何用Java爬取淘宝分类详情接口(cat_get)
一、前言 淘宝分类详情接口(cat_get)是淘宝开放平台提供的一个接口,允许开发者获取淘宝商品的分类详情,包括分类ID、分类名称、父分类等信息。这些数据对于电商分析、市场研究和商品分类管理等具有重要价值。本文将详细介绍如何使…...
语音识别的预训练模型
语音识别的预训练模型 语音识别模型 大致分为两类: 连接时序分类(Connectionist Temporal Classification, CTC):仅编码器(encoder-only)的模型,顶部带有线性分类(CTC)头序列到序列(Sequence-to-sequence, Seq2Seq):编码器-解码器(encoder-decoder)模型,编码器…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...