深度学习 Pytorch 张量的索引、分片、合并以及维度调整
张量作为有序的序列,也是具备数值索引的功能,并且基本索引方法和
python原生的列表、numpy中的数组基本一致。不同的是,
pytorch中还定义了一种采用函数来进行索引的方式。
作为
pytorch中的基本数据类型,张量既具备了列表、数组的基本功能,同时还充当向量、矩阵等重要数据结构。因此pytorch中也设置了非常晚辈的张量合并与变换的操作。
import torch # 导入torch
import numpy as np # 导入numpy
6 张量的符号索引
6.1 一维张量索引
一维张量的索引过程和python原生对象类型的索引一致,基本格式遵循[start: end: step]。
t1 = torch.arange(1, 11) # 创建一维张量
从左到右,从零开始
t1[0]
# output : tensor(1)
**注:**张量索引出来的结果还是零维张量,而不是单独的数。
要转化成单独的数,需要使用
.item()方法
冒号分割,表示对某个区域进行索引,也就是所谓的切片
t1[1: 8] # 索引其中2-9号元素,并且左闭右开
# output : tensor([2, 3, 4, 5, 6, 7, 8])
第二个冒号,表示索引的间隔
t1[1: 8: 2] # 第三个参数表示每两个数取一个
# output : tensor([2, 4, 6, 8])
冒号前后没有值,表示索引这个区域
t1[1: : 2] # 从第二个元素开始索引,一致到结尾,并且每隔两个取一个
# output : tensor([ 2, 4, 6, 8, 10])
t1[: 8: 2] #从第一个元素开始索引到第九个元素(不包含),并且每隔两个数取一个
# output : tensor([1, 3, 5, 7])
在张量的索引中,
step位必须大于0,也就是说不能逆序取数。
6.2 二维张量索引
二维张量的索引逻辑和一维张量基本相同,二维张量可以视为两个一维张量组合而成。
在实际的索引过程中,需要用逗号进行分割,表示分别对哪个一维张量进行索引、以及具体的一维张量的索引。
t2 = torch.arange(1, 10).reshape(3, 3) # 创建二维张量
t2[0, 1] # 表示索引第一行、第二列的元素
# output : tensor(2)
t2[0, : : 2] # 表示索引第一行、每隔两个元素取一个
# output : tensor([1, 3])
t2[0, [0, 2]] # 索引结果同上
t2[: : 2, : : 2] # 表示每隔两行取一行、并且每一行中每隔两个元素取一个
# output :
tensor([[1, 3],[7, 9]])
t2[[0, 2], 1] # 索引第一行、第三行、第二列的元素
# output : tensor([2, 8])
6.3 三维张量索引
我们可以将三维张量视作矩阵组成的序列,则在索引过程中拥有三个维度,分别是索引矩阵,索引矩阵的行、索引矩阵的列。
t3 = torch.arange(1, 28).reshape(3, 3, 3) # 创建三维张量
t3[1, 1, 1] # 索引第二个矩阵中,第二行、第二个元素
# output : tensor(14)
t3[1, : : 2, : : 2] #索引第二个矩阵,行和列都是每隔两个取一个
# output :
tensor([[10, 12],[16, 18]])
# 每隔两个取一个矩阵,对于每个矩阵来说,行和列都是每隔两个取一个
t3[: : 2, : : 2, : : 2]
# output :
tensor([[[ 1, 3],[ 7, 9]],[[19, 21],[25, 27]]])
7 张量的函数索引
在pytorch中,我们还可以使用index_select函数,通过指定index来对张量进行索引。
t1 = torch.arange(1, 11)
indices = torch.tensor([1, 2])
torch.index_select(t1, 0, indices)
# output : tensor([2, 3])
第二个参数
dim代表索引的维度。对于
t1这个一维向量来说,由于只有一个维度,因此第二个参数化取值为0,代表在第一个维度上进行索引。
t2 = torch.arange(12).reshape(4,3)
t2
# output :
tensor([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
indices = torch.tensor([1, 2])# dim参数取值为0,代表在shape的第一个维度上索引
torch.index_select(t2, 0, indices)
# output :
tensor([[3, 4, 5],[6, 7, 8]])# dim参数取值为0,代表在shape的第二个维度上索引
torch.index_select(t2, 1, indices)
# output :
tensor([[ 1, 2],[ 4, 5],[ 7, 8],[10, 11]])
8 tensor.view()方法
该方法会返回一个类似视图的结果,且该结果会和原张量对象共享一块数据存储空间。
通过.view()方法,还可以改变对象结构,生成一个不同结构、但共享一个存储空间的张量。
t = torch.arange(6).reshape(2, 3)
t
# output :
tensor([[0, 1, 2],[3, 4, 5]])
# 构建一个数据相同,但形状不同的“视图”
te = t.view(3, 2)
te
# output :
tensor([[0, 1],[2, 3],[4, 5]])
当然,共享一个存储空间,也就代表二者是浅拷贝的关系,修改其中一个,另一个也会同步更改。
t[0] = 1
te
# output :
tensor([[1, 1],[1, 3],[4, 5]])
当然,维度也可以修改
tr = t.view(1, 2, 3)
tr
# output :
tensor([[[1, 1, 1],[3, 4, 5]]])
视图的作用就是节省空间,在接下来介绍的很多切分张量的方法中,返回结果都是“视图”,而不是新生成一个对象。
9 张量的分片函数
9.1 分块:chunk函数
chunk函数能够按照某维度,对张量进行均匀切分,返回结果是原张量的视图。
t2 = torch.arange(12).reshape(4, 3)
t2
# output :
tensor([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
# 在第零个维度上,按行进行四等分
tc = torch.chunk(t2, 4, dim = 0)
tc
# output :
(tensor([[0, 1, 2]]),tensor([[3, 4, 5]]),tensor([[6, 7, 8]]),tensor([[ 9, 10, 11]]))
注:
chunk返回结果是一个视图,不是新生成了一个对象
tc[0][0][0] = 1 # 修改tc中的值
t2
# output :
tensor([[ 1, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
当原张量不能均分时,chunk不会报错,但会返回其他均分结果。
torch.chunk(t2, 3, dim = 0) # 返回次一级均分结果
# output :
(tensor([[1, 1, 2],[3, 4, 5]]),tensor([[ 6, 7, 8],[ 9, 10, 11]]))
torch.chunk(t2, 5, dim = 0) # 返回次一级均分结果
# output :
(tensor([[1, 1, 2]]),tensor([[3, 4, 5]]),tensor([[6, 7, 8]]),tensor([[ 9, 10, 11]]))
9.2 拆分 :split函数
split既能进行均分,也能自定义切分。
t2 = torch.arange(12).reshape(4, 3)
t2
# output :
tensor([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
第二个参数只输入一个数值时表示均分,第三个参数表示按第几个维度进行切分
torch.split(t2, 2, 0)
# output :
(tensor([[1, 1, 2],[3, 4, 5]]),tensor([[ 6, 7, 8],[ 9, 10, 11]]))
第二个参数输入一个序列时,表示按照序列数值进行切分
torch.split(t2, [1, 3], 0)
# output :
(tensor([[1, 1, 2]]),tensor([[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]))
当第二个参数输入一个序列时,序列的各数值的和必须等于对于维度下形状分量的取值。
例如,上述代码中是按照第一个维度进行切分,第一个维度有四行,因此序列的求和必须等于
4,也就是1 + 3 = 4。
序列中每个分量的取值表示切块大小
torch.split(t2,[1, 1, 1, 1], 0)
# output :
(tensor([[1, 1, 2]]),tensor([[3, 4, 5]]),tensor([[6, 7, 8]]),tensor([[ 9, 10, 11]]))
torch.split(t2,[1, 2], 1)
# output :
(tensor([[1],[3],[6],[9]]),tensor([[ 1, 2],[ 4, 5],[ 7, 8],[10, 11]]))
当然,split函数返回结果也是view。
ts = torch.split(t2,[1, 2], 1)
ts[0][0] = 1
t2
# output :
tensor([[ 1, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
10 张量的合并操作
张量的合并操作类似列表的追加元素,可以拼接、也可以堆叠。
拼接函数:cat
a = torch.zeros(2, 3)
b = torch.ones(2, 3)
c = torch.zeros(3, 3)
# dim默认取值为0,按行进行拼接
torch.cat([a, b])
# output :
tensor([[0., 0., 0.],[0., 0., 0.],[1., 1., 1.],[1., 1., 1.]])
# 按列进行拼接
torch.cat([a, b], 1)
# output :
tensor([[0., 0., 0., 1., 1., 1.],[0., 0., 0., 1., 1., 1.]])
# 形状不匹配时将报错
torch.cat([a, c], 1)
# output :
RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 2 but got size 3 for tensor number 1 in the list.
拼接的本质是实现元素的堆积,也就是构成
a、b两个二维张量的各一维张量的堆积,最终还是构成二维向量。
堆叠函数:stack
a = torch.zeros(2, 3)
b = torch.ones(2, 3)
c = torch.zeros(3, 3)
# 堆叠之后,生成一个三维张量
torch.stack([a,b])
# output :
tensor([[[0., 0., 0.],[0., 0., 0.]],[[1., 1., 1.],[1., 1., 1.]]])
注意对比和**
cat**函数的区别,拼接之后维度不变,堆叠之后维度升高。对于两个二维张量,拼接是把一个个元素单独提取出来之后放到二维张量中,而堆叠则是直接将两个二维张量封装到一个三维张量中。
因此,堆叠的要求更高,参与堆叠的张量必须形状完全相同。
# 维度不匹配将报错
torch.stack([a, c])
# output :
RuntimeError: stack expects each tensor to be equal size, but got [2, 3] at entry 0 and [3, 3] at entry 1
11 张量维度变换
在实际操作张量进行计算时,往往需要另外进行降维和升维的操作。
squeeze函数:删除不必要的维度
t = torch.zeros(1, 1, 3, 1)
# output :
tensor([[[[0.],[0.],[0.]]]])
t.shape
# output :
torch.Size([1, 1, 3, 1])
torch.squeeze(t)
# output :
tensor([0., 0., 0.])
torch.squeeze(t).shape
# output :
torch.Size([3])
简单理解,
squeeze就相对于提出了shape返回结果中的1.
t1 = torch.zeros(1, 1, 3, 2, 1, 2)
torch.squeeze(t1)
torch.squeeze(t1).shape
# output :
torch.Size([3, 2, 2])
unsqueeze函数:手动升维
t = torch.zeros(1, 2, 1, 2)
t.shape
# output :
torch.Size([1, 2, 1, 2])
# 在第1个维度索引上升高1个维度
torch.unsqueeze(t, dim = 0)
# output :
tensor([[[[[0., 0.]],[[0., 0.]]]]])
torch.unsqueeze(t, dim = 0).shape
# output :
torch.Size([1, 1, 2, 1, 2])
# 在第3个维度索引上升高1个维度
torch.unsqueeze(t, dim = 2).shape
# output :
torch.Size([1, 2, 1, 1, 2])
注意理解维度和
shape返回结果一一对应的关系,shape返回的序列有多少元素,张量就有多少维度。
相关文章:
深度学习 Pytorch 张量的索引、分片、合并以及维度调整
张量作为有序的序列,也是具备数值索引的功能,并且基本索引方法和python原生的列表、numpy中的数组基本一致。 不同的是,pytorch中还定义了一种采用函数来进行索引的方式。 作为pytorch中的基本数据类型,张量既具备了列表、数组的基…...
神州数码--制作wifi
防火墙: #ip vrouter trust-vr#router ospf 1#router-id 8.8.8.8#network 10.0.0.0/30 area 0.0.0.0#network 10.0.0.4/30 area 0.0.0.0#network 10.0.0.8/30 area 0.0.0.0 交换机: #vlan 10;50#ip add 192.168.10.1 255.255.255.0#int vlan 50#ip add 192.168.50.…...
Web前端开发技术之HTMLCSS知识点总结
学习路线 一、新闻网界面1. 代码示例2. 效果展示3. 知识点总结3.1 HTML标签和字符实体3.2 超链接、颜色描述与标题元素3.3 关于图片和视频标签:3.4 CSS引入方式3.5 CSS选择器优先级 二、flex布局1. 代码示例2. 效果展示3. 知识点总结3.1 span标签和flex容器的区别3.…...
客户案例:致远OA与携程商旅集成方案
一、前言 本项目原型客户公司创建于1992年,主要生产并销售包括糖果系列、巧克力系列、烘焙系列、卤制品系列4大类,200多款产品。公司具有行业领先的生产能力,拥有各类生产线100条,年产能超过10万吨。同时,经过30年的发展,公司积累了完善的销售网络,核心经销商已经超过1200个,超…...
【常见BUG】Spring Boot 和 Springfox(Swagger)版本兼容问题
???欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老…...
【Python】FastAPI入门
文章目录 第一节:FastAPI入门一、FastAPI框架介绍什么是ASGI服务(WSGI)1、补充Web开发1)Web前端开发2)Web后端开发 二、FastAPI安装1、安装Python虚拟环境2、安装FastAPI 三、第一个FastAPI案例1、访问接口和文档2、接…...
JavaScript系列(32)-- WebAssembly集成详解
JavaScript WebAssembly集成详解 🚀 今天,让我们深入了解JavaScript与WebAssembly的集成,这是一项能够显著提升Web应用性能的关键技术。 WebAssembly基础概念 🌟 💡 小知识:WebAssembly(简称W…...
wps数据分析000002
目录 一、快速定位技巧 二、快速选中技巧 全选 选中部分区域 选中部分区域(升级版) 三、快速移动技巧 四、快速录入技巧 五、总结 一、快速定位技巧 ctrl→(上下左右)快速定位光标对准单元格的上下部分双击名称单元格中…...
无降智o1 pro——一次特别的ChatGPT专业模式探索
这段时间和朋友们交流 ChatGPT 的使用心得,大家都提到一个很“神秘”的服务:它基于 O1 Pro 模型,能够在对话里一直保持相对高水平的理解和回复,不会突然变得“降智”。同时,整体使用还做了免折腾的网络设置——简单一点…...
前端:前端开发任务分解 / 开发清单
一、背景 前端开发过程中,好多任务同时开发,或者一个大的任务分解为若干个子任务进行开发,分解出去的很多内容容易记不清楚 / 不易过程管理,所以记录表格如下,方便开发同事,也辅助掌握整体开发情况。 二、…...
【Django自学】Django入门:如何使用django开发一个web项目(非常详细)
测试机器:windows11 x64 python版本:3.11 一、安装Django 安装步骤非常简单,使用pip安装就行 pip install django安装完成之后,python的 Scripts 文件夹下,会多一个 django-admin.exe (管理创建django项目的工具)。…...
面试经验分享-回忆版某小公司
说说你项目中数据仓库是怎么分层的,为什么要分层? 首先是ODS层,连接数据源和数据仓库,数据会进行简单的ETL操作,数据来源通常是业务数据库,用户日志文件或者来自消息队列的数据等 中间是核心的数据仓库层&a…...
WebSocket——推送方案选型
一、前言:为何需要服务端主动推送? 在现代应用中,很多功能都依赖于“消息推送”。比如: 小红点提醒:我们经常在手机应用里看到的一个小红点提示,表示有新的消息或任务需要我们关注。新消息提醒࿱…...
山石防火墙命令行配置示例
现网1台山石SG6000防火墙,配置都可以通过GUI实现。 但有一些配置在命令行下配置效率更高,比如在1个已有策略中添加1个host或端口。 下面的双引号可以不加 1 创建服务 1.1 单个端口 service "tcp-901"tcp dst-port 901 1.2 端口范围 servi…...
LLM - 大模型 ScallingLaws 的 C=6ND 公式推导 教程(1)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/145185794 Scaling Laws (缩放法则) 是大模型领域中,用于描述 模型性能(Loss) 与 模型规模N、数据量D、计算资源C 之间关系的经验规律…...
Leetcode 983. 最低票价 动态规划
原题链接:Leetcode 983. 最低票价 class Solution { public:int mincostTickets(vector<int>& days, vector<int>& costs) {int n days.size();int last days[n - 1];int dp[last 1];map<int, int> mp;for (auto x : days)mp[x] 1;dp…...
Kafka——两种集群搭建详解 k8s
1、简介 Kafka是一个能够支持高并发以及流式消息处理的消息中间件,并且Kafka天生就是支持集群的,今天就主要来介绍一下如何搭建Kafka集群。 Kafka目前支持使用Zookeeper模式搭建集群以及KRaft模式(即无Zookeeper)模式这两种模式搭…...
springboot使用websocket
文章目录 一、概述1、简介 二、 使用1、引包2、配置处理器3、前端测试 一、概述 1、简介 简介略,附上官方文档,spring5和spring6的官方文档内容大致是一样的: https://docs.spring.io/spring-framework/docs/5.2.25.RELEASE/spring-framewo…...
Redis的安装和配置、基本命令
一、实验目的 本实验旨在帮助学生熟悉Redis的安装、配置和基本使用,包括启动Redis服务、使用命令行客户端进行操作、配置Redis、进行多数据库操作以及掌握键值相关和服务器相关的命令。 二、实验环境准备 1. JAVA环境准备:确保Java Development Kit …...
Rnote:Star 8.6k,github上的宝藏项目,手绘与手写画图笔记,用它画图做笔记超丝滑,值得尝试!
嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 Rnote是一款开源的基于矢量的绘图应用,专为学生、教师以及绘图板用户设计。它支持草图绘制、手写笔记以及对文档和图片进行注释。Rnote提供…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
