六、矩阵转置操作
-
a.t() 仅适用于二维情况
-
a.transpoae(d1,d2) 维度两两交换,数据信息由[d0,d1,d2,d3]–>[d0,d2,d1,d3]
注意转置了以后数据被打乱,变成行与行之间不连续,需要用contiguous函数将其变成连续的。
即执行如下操作:a.transpose(1,2).contiguoous()
再将数据重现,view
a.shape -->torch.size([5,2,14,32]) a1=a.transpose(1,2).contiguous().view(5,2*14*32).view(5,14,2,32) 注意:最后这个view(5,14,2,32) 参数数据一定要与变换后的维度相符合,否则会造成数据污染 检测交换后数据是否还保持一致: torch.all(torch.eq(a,a1)) 若一致,返回1,证明交换维度后数据并没有遭受到污染,否则,返回结果为0
-
permute 可以同时进行多个维度的交换
permute(d0,d2,d3,d1) 数据信息由[d0,d1,d2,d3] -->[d0,d2,d3,d1]
a.shape = [4,24,12,3] a.permute(0,2,3,1).contiguous().view(4,24*12*3).view(4,12,3,24)
七、Broatcast 维度扩张(自动根据需要插入维度,并复制数据)
假设图片数据的维度为:[d0,d1,d2,d3] 一般认为最右侧为小维度,左侧为大维度
什么情况下使用broadcast:
(从最后(最小)一个维度开始匹配)
维度是1 -->扩展成相同shape
维度为0 -->插入一个维度,再扩张成相同shape
eg.1
A: [12,32,6,6]
B: [1,32,1,1] -->扩张[12,32,6,6]-->再执行A+B
eg.2
A: [12,32,6,6]
B: [6,6] -->插入维度 [1,1,6,6] -->扩张维度 [12,32,6,6] -->再执行 A+B
eg.3
A: [12,32,6,6]
B: [3,32,6,6] 不符合操作要求,不能直接用broadcast
需要进行手动操作:把B[0]: [32,6,6]取出来,然后使用broadcast
八、Tensor之间的拼接与拆分
1.cat
要求:在非cat的维度上,shape必须一样。在cat的维度上,shape可以不一致
a = torch.rand(2,14,5)
b = torch.rand(5,14,5)
torch.cat([a,b],dim = n) 在第n个维度上进行合并
torch.cat([a,b],dim = 0).size -->torch.size([7,14,5])
2.stack
新插入一个维度,把之前某个维度的数据分成几份
除了新插入的维度,其他维度的shape必须保持一致
a.shape -->[4,3,32,32]
torch.stack([a],dim = 2).shape -->torch.size([4,3,2,16,32]) 相当于把照片数据的行数分成了两部分
a = torch.rand(32,8)
b = torch.rand(32,8)
torch.stack([a,b],dim = 0).shape --> torch.size([2,32,8]) 相当于有两个班级。每个班级32个人,每个人有8门成绩,新创建的第0个维度,表示班级
3.拆分:split 根据长度来拆分
split(len,dim=n)
eg. c.shape -->torch.size([2,32,14])
a,b = c.split(1,dim=0)
a.shape --> torch.size([1,32,14])
b.shape --> torch.size([1,32,14])
不均匀长度拆分
split([len1,len2,len3],dim=n)
eg. c.shape -->torch.size([5,14,2])
a,b,d = c.split([3,1,1],dim=0)
a.shape --> torch.size([3,14,2])
b.shape --> torch.size([1,14,2])
d.shape --> torch.size([1,14,2])
4.拆分:Chunk 根据数量来进行拆分
chunk(num,dim) 该维度上的shape按数量进行均分