【Pytorch基础(2)】张量的索引,切片与维度变换

news2024/9/20 20:30:24

一、张量的维度索引

张量的索引是从第零维度开始的。让我们来创建一个四维的张量做举例说明:torch.Tensor(2,3,64,64) 此时,这个张量可以表示两张边长为64的正方形彩色图像,具体来说,张量的第零维表示图像的数量;第一维表示图像的颜色通道(3即为彩色图片,代表RGB三通道);第二维和第三维代表图像的高度和宽度。此张量的索引代码如下:

import torch

a = torch.Tensor(2, 3, 64, 64)
# 通过.shape的方法查看当前张量的形状
print(a.shape)
print(a[0].shape)
print(a[0][0].shape)
print(a[0][0][0].shape)
print(a[0][0][0][0].shape)

上述代码的输出为:

torch.Size([2, 3, 64, 64]) # 图像的形状
torch.Size([3, 64, 64]) # 取到第一张图像,形状为 [3, 64, 64]
torch.Size([64, 64]) # 取到第一张图像的第一个颜色通道, 形状为[64, 64]
torch.Size([64]) # 取到第一张图像的第一个颜色通道的第一列像素值,形状为64
torch.Size([]) # 取到第一张图像的第一个颜色通道的第一个像素值,形状为0(因为是标量)

另外,需要注意的是pytorch也支持负索引,使用方法与python中的负索引相同。

二、张量的维度切片

在上一小节中,维度的索引是取到某维度上的全部数据。但是,如果我们只想要某维度上的部分数据应该怎么做呢?这就是切片的作用。

切片方法的格式为:tensor[ first : last : step] first与last为切片的起始和结束位置,取值方法是按照step的间隔进行左闭右开的取值;当间隔为1时,step可以默认不写;当取到该维度的所有数据时,使用冒号即可。实例如下:

import torch

a = torch.Tensor(2, 3, 64, 64)
# 通过.shape的方法查看当前张量的形状
print(a.shape)
print(a[1:2, :, :, :].shape)
print(a[ : , : , 0:32, 0:32].shape)
print(a[ : , : , 0:32:2, 0:32:2].shape)
print(a[ : , : , : : 2, : : 2].shape)

上述代码的输出为:

torch.Size([2, 3, 64, 64]) # 图像的形状
torch.Size([1, 3, 64, 64]) # 取到第二张图像
torch.Size([2, 3, 32, 32]) # 取到两张图像1/4大小的左上角子图
torch.Size([2, 3, 16, 16]) # 取到两张图像1/4大小的左上角子图后,在子图上隔点取样
torch.Size([2, 3, 32, 32]) # 在原图上隔点取样

三、张量的维度变换

在之后的学习中我们会发现每个算法模型都有自己要求的输入数据维度,每个问题下的数据维度也不同。因为,为了使用各种的算法来处理各种的问题往往需要对数据进行维度的变换。例如,如果想用神经网络层来处理图像数据,我们就可以发现,图片是三维的数据维度(颜色通道,高度,宽度),但是神经网络层能接受的数据维度是二维,此时维度是不匹配的,因此需要将图像的空间维度打平成向量。下面介绍pytorch中一些常见的维度变换方法。

(1)view() 和 reshape() 变换维度

import torch

a = torch.Tensor(2, 3, 32, 32)
 
print(a.view(2, 3, 32*32))
print(a.reshape(2, 3, 32*32))
print(a.reshape(2, 3, -1))

代码运行结果如下:
在这里插入图片描述

torch.Size([2, 3, 1024])
torch.Size([2, 3, 1024])
torch.Size([2, 3, 1024])

view() 和reshape()都可以对某张量进行维度的变化,但是reshape()方法的鲁棒性更强,更推荐大家使用。此外,view() 和reshape()接受的参数都是变换后的维度大小,在设置变换后维度的参数时,如果只剩一个维度没有给予,可直接使用-1来代替,pytorch会根据之前已设置的维度自动推导出最后未给予的维度。最后,这里需要注意的是变换后的总维度数量必须与变换前相等,否则报错。实例如下所示:

import torch

a = torch.Tensor(2, 3, 32, 32)
 
print(a.reshape(2, 3, 10).shape) 

# ---------------------------------------------------------------------------
# RuntimeError                              Traceback (most recent call last)
# Input In [15], in <cell line: 5>()
#       1 import torch
#       3 a = torch.Tensor(2, 3, 32, 32)
# ----> 5 print(a.reshape(2, 3, 10).shape)

# RuntimeError: shape '[2, 3, 10]' is invalid for input of size 6144

(2)unsqueeze() 增加新的数据维度
有时候,我们往往因为数据的增加需要在原始张量表示的基础上扩张维度来存储新增加的数据。举个例子,我们创建一个小学年级的档案时,可以创建一个三维张量:[年级数量,每年级的班级数量,班级的人数] ,此时,我要合并另一所学校的年级档案,最好的办法是在扩充出一个学校的维度,变成四维张量:[学校的数量,年级数量,每年级的班级数量,班级的人数] 。 unsqueeze() 方法就是用来增加数据维度的,接受的参数含义是在哪个维度之前增加新维度,这个参数也支持负索引。具体实例如下:

import torch

a = torch.Tensor(2, 3, 64, 64)
print(a.unsqueeze(0).shape)
print(a.unsqueeze(1).shape)
print(a.unsqueeze(2).shape)
print(a.unsqueeze(-1).shape)

# output
# torch.Size([1, 2, 3, 64, 64])
# torch.Size([2, 1, 3, 64, 64])
# torch.Size([2, 3, 1, 64, 64])
# torch.Size([2, 3, 64, 64, 1])

(3)squeeze() 缩减数据维度
增加某张量维度的反操作是减少维度,对于pytorch中的方法是squeeze(),接受的参数是要进行维度缩减的维度索引,注意,缩减的维度值必须等于1,否则不能进行缩减,而且程序不报错,实例如下:

import torch

a = torch.Tensor(2, 1, 64, 64)
print(a.squeeze(1).shape)
print(a.squeeze(2).shape) 

# output
# torch.Size([2, 64, 64])
# torch.Size([2, 1, 64, 64]) 

(4)expand()和 repeat()在某维度上扩展数据
expand()可以在某维度上进行数据扩展,扩展的方法是复制原始数据。需要注意的是,expand()方法不能扩展维度大于1的维度,否则报错。因为其扩展方式是复制,当维度大于1时,expand()方法不清楚应该复制哪个数据。具体实例如下:

import torch

a = torch.Tensor(2, 1, 64, 64) 
print(a.shape)
print(a.expand(2,3,64,64).shape)
print(a.expand(2,3,65,65).shape)

# output
# torch.Size([2, 1, 64, 64])
# torch.Size([2, 3, 64, 64])
# ---------------------------------------------------------------------------
# RuntimeError                              Traceback (most recent call last)
# Input In [22], in <cell line: 6>()
#       4 print(a.shape)
#       5 print(a.expand(2,3,64,64).shape)
# ----> 6 print(a.expand(2,3,65,65).shape)

# RuntimeError: The expanded size of the tensor (65) must match the existing size (64) 
# at non-singleton dimension 3 Target sizes: [2, 3, 65, 65]. Tensor sizes: [2, 1, 64, 64]

repeat()也可以在某维度上进行数据扩展,但是其接受的参数含义与expand()函数不同。repeat()函数接受的是在该维度上复制全部数据的次数,实例如下:

import torch

a = torch.Tensor(2, 1, 64, 64) 
print(a.shape)
print(a.repeat(1,3,1,1).shape)
print(a.repeat(3,3,3,3).shape)

# output
# torch.Size([2, 1, 64, 64])
# torch.Size([2, 3, 64, 64])
# torch.Size([6, 3, 192, 192])

(5)transpose()和 permute()进行张量的维度调整
transpose()可以通过指定张量中某两个维度的索引,来对这两个维度的数据进行交换维度操作,示例如下:

import torch

a = torch.Tensor(2, 3, 64, 64) 
print(a.shape)
print(a.transpose(0, 1).shape) 

# output
# torch.Size([2, 3, 64, 64])
# torch.Size([3, 2, 64, 64])

(6)Broadcast:pytorch对不同维度张量进行计算时的自动补全规则
注意,broadcast不是函数,而是pytorch在加减两个不同维度张量时,底层自动实现的计算逻辑。首先,一个常识是当两个张量维度不同时,是不能进行加减操作的。broadcast的主要思想是针对维度小的数据依次从最后一个维度开始匹配维度大的数据,如果没匹配上,则插入一个新的维度。举例如下:

[2, 3, 32, 32] + [3,1,1] 是不能直接相加的。
Broadcast机制会先将 [3,1,1] 增加新维度变为 [1, 3, 1, 1] (等价于unsqueeze()方法),然后再将 [1, 3, 1, 1]扩展维度为 [2, 3, 32, 32] (等价于expand()方法)

从某种程度上说,broadcast机制等价于unsqueeze()和expand()两个方法的组合。目的是在处理两个维度不同的张量时,可以显式的不做任何处理进行直接加减操作。实际上,在底层隐式的进行了unsqueeze()和expand()。

注意,broadcast机制也有限制:当维度小的数据依次从最后一个维度开始匹配维度大的数据时,小维度数据的维度值必须符合以下两种情况之一,才能进行broadcast:等于1,与大维度数据的维度值相等,否则报错。示例如下:

import torch

a = torch.Tensor(2,3,32,32)
b = torch.Tensor(1,1,1)
c = torch.Tensor(32)
d = torch.Tensor(32, 1)
e = torch.Tensor(2, 32, 32)
print((a + b).shape)
print((a + c).shape)
print((a + d).shape)
print((a + e) .shape)

# output
# torch.Size([2, 3, 32, 32])
# torch.Size([2, 3, 32, 32])
# torch.Size([2, 3, 32, 32])
# ---------------------------------------------------------------------------
# RuntimeError                              Traceback (most recent call last)
# Input In [29], in <cell line: 11>()
#       9 print((a + c).shape)
#      10 print((a + d).shape)
# ---> 11 print((a + e) .shape)

# RuntimeError: The size of tensor a (3) must match the size of tensor b (2) 
# at non-singleton dimension 1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172478.html

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

相关文章

Apollo星火计划学习笔记——Control 专项讲解(LQR)

文章目录1. 算法相关基础1.1 一阶倒立摆1.2 二自由度车辆横向跟踪偏差模型1.3 车辆横向跟踪偏差模型1.4 车辆横向跟踪偏差倒车模型1.5 轮胎侧偏角与侧偏刚度1.6 LQR 线性二次型问题:2. LQR代码解析2.1 WriteHeaders&#xff08;调试过程中的状态量&#xff09;2.2 LatControlle…

Android APK 瘦身

Android APK 瘦身的几个方法将项目中的图片由png、jpg转为webp格式。如下操作&#xff1a;1.1选中图片或者含有图片的文件夹 右键选择Convert toWebP..1.2根据自身情况选择有损压缩还是无损压缩备注&#xff1a;官网连接&#xff1a;https://developer.android.google.cn/studi…

leetcode-每日一题-强密码检验器II(简单,数学逻辑)

如果一个密码满足以下所有条件&#xff0c;我们称它是一个 强 密码&#xff1a;它有至少 8 个字符。至少包含 一个小写英文 字母。至少包含 一个大写英文 字母。至少包含 一个数字 。至少包含 一个特殊字符 。特殊字符为&#xff1a;"!#$%^&*()-" 中的一个。它 不…

Golang 从菜鸟到大咖的必经之路_GO 语言的转义字符、注释、规范和代码风格要求

目录 一、GO 语言转义字符 A.Golang 常用的转义字符&#xff08;escape char&#xff09;: B.课程练习 二、Go 语言注释&#xff1a; A.注释&#xff08;Comment&#xff09;: B.Go 语言中的注释类型&#xff1a; C.注释不会被编译 D.shifttab 三、规范的代码风格要求…

聚焦儿童羽绒服产业,看用友YonSuite打造领先实践的数智创新小灯塔

有一种冷“是妈妈觉得你冷”。每每想起小时候&#xff0c;为了应对寒冷的冬季&#xff0c;都会“全副武装”&#xff0c;裹得厚厚的&#xff0c;里三层外三层。 放到如今&#xff0c;有了羽绒服的萌娃们&#xff0c;已不再像我们当年一样穿得厚厚的了。现在的年轻爸妈喜欢装扮…

Udev 为设备节点起别名

查看设备信息&#xff1a; 操作udev&#xff0c;可以使用udevadm命令&#xff0c;如果我们要查看/dev/sda 设备节点信息&#xff0c;我们可以使用下面命令&#xff1a; 命令&#xff1a;udevadm info -a --namesda rootubuntu:/sys/kernel/debug/usb# udevadm info -a --nam…

【C语言】文件操作(1)

文件操作一、关于文件的基础知识1.为什么要学习文件2.什么是文件3.文本文件与二进制文件二、文件的打开和关闭1. 文件指针2.文件的打开和关闭3.文件结尾三、文件的顺序读写1.fputc与fgetc2.fputs与fgets3.fprintf与fscanf4.fwrite与fread5.三个标准流一、关于文件的基础知识 1…

低代码平台的优缺点

全文 1518 字 阅读时间约 5 分钟 本文首发于码匠技术博客 目录 低代码平台的优点 低代码平台的缺点 写在最后 低代码工具大大减少了开发者需要编写的代码量&#xff0c;通过增加可复用代码和组件的数量来帮助企业适应发展需求&#xff0c;设计和部署自定义应用程序以紧跟市…

科研快报|二代加三代扩增子测序探究苏铁植物根部复杂微生物群落组成

背景介绍苏铁俗称铁树&#xff0c;是地球上现存最古老的活化石植物&#xff0c;也是种子植物中最原始的种群。我国是世界上苏铁植物资源最丰富的国家之一&#xff0c;本文对我国的特有种德保苏铁&#xff08;Cycas debaoensis&#xff09;和仙湖苏铁&#xff08;Cycas fairylak…

【复习 自用】JavaScript知识汇总(基础版)

注&#xff1a;之前学过JavaScript&#xff0c;本贴仅用于复习(自用)&#xff0c;建议没基础的朋友先学基础。会混入typescript&#xff01; 更新中~~~~~~~~~~ 对象.属性和对象[‘属性’]的区别&#xff1a;总的来说没啥区别&#xff0c;但是&#xff0c; &#xff01;&#…

办公必备的快捷键,轻松助你键步如飞

作为职场人&#xff0c;你不会只会用Ctrl C和Ctrl V吧&#xff1f;掌握更多的办公快捷键&#xff0c;可以大大提高工作效率&#xff01;今天教大家几个好用的快捷键&#xff01;现在收收藏起来吧&#xff01;快捷键一&#xff1a;winL&#xff08;锁屏&#xff09; 电脑锁屏可以…

【NI Multisim 14.0虚拟仪器设计——放置虚拟仪器仪表(功率表)】

目录 序言 &#x1f34d;放置虚拟仪器仪表 &#x1f349;功率表 序言 NI Multisim最突出的特点之一就是用户界面友好。它可以使电路设计者方便、快捷地使用虚拟元器件和仪器、仪表进行电路设计和仿真。 首先启动NI Multisim 14.0&#xff0c;打开如图所示的启动界面&#x…

opencv的图像基本操作_2

import cv2 #图像BGRimport numpy as npimport matplotlib.pyplot as plt #Matplotlib是RGB腐蚀操作kernel np.ones((3,3), np.uint8) #选择3*3卷积核&#xff0c;3*3括起来&#xff0c;(3,3)erosion cv2.erode(img, kernel, iterations 1) #erode腐蚀函数&#xff0c; iter…

【LeetCode】生命游戏 [M](矩阵)

289. 生命游戏 - 力扣&#xff08;LeetCode&#xff09; 一、题目 根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是一个…

2023年mybatis常见面试题10道

1. MyBatis是什么&#xff1f;Mybatis 是一个半 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了 JDBC&#xff0c;开发时只需要关注 SQL 语句本身&#xff0c;不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过程。程序员直接编写原生…

Hyper-V三种虚拟网络类型的理解

Windows 10除家庭版之外都内置了Hyper-V&#xff0c;但是Win10系统上Hyper-V虚拟网络的设置方法却与之前版本的Hyper-V有些不同&#xff0c;最近在折腾了无数遍之后&#xff0c;总算有些心得&#xff1a;先说说虚拟网络的三种类型。Hyper-v支持外部、内部、专用三种网络&#x…

蓝桥杯STM32G431RBT6学习——定时器中断

蓝桥杯STM32G431RBT6学习——定时器中断 前言 从网络上的资料来看&#xff0c;蓝桥杯嵌入式好像并不考外部中断&#xff08;毕竟通常只是个按键应用&#xff09;&#xff0c;因此跳过进行定时器的学习。 STM32单片机的定时器通常分为高级定时器、通用定时器、基本定时器三种&…

111、【树与二叉树】leetcode ——669. 修剪二叉搜索树:递归法(C++版本)

题目描述 解题思路 本题的关键是用好递归这个结构&#xff0c;用好每次他向下的遍历和返回的值。每一次递归时&#xff0c;相当于解决与之前相同的问题&#xff0c;因此先按某一种类子问题进行讨论&#xff08;仅有三个结点的满二叉树&#xff09;&#xff0c;当递归的方式向下…

二本学历5年经验的程序员,出去面试被碾压~

目录 1、从一个求职案例引入2 、学历差距&#xff1a;面试官的第一印象3、公司背景差距&#xff1a;你的人生名片4、技术差距&#xff1a;硬核能力的欠缺5、架构能力的差距6、面试结果的分析 这篇文章&#xff0c;聊一个很多人感兴趣的话题&#xff0c;小公司的Java工程师和大…

计网必会:HTPP详解、cookie、缓存

文章目录应用层协议Web和HTTPHTTP 概述采用非持续连接的HTTPRTT 往返时间的定义**三次握手过程**采用持续连接的HTTPHTTP到底采用哪个&#xff1f;HTTP 的报文格式请求报文功效格式响应报文状态码格式Cookie什么是cookieWeb缓存在学习的过程很多人都遇到了HTTP和Cookie&#xf…