PyTorch中Tensor的维度变换实现
对于PyTorch的基本数据对象Tensor(张量),在处理问题时,需要经常改变数据的维度,以便于后期的计算和进一步处理,本文旨在列举一些维度变换的方法并举例,方便大家查看。
维度查看:torch.Tensor.size()
查看当前tensor的维度
举个例子:
>>>importtorch >>>a=torch.Tensor([[[1,2],[3,4],[5,6]]]) >>>a.size() torch.Size([1,3,2])
张量变形:torch.Tensor.view(*args)→Tensor
返回一个有相同数据但大小不同的tensor。返回的tensor必须有与原tensor相同的数据和相同数目的元素,但可以有不同的大小。一个tensor必须是连续的contiguous()才能被查看。
举个例子:
>>>x=torch.randn(2,9) >>>x.size() torch.Size([2,9]) >>>x tensor([[-1.6833,-0.4100,-1.5534,-0.6229,-1.0310,-0.8038,0.5166,0.9774, 0.3455], [-0.2306,0.4217,1.2874,-0.3618,1.7872,-0.9012,0.8073,-1.1238, -0.3405]]) >>>y=x.view(3,6) >>>y.size() torch.Size([3,6]) >>>y tensor([[-1.6833,-0.4100,-1.5534,-0.6229,-1.0310,-0.8038], [0.5166,0.9774,0.3455,-0.2306,0.4217,1.2874], [-0.3618,1.7872,-0.9012,0.8073,-1.1238,-0.3405]]) >>>z=x.view(2,3,3) >>>z.size() torch.Size([2,3,3]) >>>z tensor([[[-1.6833,-0.4100,-1.5534], [-0.6229,-1.0310,-0.8038], [0.5166,0.9774,0.3455]], [[-0.2306,0.4217,1.2874], [-0.3618,1.7872,-0.9012], [0.8073,-1.1238,-0.3405]]])
可以看到x和y、z中数据的数量和每个数据的大小都是相等的,只是尺寸或维度数量发生了改变。
压缩/解压张量:torch.squeeze()、torch.unsqueeze()
- torch.squeeze(input,dim=None,out=None)
将输入张量形状中的1去除并返回。如果输入是形如(A×1×B×1×C×1×D),那么输出形状就为:(A×B×C×D)
当给定dim时,那么挤压操作只在给定维度上。例如,输入形状为:(A×1×B),squeeze(input,0)将会保持张量不变,只有用squeeze(input,1),形状会变成(A×B)。
返回张量与输入张量共享内存,所以改变其中一个的内容会改变另一个。
举个例子:
>>>x=torch.randn(3,1,2) >>>x tensor([[[-0.1986,0.4352]], [[0.0971,0.2296]], [[0.8339,-0.5433]]]) >>>x.squeeze().size()#不加参数,去掉所有为元素个数为1的维度 torch.Size([3,2]) >>>x.squeeze() tensor([[-0.1986,0.4352], [0.0971,0.2296], [0.8339,-0.5433]]) >>>torch.squeeze(x,0).size()#加上参数,去掉第一维的元素,不起作用,因为第一维有2个元素 torch.Size([3,1,2]) >>>torch.squeeze(x,1).size()#加上参数,去掉第二维的元素,正好为1,起作用 torch.Size([3,2])
可以看到如果加参数,只有维度中尺寸为1的位置才会消失
- torch.unsqueeze(input,dim,out=None)
返回一个新的张量,对输入的制定位置插入维度1
返回张量与输入张量共享内存,所以改变其中一个的内容会改变另一个。
如果dim为负,则将会被转化dim+input.dim()+1
接着用上面的数据举个例子:
>>>x.unsqueeze(0).size() torch.Size([1,3,1,2]) >>>x.unsqueeze(0) tensor([[[[-0.1986,0.4352]], [[0.0971,0.2296]], [[0.8339,-0.5433]]]]) >>>x.unsqueeze(-1).size() torch.Size([3,1,2,1]) >>>x.unsqueeze(-1) tensor([[[[-0.1986], [0.4352]]], [[[0.0971], [0.2296]]], [[[0.8339], [-0.5433]]]])
可以看到在指定的位置,增加了一个维度。
扩大张量:torch.Tensor.expand(*sizes)→Tensor
返回tensor的一个新视图,单个维度扩大为更大的尺寸。tensor也可以扩大为更高维,新增加的维度将附在前面。扩大tensor不需要分配新内存,只是仅仅新建一个tensor的视图,其中通过将stride设为0,一维将会扩展位更高维。任何一个一维的在不分配新内存情况下可扩展为任意的数值。
举个例子:
>>>x=torch.Tensor([[1],[2],[3]]) >>>x.size() torch.Size([3,1]) >>>x.expand(3,4) tensor([[1.,1.,1.,1.], [2.,2.,2.,2.], [3.,3.,3.,3.]]) >>>x.expand(3,-1) tensor([[1.], [2.], [3.]])
原数据是3行1列,扩大后变为3行4列,方法中填-1的效果与1一样,只有尺寸为1才可以扩大,如果不为1就无法改变,而且尺寸不为1的维度必须要和原来一样填写进去。
重复张量:torch.Tensor.repeat(*sizes)
沿着指定的维度重复tensor。不同于expand(),本函数复制的是tensor中的数据。
举个例子:
>>>x=torch.Tensor([1,2,3]) >>>x.size() torch.Size([3]) >>>x.repeat(4,2) [1.,2.,3.,1.,2.,3.], [1.,2.,3.,1.,2.,3.], [1.,2.,3.,1.,2.,3.]]) >>>x.repeat(4,2).size() torch.Size([4,6])
原数据为1行3列,按行方向扩大为原来的4倍,列方向扩大为原来的2倍,变为了4行6列。
变化时可以看成是把原数据作成一个整体,再按指定的维度和尺寸重复,变成一个4行2列的矩阵,其中的每一个单位都是相同的,再把原数据放到每个单位中。
矩阵转置:torch.t(input,out=None)→Tensor
输入一个矩阵(2维张量),并转置0,1维。可以被视为函数transpose(input,0,1)的简写函数。
举个例子:
>>>x=torch.randn(3,5) >>>x tensor([[-1.0752,-0.9706,-0.8770,-0.4224,0.9776], [0.2489,-0.2986,-0.7816,-0.0823,1.1811], [-1.1124,0.2160,-0.8446,0.1762,-0.5164]]) >>>x.t() tensor([[-1.0752,0.2489,-1.1124], [-0.9706,-0.2986,0.2160], [-0.8770,-0.7816,-0.8446], [-0.4224,-0.0823,0.1762], [0.9776,1.1811,-0.5164]]) >>>torch.t(x)#另一种用法 tensor([[-1.0752,0.2489,-1.1124], [-0.9706,-0.2986,0.2160], [-0.8770,-0.7816,-0.8446], [-0.4224,-0.0823,0.1762], [0.9776,1.1811,-0.5164]])
必须要是2维的张量,也就是矩阵,才可以使用。
维度置换:torch.transpose()、torch.Tensor.permute()
- torch.transpose(input,dim0,dim1,out=None)→Tensor
返回输入矩阵input的转置。交换维度dim0和dim1。输出张量与输入张量共享内存,所以改变其中一个会导致另外一个也被修改。
举个例子:
>>>x=torch.randn(2,4,3) >>>x tensor([[[-1.2502,-0.7363,0.5534], [-0.2050,3.1847,-1.6729], [-0.2591,-0.0860,0.4660], [-1.2189,-1.1206,0.0637]], [[1.4791,-0.7569,2.5017], [0.0098,-1.0217,0.8142], [-0.2414,-0.1790,2.3506], [-0.6860,-0.2363,1.0481]]]) >>>torch.transpose(x,1,2).size() torch.Size([2,3,4]) >>>torch.transpose(x,1,2) tensor([[[-1.2502,-0.2050,-0.2591,-1.2189], [-0.7363,3.1847,-0.0860,-1.1206], [0.5534,-1.6729,0.4660,0.0637]], [[1.4791,0.0098,-0.2414,-0.6860], [-0.7569,-1.0217,-0.1790,-0.2363], [2.5017,0.8142,2.3506,1.0481]]]) >>>torch.transpose(x,0,1).size() torch.Size([4,2,3]) >>>torch.transpose(x,0,1) tensor([[[-1.2502,-0.7363,0.5534], [1.4791,-0.7569,2.5017]], [[-0.2050,3.1847,-1.6729], [0.0098,-1.0217,0.8142]], [[-0.2591,-0.0860,0.4660], [-0.2414,-0.1790,2.3506]], [[-1.2189,-1.1206,0.0637], [-0.6860,-0.2363,1.0481]]])
可以对多维度的张量进行转置
- torch.Tensor.permute(dims)
将tensor的维度换位
接着用上面的数据举个例子:
>>>x.size() torch.Size([2,4,3]) >>>x.permute(2,0,1).size() torch.Size([3,2,4]) >>>x.permute(2,0,1) tensor([[[-1.2502,-0.2050,-0.2591,-1.2189], [1.4791,0.0098,-0.2414,-0.6860]], [[-0.7363,3.1847,-0.0860,-1.1206], [-0.7569,-1.0217,-0.1790,-0.2363]], [[0.5534,-1.6729,0.4660,0.0637], [2.5017,0.8142,2.3506,1.0481]]])
直接在方法中填入各个维度的索引,张量就会交换指定维度的尺寸,不限于两两交换。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。