深度学习中的张量 - 使用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)模型,编码器…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...