PyTorch入门实战教程笔记(五):基础张量操作2

PyTorch入门实战教程笔记(五):基础张量操作2

包括:索引与切片和 维度变换

索引和切片:

使用函数torch.rand()来创建一个数据,比如a = torch.rand(4,3,28,28),即为Batch size为4(即4张图片)的28×28的RGB图像,这也是CNN中最常用的,那么a[0]指的就是索引的第一张图片,a[0,1]指的是第一张图片第一个通道(如:R)的数据,示例如下图: PyTorch入门实战教程笔记(五):基础张量操作2_第1张图片
  与python中类似,可以使用[:]等进行索引,比如a = torch.rand(4,3,28,28),每一个逗号分开代表Batchsize,通道数,长,宽等,a[:2]指从0,1(不包含2),即第一个、第二个Batch size,再比如:a[:2, 1:, :, :],表示第1-2个图片,第2-3(末尾)通道的整个图片。此外,a[:2, -1:, :, :],那么只取了一个通道,参考下图,也就是从-1到末尾,那么只有通道“2”。
PyTorch入门实战教程笔记(五):基础张量操作2_第2张图片
  隔行采样呢,就用两个冒号,比如a[:, :, 0:28:2, 0:28:2],也就是长宽像素,隔一行 保留一个数据,那么最后剩余的尺寸为14×14.
  此外,如果说想只用第1张和第三张图片(也就是Batchsize为0,2的),可以使用a.index_select( 0, torch.tensor([0,2]) ),第一个参数表示操作Batchsize,第二个参数表示用序列号为0,2的Batchsize,再比如想用图片的两个通道G、B通道(也就是索引值为1,2),编程:a.index_select(1,torch.tensor([1,2]) ).此外随机取图片的横着方向的8个,a.index_select(2,torch.arange(8) ).
  如果后面的每个维度都取,比如,取序列号为0的Batchsize的所有通道数和像素值,a[0,:, :, :]这样当然可以,但是麻烦,可以用:a[0, …]即可,用三个点号代替所有的冒号,或者a[… , :2]即前面的都取,列只取前前2个列。如下图:
  PyTorch入门实战教程笔记(五):基础张量操作2_第3张图片
  将概率大于0.5的全部取出,可以用masked_select(), 弊端在于会将数据打平,其中x.ge(0.5)表示将大于0.5的置为1具体操作如下图:
PyTorch入门实战教程笔记(五):基础张量操作2_第4张图片

Tensor纬度变换

常用API:

  • View/reshape:保证Tensor不变,将一个shape装换成另一个shape。
  • Squeeze/unsqueeze:删减与增加维度
  • Transpose/t/permute:矩阵的单次交换操作,转置,多次交换操作
  • Expend/repeat:矩阵的扩展
    View reshape:
    这两个完全可以通用,参数一模一样,都可以完成相同的功能。
      举个例子,比如我用类似手写数据集的数据尺寸,a = torch.rand(4,1,28,28),它是一个通道的图片,现在不需要其位置信息,要将通道,行列都合并(多用于全连接层),即变成[4,784](1×28×28=784),可以用a.view(4,28×28)。如下图,16行的意思是将Batchsize、channel、行都合到一块,然后只剩余列。
    PyTorch入门实战教程笔记(五):基础张量操作2_第5张图片
    Squeeze/unsqueeze:
    unsqueeze(pos/index)维度增加:
      函数的功能是在索引值的前后插入一个维度,而不增加数据本身的量,其中()内的范围为[-a.dim()-1,a.dim()+1],但是应该注意,如果用正数的索引,是在索引值之前插入,比如a.unsqueeze(0)就是在最前面插入一个维度,如果用负数的索引,是在索引值之后插入,比如a.unsqueeze(-1)就是在最后面插入一个维度,具体看下图: PyTorch入门实战教程笔记(五):基础张量操作2_第6张图片
      可以再看一下下图具体的操作,并且在低纬度时,使用0,1的区别,如下: PyTorch入门实战教程笔记(五):基础张量操作2_第7张图片PyTorch入门实战教程笔记(五):基础张量操作2_第8张图片
    Squeeze(pos/index)维度挤压:   
      数据挤压什么意思呢,就是把不那么重要的维度删除,而不改变数据的量,比如:现在有一个Batchsize=1,channel=32,H=1,W=1的数据,那么把Batchsize、H、W都删减都可以。如果不给定维数,会把能删减(dim = 1)的全部删减,比如:b的shape的size为([1,32,1,1]),那么b.squeeze()的结果为,Size为([32])。给定具体的维度挤压,如果能挤压的就可以挤压,比如b.squeeze(0),那么就变成size为([32,1,1]),如果不能挤压,就不变,比如b.squeeze(1),那么size还是([1,32,1,1])。如下图:  PyTorch入门实战教程笔记(五):基础张量操作2_第9张图片
    Expend/repeat: 
      Expend改变了理解方式,而不增加数据(推荐:速度快,节约内存),而repeat增加数据。扩展的时候只能从1维度扩展到N维度,而不能从如3扩展到M。扩张到几维,那参数就写几维就好。如果不变就写-1就好了。看下图:
    PyTorch入门实战教程笔记(五):基础张量操作2_第10张图片
      repeat函数接口给的参数不是新的shape,而是新的shape上面每一个dim要capy的次数,比如从([1, 32, 1, 1]),执行b.repeat(4,32,1,1)那么生成:([4,1024,1,1]).看下面结果展示(不建议使用,浪费内训空间,并且可能把之前的数据更改掉):
    PyTorch入门实战教程笔记(五):基础张量操作2_第11张图片
    Transpose/t/permute:
      .t转置操作:只能适用于2D维度的,即只是应于矩阵。
      Transpose(a,b)将a,b维的数据进行交换,.contiguous()函数将内存数据变成连续的,但要注意在装换过程中,记住那个数据在哪,合并后并通过view进行相应维度的还原,如下图,a2操作完全正确,而a1就把C、W给搞反了。
    PyTorch入门实战教程笔记(五):基础张量操作2_第12张图片
      permute传入参数为想要放的维度,就比如,序列为0,1,2,3。现在想要维度排列方式为0,2,3,1,如果用transpose的话,需要b.transpose(1,3).transpose(1,2),而用permute就比较简单了 直接:permute(0,2,3,1)即可。看下图:
    PyTorch入门实战教程笔记(五):基础张量操作2_第13张图片

你可能感兴趣的:(PyTorch实战学习笔记)