Pytorch基础之张量的存储方式及维度操作:size,shape,view,reshape,contiguous

参考书目:张校捷,《深入浅出PyTorch:从模型到源码》

Pytorch中张量的存储

假设存在一个k维张量,其维数为[ n 1 , n 2 . . . n k n_1,n_2...n_k n1,n2...nk],在计算机的实际存储过程中为一个1维的向量,向量的大小为 n 1 ∗ n 2 ∗ . . . ∗ n k n_1*n_2*...*n_k n1n2...nk。在读取张量某一位置的元素数据时,假设此元素的下标为 ( k 1 , k 2 . . . k k ) (k_1,k_2...k_k) (k1,k2...kk),则在读取时读取的是内存中第 i 1 ∗ ( n 2 ∗ . . . ∗ n k ) + i 2 ∗ ( n 3 ∗ . . . ∗ n k ) + . . . + i k − 1 ∗ n k + i k i_1*(n_2*...*n_k)+i_2*(n_3*...*n_k)+...+i_{k-1}*n_k+i_k i1(n2...nk)+i2(n3...nk)+...+ik1nk+ik位置的数据,其中 ( n 2 ∗ . . . ∗ n k ) , ( n 3 ∗ . . . ∗ n k ) , n k , 1 (n_2*...*n_k), (n_3*...*n_k), n_k,1 (n2...nk),(n3...nk),nk,1称为对应维度的步长(Stride)或者系数(Offset)。例如下表为一 2 ∗ 2 ∗ 4 2*2*4 224张量在内存中的存储。

000 001 002 003 010 011 012 013 100 101 102 103 110 111 112 113

Pytorch中张量维度大小与数目的获取

在pytorch中对张量tensor维度及维度数目的获取可以有以下方法:ndimension方法可以获取张量的维数,nelement方法可以获取张量总的元素个数。想要获得张量的每个维度的大小,也就是张量的形状信息,可以通过tensor.size()或者tensor.shape得到。这两者不同的是tensor.szie()调用的是方法,tensor.shape访问的是张量的属性。相同的是两者返回的结果的数据类型都为torch.Size。想要获得特定维度的大小可以在使用size方法时输入想要的维度。

tensor0=torch.randn(1,3,28,28)
tensor0.ndimension(),tensor0.nelement()
Out[4]: (4, 2352)

tensor0.size(),tensor0.shape,tensor0.size(1)
Out[5]: (torch.Size([1, 3, 28, 28]), torch.Size([1, 3, 28, 28]), 3)

Pytorch中张量维度变换

在Pytorch中想要对张量的维度进行改变主要采用的方法时view方法和reshape方法。他们的作用都是将原有张量转换为想要的形状大小,前提是张量的元素总量保持一致,当view()或reshape()方法的输入中某一维度为-1时,作用是将这一维度的元素数量设为活动值,具体数值由其他维度确定例如

tensor0.view(1,-1,28).shape
Out[7]: torch.Size([1, 84, 28])
tensor0.reshape(1,-1,28).shape
Out[8]: torch.Size([1, 84, 28])

这里-1对应的维度的元素个数就是 ( 1 ∗ 3 ∗ 28 ∗ 28 ) / ( 1 ∗ 28 ) = 84 (1*3*28*28)/(1*28)=84 (132828)/(128)=84的结果

view方法与reshape方法的不同之处在于view方法不改变张量底层的数据,只改变维度的步长信息。在使用view方法之后使用contiguous可以重新生成一个张量。使用reshape()方法直接对底层数据进行了更改相当于先后调用了view()方法和contiguous方法。

contiguous方法的作用是应对张量的步长和维度不兼容时的方法,同样也常用于narrow()expand()transpose()permute()这种只改变维度步长信息而不改变底层数据本身的方法之后,不然可能出现报错。

你可能感兴趣的:(Pytorch,张量,pytorch)