P3 PyTorch 维度变换

news/2025/2/13 20:49:57/

前言

参考

课时21 维度变换-2_哔哩哔哩_bilibili

目录:

  1.      view
  2.     unsqueeze
  3.      squeeze
  4.     Expand
  5.      repeat
  6.     转置
  7.     contiguous
  8.     Permute
  9.     例子

    

     


一 view 

      作用:

            重新调整Tensor的形状,通过shape,或size属性可以看出来

     1.1 普通的用法

    import torch def test():img = torch.rand(4,1,28,28)a1= img.view(4,28*28)print("\n a1 ",a1.shape,a1.size())if __name__ == "__main__":test()

    输出:

 a1  torch.Size([4, 784]) torch.Size([4, 784])

   1.2参数-1 (自动调整该维度 size)

    

import torch def test():a = torch.arange(0, 16, 1)a1= a.view(-1,16)a2 = a.view(16,-1)print("\n a1 ",a2.shape,a1.shape)print(a1.size(0),a2.size(0))
if __name__ == "__main__":test()

输出

    a1    torch.Size([16, 1])         torch.Size([1, 16])
   1        16


 二  unsqueeze

      在指定的维度增加一个维度

      2.1  正数

         指定的位置前面插入一个维度

def test():a = torch.rand(4,5,6)a2 =a.unsqueeze(2).shapeprint("\n a2.shape: ",a2,a.ndim)a3 = a.unsqueeze(3).shapeprint("\n a3: ",a3)if __name__ == "__main__":test()

       输出


     a2.shape  torch.Size([4, 5, 1, 6]) 3

     a3  torch.Size([4, 5, 6, 1])

  2.2 负数

       在指定的维度之后插入一个维度

       a = torch.rand(4,5,6)

      a2 =a.unsqueeze(-3).shape

      在指定的维度之后插入一个维度

     
      a2.shape:  torch.Size([4, 1, 5, 6]) 3 

例1: 在指定的维度之后插入

 例2 :   在指定的维度之前插入


三  squeeze

      维度挤压,如果指定的维度为1,则删除该维度,其它则保持不变

    a = torch.rand(1,3,1,1)
    
    b = a.squeeze().shape
    print("\n  默认 ",b)
    
   
    

    #索引为正数
    #Positive and negative number
    p_0 = a.squeeze(0).shape  
    print("\n 挤压0",p_0)
    
    p_1 = a.squeeze(1).shape
    print("\n 挤压1",p_1)
    
    #索引为负数
    n_0 = a.squeeze(-1).shape  
    print("\n 挤压-1 ",n_0)
    
    n_1 = a.squeeze(-4).shape
    print("\n 挤压-4 ",p_1)


四 Expand

   正数作用和reshape 一样,对应的维度上面调整到指定的大小

  负数 -1:

      表示该维度保持不变


五 repeat

    在指定的维度上面复制几次

   


六 矩阵转置

     下面这张方法值只适用于2D的矩阵。

    a = torch.rand(2,3)d= a.T.shapeprint("\n b ",d)


七  contiguous

   torch.contiguous()方法首先拷贝了一份张量在内存中的地址,然后将地址按照形状改变后的张量的语义进行排列。

torch.contiguous()方法语义上是“连续的”,经常与torch.permute()、torch.transpose()、torch.view()方法一起使用,要理解这样使用的缘由,得从pytorch多维数组的底层存储开始说起:

touch.view()方法对张量改变“形状”其实并没有改变张量在内存中真正的形状,可以理解为:

view方法没有拷贝新的张量,没有开辟新内存,与原张量共享内存;
view方法只是重新定义了访问张量的规则,使得取出的张量按照我们希望的形状展现。

   7.1 pytorch与numpy在存储MxN的数组时,均是按照行优先将数组拉伸至一维存储

        

   a = torch.tensor([[1,2,3],[4,5,6]])print(a,a.shape)

   在内存中的样子:相当于做个flatten

  

[1, 2, 3, 4, 5, 6]

7.2 当我们使用torch.transpose()方法或者torch.permute()方法对张量翻转后,改变了张量内存的形状

   

    a = torch.tensor([[1,2,3],[4,5,6]])print("\n a ",a.shape)a2 =a.transpose(0,1)

   此刻如果再想通过view 方式访问就会出错


原因是:改变了形状的a2语义上是2行3列的,在内存中还是跟a一样,没有改变,导致如果按照语义的形状进行view拉伸,数字不连续,此时torch.contiguous()方法就派上用场了
 

    a = torch.tensor([[1,2,3],[4,5,6]])b = a.transpose(0,1).contiguous().view(2,3)print(b)out:tensor([[1, 4, 2],[5, 3, 6]])

八 Permute

      transpose 改变维度只能两两交换,有的时候需要多次交换比较繁琐

 比如[B,C,H,W]  需要更变成[B,H,W,C]

则 [B,C,H,W]--->[B,W,H,C]--->[B,H,W,C] 两次变更才能得到

   通过permute 操作一次就可以完成

  a = torch.rand(2,3,4,5)b = a.permute(0,2,3,1).shapetorch.Size([2, 4, 5, 3])

   如下为shape的变换情况

 


 九  例子

     8.1 view

把原先tensor中的数据按照行优先的顺序排成一个一维的数据(这里应该是因为要求地址是连续存储的),然后按照参数组合成其他维度的tensor

 8.2 view+tranpose+continues

 a = torch.rand(5,3,16,16)a1 = a.transpose(1,3).view(5,3*16*16).view(5,3,16,16)

   5张图片,图片channel =3 ,height=16, width =16

通过transpose改变了meomery中的存储结构,不再是那种按行顺序结构了,再去访问的时候

就会出错

  解决方法:

    a1 = a.transpose(1,3).contiguous().view(5,3*16*16).view(5,3,16,16)eq = torch.all(torch.eq(a,a1))

    问题:

     不报错了,但是因为transpose改变了数据Memory中的顺序,再访问依然按照

 [B,W,H,C] 去获取[B,C,H,W]数据.

    解决方案:

    [B,C,H,W]->[B,W,H,C]->[B,C,H,W]

 a1 = a.transpose(1,3).contiguous().view(5,3*16*16).view(5,16,16,3).transpose(1,3)eq = torch.all(torch.eq(a,a1))print(eq)

    tensor(True)


http://www.ppmy.cn/news/2297.html

相关文章

JPA 复合主键含自增id

为了使用分区,需要在主键里加入分区字段,主键变为复合主键,包含自增的id和一个分区的字段part。不正确的java代码建表语句,会导致下述错误。 导致下述错误的原因:在IdClass里的自增id属性,有注解Generated…

CN_集线器@网桥和交换机@碰撞域

文章目录网桥和交换机碰撞域集线器(Hub)网桥交换机工作原理转发表/MAC地址表表项缺失的维护第二层不足工作方式学习泛洪确认转发过滤老化特点网络容量优点端口和带宽问题例例集线器和交换机综合案例网桥和交换机 碰撞域 Collision domain - Wikipedia 碰撞域是指共享同一信道…

5年测试,面试结束后被HR怼了..(心塞)

前一阵子向朋友诉苦,我在参加字节跳动面试的时候被面试官怼得哑口无言,场面让我一度十分尴尬。印象最深的就是下面几个问题: 根据你以前的工作经验和学习到的测试技术,说说你对质量保证的理解?非关系型数据库和关系型数…

【Linux】yum的介绍和使用

本期主题:yum介绍和使用博客主页:小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限,出现错误希望大家不吝赐作为程序员,不会有人还没女朋友吧。 目录 🍁1.软件包是什么? 🍁…

[附源码]计算机毕业设计剧本杀交流分享平台Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

实现异步转同步的几种方式

循环等待实现异步转同步 在循环等待中,我们可以使用一个变量来指示异步操作是否已完成。然后,我们可以在循环中检查该变量,如果它指示异步操作已完成,则退出循环。 否则,我们可以让线程等待一段时间,然后…

「图文教程」iOS 16测试版如何升级iOS 16正式版?

苹果iOS 16正式版已经更新到iOS 16.1.2了,如果你的iPhone之前为了尝鲜已经下载安装iOS 16测试版,该如何升级iOS 16正式版呢?一起来了解下吧! 方法一、移除iOS 16 Beta描述文件 1、进入【设置】-【通用】-【VPN与设备管理】&…

【linux】进程的概念与控制

目录 冯诺依曼体系结构 操作系统(Operator System) 进程 基本概念 组织进程 查看进程 进程状态 僵尸进程危害 环境变量 程序地址空间 挂起 进程创建 写时拷贝 进程终止 _exit函数 exit函数 参数: 冯诺依曼体系结构 我们常见的计算机,如…