当前位置: 首页 > news >正文

Pytorch使用教学6-张量的分割与合并

在这里插入图片描述

在使用PyTorch时,对张量的分割与合并是不可避免的操作,本节就带大家深刻理解张量的分割与合并。

在开始之前,我们先对张量的维度进行深入理解:

t2 = torch.zeros((3, 4))
# tensor([[0., 0., 0., 0.],
#         [0., 0., 0., 0.],
#         [0., 0., 0., 0.]])t2.shape
# torch.Size([3, 4])

重点理解

我们可以把shape的返回结果看成一个序列,代表着各张量维度的信息,第一个数字3代表行,即向量数,第二个数字4代表列,即每个向量中的标量数。

深入理解:t2是由3个一维张量组成,并且每个一维张量都包含四个元素。

张量的分割

chunk(tensor, chunks, dim)

chunk函数能够按照某个维度(dim)对张量进行均匀切分(chunks),并且返回结果是原张量的视图。

# 创建一个4×3的矩阵
t2 = torch.arange(12).reshape(4, 3)
t2
# tensor([[ 0,  1,  2],
#        [ 3,  4,  5],
#        [ 6,  7,  8],
#        [ 9, 10, 11]])

张量可均分时

在第0个维度(shape的第一个数字,代表向量维度)上将t2进行4等分:

# 在矩阵中,第一个维度是行,理解为shape的第一个数
tc = torch.chunk(t2, chunks = 4, dim = 0)
tc
# (tensor([[0, 1, 2]]),
#  tensor([[3, 4, 5]]),
#  tensor([[6, 7, 8]]),
#  tensor([[ 9, 10, 11]]))

根据结果可见:

  1. 返回结果是一个元组,不可变
tc[0] = torch.tensor([[1, 1, 1]])
# TypeError: 'tuple' object does not support item assignment
  1. 元组中的每个值依然是一个二维张量
tc[0]
# tensor([[0, 1, 2]])
  1. 返回的张量tc的一个视图,不是新成了一个对象
# 我们将原张量t2中的数值进行更改
t2[0] = torch.tensor([6, 6, 6])
# 再打印分块后tc的结果
tc
# (tensor([[6, 6, 6]]),
#  tensor([[3, 4, 5]]),
#  tensor([[6, 7, 8]]),
#  tensor([[ 9, 10, 11]]))

还不了解视图的同学,点击进行学习

张量不可均分时

若原张量不能均分时,chunk不会报错,会返回次一级均分结果。

# 创建一个4×3的矩阵
t2 = torch.arange(12).reshape(4, 3)
t2
# tensor([[ 0,  1,  2],
#        [ 3,  4,  5],
#        [ 6,  7,  8],
#        [ 9, 10, 11]])

将4行分为3等份,不可分,就会返回2等分的结果:

tc = torch.chunk(t2, chunks = 3, dim = 0)
tc
# (tensor([[0, 2, 2],
#          [3, 4, 5]]), 
#  tensor([[ 6,  7,  8],
#          [ 9, 10, 11]]))

将4行分为5等份,不可分,就会返回4等分的结果:

tc = torch.chunk(t2, chunks = 5, dim = 0)
# (tensor([[0, 2, 2]]),
#  tensor([[3, 4, 5]]),
#  tensor([[6, 7, 8]]),
#  tensor([[ 9, 10, 11]]))

split函数

split既能进行均分,也能进行自定义切分。需要注意的是split的返回结果也是视图。

# 第二个参数只输入一个数值时表示均分
# 第三个参数表示切分的维度
torch.split(t2, 2, dim = 0)
# (tensor([[0, 1, 2],
#          [3, 4, 5]]), 
#  tensor([[ 6,  7,  8],
#          [ 9, 10, 11]]))

chunk函数不同的是,split第二个参数可以输入一个序列,表示按照序列数值等分:

torch.split(t2, [1,3], dim = 0)
# (tensor([[0, 1, 2]]), 
#  tensor([[ 3,  4,  5],
#          [ 6,  7,  8],
#          [ 9, 10, 11]]))

当第二个参数输入一个序列时,序列的各数值的和必须等于对应维度下形状分量的取值,即shape对应的维度。

例如上述代码中,是按照第一个维度进行切分,而t2总共有4行,因此序列的求和必须等于4,也就是1+3=4,而序列中每个分量的取值,则代表切块大小。

torch.split(t2, [1, 1, 2], 0)
# (tensor([[0, 1, 2]]), 
#  tensor([[3, 4, 5]]), 
#  tensor([[ 6,  7,  8],
#         [ 9, 10, 11]]))

将张量第一个维度(行维度)分为1:1:2。

张量的合并

张量的合并操作类似与列表的追加元素,可以进行拼接、也可以堆叠。

这里一定要将dim参数与shape返回的结果相对应理解。

cat拼接函数

a = torch.zeros(2, 3)
a
# tensor([[0., 0., 0.],
#         [0., 0., 0.]])b = torch.ones(2, 3)
b
# tensor([[1., 1., 1.],
#         [1., 1., 1.]])

因为在张量ab中,shape的第一个位置是代表向量维度,所以当dim取0时,就是将向量进行合并,向量中的标量数不变:

torch.cat([a, b], dim = 0)
# tensor([[0., 0., 0.],
#         [0., 0., 0.],
#         [1., 1., 1.],
#         [1., 1., 1.]])

dim取1时,shape的第二个位置是代表列,即标量数,就是在列上(标量维度)进行拼接,行数(向量数)不变:

torch.cat([a, b], dim = 1)
# tensor([[0., 0., 0., 1., 1., 1.],
##        [0., 0., 0., 1., 1., 1.]])

dimshape结合理解,是不是清晰明了了?

对维度不理解的同学,点击进行学习

stack堆叠函数

和拼接不同,堆叠不是将元素拆分重装,而是将各参与堆叠的对象分装到一个更高维度的张量里。

a = torch.zeros(2, 3)
a
# tensor([[0., 0., 0.],
#         [0., 0., 0.]])b = torch.ones(2, 3)
b
# tensor([[1., 1., 1.],
#         [1., 1., 1.]])

堆叠之后,生成一个三维张量:

torch.stack([a, b], dim = 0)
# tensor([[[0., 0., 0.],
#          [0., 0., 0.]],
#         [[1., 1., 1.],
#          [1., 1., 1.]]])torch.stack([a, b], dim = 0).shape
# torch.Size([2, 2, 3])

此例中,就是将两个维度为1×2×3的张量堆叠为一个2×2×3的张量。

cat的区别

拼接之后维度不变,堆叠之后维度升高。拼接是把一个个元素单独提取出来之后再放到二维张量里,而堆叠则是直接将两个二维向量封装到一个三维张量中。因此,堆叠的要求更高,参与堆叠的张量必须形状完全相同。

python对比

a = [1, 2]
b = [3, 4]

cat拼接操作与listextend相似,不会改变维度,只会在已有框架内增加元素:

a.extend(b)
a
# [1, 2, 3, 4]

stack堆叠操作与listappend相似,会改变维度:

a = [1, 2]
b = [3, 4]
a.append(b)
a
# [1, 2, [3, 4]]

Pytorch张量操作大全:

Pytorch使用教学1-Tensor的创建
Pytorch使用教学2-Tensor的维度
Pytorch使用教学3-特殊张量的创建与类型转化
Pytorch使用教学4-张量的索引
Pytorch使用教学5-视图view与reshape的区别
Pytorch使用教学6-张量的分割与合并
Pytorch使用教学7-张量的广播
Pytorch使用教学8-张量的科学运算
Pytorch使用教学9-张量的线性代数运算
Pytorch使用教学10-张量操作方法大总结

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • UE4Editor.exe运行与调试 “-run=XX” 命令行
  • LabVIEW放大器自动测量系统
  • PHP设计模式-简单工厂模式
  • 【Apache Doris】数据副本问题排查指南
  • StarryCoding-35:鼠鼠我鸭
  • C语言开关迷宫
  • 物理机 gogs+jenkins+sonarqube 实现CI/CD
  • Ubuntu转竖屏,文件解锁和查看mac地址命令记录
  • 力扣141环形链表问题|快慢指针算法详细推理,判断链表是否有环|龟兔赛跑算法
  • ECCV2024|LightenDiffusion 超越现有无监督方法,引领低光图像增强新纪元!
  • Jsoup爬虫——自学习梳理
  • Connecting weaviate with langflow across docker containers
  • 【OpenCV C++20 学习笔记】调节图片对比度和亮度(像素变换)
  • STM32-寄存器DMA配置指南
  • Web响应式设计———1、Grid布局
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • AHK 中 = 和 == 等比较运算符的用法
  • bootstrap创建登录注册页面
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • CSS盒模型深入
  • es6--symbol
  • JS数组方法汇总
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • STAR法则
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 用简单代码看卷积组块发展
  • 鱼骨图 - 如何绘制?
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • ​油烟净化器电源安全,保障健康餐饮生活
  • ###C语言程序设计-----C语言学习(6)#
  • #Java第九次作业--输入输出流和文件操作
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • #数据结构 笔记一
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (06)Hive——正则表达式
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (三分钟)速览传统边缘检测算子
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (十六)Flask之蓝图
  • (十三)Flink SQL
  • (四)stm32之通信协议
  • ***监测系统的构建(chkrootkit )
  • .net 生成二级域名
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • @Validated和@Valid校验参数区别
  • [<事务专题>]
  • [20150321]索引空块的问题.txt