【pytorch06】 维度变换

2024-06-24 04:04
文章标签 pytorch06 维度 变换

本文主要是介绍【pytorch06】 维度变换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

常用API

  • view/reshape
  • squeeze/unsqueeze
  • transpose/t/permute
  • expand/repeat

view和reshape

在这里插入图片描述
view操作的基本前提是保证numel()一致

a.view(4,28*28)的物理意义是把行宽以及通道合并在一起,对于4张图片,我们直接把所有数据都合在一起,用一个784维的向量来表示,这样所有的二维信息上下左右位置信息就忽略掉了,这种数据特别适合于全连接层,因为全连接层的输入就是这样的一个向量输入

a.view(4*28,28)把原来数据的前三个通道合并在一起,这种方式的物理意义是把所有的照片的所有通道的所有行放在第一个维度变成一个N,每一个N都有一个一行的数据,这一行的数据刚好是28个像素点[N,28],就是说我们现在只关注所有的行这些数据信息

a.view(4*1,28,28)把前面两个通道合并在一起,这种方式是说,我们只关注feature map这个属性,不关注feature map来自于哪张图片或哪个通道

view操作或reshape操作的致命问题
b是a通过view操作得到的,如果只看b不看a的话得到的是一个[4,784]的tensor,就会丢失非常重要的数据,原来的存储方式(维度信息)是[b,c,h,w],会丢失原来的维度信息,所以恢复的时候就恢复不出来,恢复的时候可以恢复成[4,28,28,1]这种方式从语法上来是没问题的,但是把数据破坏掉了,因为把维度信息丢失掉了,没有按照维度信息来还原数据就造成了数据的污染

数据的存储/维度顺序非常重要,需要时刻记住

如果view的新的tensor的size跟原来的不一样会报错原来是42828=4784,如果标成4783的话还有一部分数据不知道会去哪,没有把数据的size保持住
在这里插入图片描述

squeeze和unsqueeze

unsqueeze维度增加

unsqueeze把一个维度展开
范围在[-a.dim()-1,a.dim()+1] 这里是[-5,5)
在这里插入图片描述
a.unsqueeze(0).shape0维度前面插入一个维度,可以把这个维度理解为一个集合或者一个组,一个组里面有4个图片,每个图片有1个通道长宽为28
增加了一个组,但这个组还是4张图片,没有增加数据,只是数据的理解方式不一样

a.unsqueeze(-1).shape可以理解一个像素的均值和方差的属性,这里只是假设,便于理解,要理解的是unsqueeze并没有改变数据本身,只是改变数据的理解方式

负数是在索引之后插入,正数是在索引之前插入

在这里插入图片描述
a的shape是[2],经过unsqueeze(-1)之后shape是[2,1],经过unsqueeze(0)之后shape是[1,2]

图片处理案例

在这里插入图片描述

feature map是[4,32,14,14]也就是给的照片长宽为14×14,channel为32,bias相当于给每个channel上的所有像素增加一个偏置值,如何把f叠加在b上?因为f和b的dimension不一样,所以shape也不一样,所以肯定要把b的dimension变成4维,保持与f的shape一样,才可以进行累加操作,然后再把它扩张成[4,32,14,14](扩张后面会说),这样就可以跟f相加了

squeeze维度减少

在这里插入图片描述
squeeze()能挤压的全部挤压,能挤压的包括dimension的size是1的

expand和repeat

  • expand:boradcasting
  • repeat:memory copied
    维度扩展是把维度的shape改变掉
    比如b[32]用unsqueeze操作把dimension为1的tensor变成了dimension为4的tensor[1,32,1,1],变成dimension为4的tensor以后fearture map还是[4,32,14,14]还是不能直接相加,我们需要把这1维度扩展成14维度
    在这里插入图片描述
    expand只是改变了我们的理解方式并没有增加数据
    repeat实实在在的增加了数据,比如你把1变成4的时候增加了4张照片,因此他把后面的所有的数据都拷贝一遍,现在有1行要变成14行,那就会把14行的数据全部拷贝一遍

这两个api从最终的效果来说是等效的,第一种方式和第二种方式区别在于什么,第一种方式不会主动复制数据只会在有需要的时候才会复制数据否则就会省略掉复制数据这个过程(推荐)执行速度快节约内存

在这里插入图片描述
调用expand函数的前提是tensor原来的shape和expand之后的shape的dimension必须一致,对于原来1维度扩展以后是n维度的话是可以扩张的,对于原来维度不为1的维度不可行(比如原来是3 expand之后变成M的话这一部分操作没办法复制,必须告诉策略是什么,所以会报错)

如果不想改变某一维度只需要填上-1即可,-1表示这个维度保持不变

在这里插入图片描述
repeat的接口和expand不一致,它给的参数不是新的shape,而是每一个dimension要拷贝的次数

T转置

在这里插入图片描述
.t()方法只适用于2-D的tensor,只能适用于矩阵
在这里插入图片描述
transpose接受的是两个参数包含了要交换的两个维度a.transpose(1,3)这里要交换1维度和3维度,本来是[b,c,h,w]会变成[b,w,h,c],然后把后面的3个维度连起来一起理解再把它展开成[4,3,32,32]就会变成[b,c,w,h],问题就来了

view操作会把维度信息给丢掉,没有考虑到原来的维度顺序是[b,w,h,c],展开的时候变成了[b,c,w,h]这样子c维度就会提前,通过这种方式破坏了原来的数据

数据的维度顺序必须和存储顺序保持一致

另一个问题是,transpose涉及到维度交换,因此原来的数据存储方式肯定是要改变的,本来说原来是一行行的存储,转置之后数据是不连续的。

在PyTorch中,当提到张量(tensor)是“不连续的”(non-contiguous),意思是张量的数据在内存中不是紧密排列的,而是分散在不同的位置。这通常发生在对张量进行某些操作后,比如切片(slicing)、索引(indexing)或者某些形式的拼接(catenation),这些操作可能导致张量的数据在内存中不再连续。
在这里插入图片描述
a2=a,a1≠a
torch.eq()来判断数据内容是否一致,再用torch.all()函数来确保所有内容都是一致的

torch.all()函数用于检查给定条件是否对输入张量(tensor)的所有元素都为真(true)。如果张量中的所有元素都满足条件,则返回True,否则返回False。

可以看出要把维度的先后顺序保持住,否则会污染数据

permute

在这里插入图片描述

一开始维度是[b,c,h,w]用transpose(1,3)只能两两交换会变成[b,w,h,c],会发现w和h维度交换了(原来w在h的后面,现在h在w的前面),比如原来是一个人,现在交换之后变成了一个转置(长变宽,宽变长),它这个图片可能会改变所以图片不会是一个人,为了很好的还原出来原来的图片,只完成C放到后面的这个操作还是希望得到[b,h,w,c]这样的一个形状

两步
b=a.transpose(1,3) [b,w,h,c]
c=b.transpose(1,2) [b,h,w,c]

[b,h,w,c]是numpy存储图片的格式,需要这一步才能导出numpy

permute()实现上述操作只需要一步,可以完成任意维度的交换

同样permute()也会把内存顺序打乱,因此如果要涉及到contagious这个错误的话,必须要额外加一个contagious()函数,把内存顺序变连续,也就是重新生成一片内存再复制过来

这篇关于【pytorch06】 维度变换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089122

相关文章

OSG数学基础:坐标系变换

三维实体对象需要经过一系列的坐标变换才能正确、真实地显示在屏幕上。在一个场景中,当读者对场景中的物体进行各种变换及相关操作时,坐标系变换是非常频繁的。坐标系变换通常包括:世界坐标系-物体坐标系变换、物体坐标系-世界坐标系变换和世界坐标系-屏幕坐标系变换(一个二维平面坐标系,即显示器平面,是非常标准的笛卡尔坐标系的第一象限区域)。 世界坐标系-物体坐标系变换 它描述的问题主要是关于物体本身的

【CSS】深入解释CSS 2D变换

CSS 2D变换(CSS 2D Transformations)是CSS3引入的一组功能,允许你对HTML元素进行2D空间内的移动、旋转、缩放和倾斜等操作。这些变换不会影响到页面的布局,因为它们只是视觉上改变元素的呈现方式,而不是改变其在文档流中的位置或大小。 以下是CSS 2D变换的详细解释: 1. transform 属性 transform 属性用于在2D或3D空间中移动、旋转、缩放或

昇思25天学习打卡营第4天 | 数据变换

内容介绍:通常情况下,直接加载的原始数据并不能直接送入神经网络进行训练,此时我们需要对其进行数据预处理。MindSpore提供不同种类的数据变换(Transforms),配合数据处理Pipeline来实现数据预处理。所有的Transforms均可通过`map`方法传入,实现对指定数据列的处理。 具体内容: 1. 导包 import numpy as npfrom PIL import Im

SSIS--- 数据仓库中实现 Slowly Changing Dimension 缓慢渐变维度的三种方式

看文章之前先了解----缓慢渐变维度 (Slowly Changing Dimension) 常见的三种类型及原型设计:http://blog.csdn.net/u012071918/article/details/77533025 2013-10-16 00:09 by BIWORK, 6661 阅读, 14 评论, 收藏, 编辑 开篇介绍 关于 Slowly Changing Dim

SSIS+数据仓库系列--- 缓慢渐变维度 (Slowly Changing Dimension) 常见的三种类型及原型设计

在从 OLTP 业务数据库向 DW 数据仓库抽取数据的过程中,特别是第一次导入之后的每一次增量抽取往往会遇到这样的问题:业务数据库中的一些数据发生了更改,到底要不要将这些变化也反映到数据仓库中?在数据仓库中,哪些数据应该随之变化,哪些可以不用变化?考虑到这些变化,在数据仓库中的维度表又应该如何设计以满足这些需要。 很显然在业务数据库中数据的变化是非常自然和正常的,比如顾客的联系方式,手机号码

快速傅里叶变换FFT的迭代实现

《快速傅里叶变换的相关定义、原理及其递归算法》描述了FFT的最基本原理,按2来分解原DFT运算。实际上有效率更高的分解办法(视卷积双方的长度而定),当然效率虽更高却更难以理解。即使按2来分解,也有基于时域的和基于频域的区别,上文描述的是基于时域的,个人觉得这是最容易理解的一种FFT原理。本文描述此原理下的FFT的迭代实现。     仍然以8点DFT为例,考察其依次2分的过程,可以得到这样

快速傅里叶变换的相关定义、原理及其递归算法

快速傅里叶变换FFT是离散傅里叶变换DFT的一种快速算法,实际上诸如Matlab等科学计算软件都已经实现了FFT,只需调用相应的接口即可。在ACM里,FFT的典型应用就是大数的乘法或者多项式的乘法。顺便,如果题目规模不是很大,有关大数的运算推荐使用Java语言,使用java.math.BigInteger包完成;包括高精度运算,可以使用BigDecimal包完成。任何情况下,会一门外语总是

[转载]细说傅里叶变换

原文地址:[转载]细说傅里叶变换 作者:小腹黑zju 原文出处:http://blog.163.com/niujiashu@126/blog/static/1002930422011102501211199/   一、傅立叶变换的由来 关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶变换的描述,但是大都是些故弄玄虚的文章,太过抽象,尽是一些让人看了就望而生畏的公式的罗列

维度/标量/张量/一维/二维/三维/shape/size/索引/view理解

维度是对不类型的描述,有几个不同的类型就有几个不同的维度. 张量是用来描述维度更宽泛的概念 标量是一个数. 一维是一组数据. 二维是两个不同特征组合的数据. 三维是三个不同的特征组合的数据.[] 只是用来表示区间范围套更多的[]是为了表示不同的维度,要理解维度 含义而不是只看[]. 生活例子 假设我们有一个书架,书架有很多层,每层放着书: 索引 (Index):就像书架上书的位置,比

【昇思25天学习打卡营打卡指南-第四天】数据变换 Transforms

数据变换 Transforms 通常情况下,直接加载的原始数据并不能直接送入神经网络进行训练,此时我们需要对其进行数据预处理。MindSpore提供不同种类的数据变换(Transforms),配合数据处理Pipeline来实现数据预处理。所有的Transforms均可通过map方法传入,实现对指定数据列的处理。 mindspore.dataset提供了面向图像、文本、音频等不同数据类型的Tra