Pytorch tensors (张量)
Introduce
Pytorch的Tensors可以理解成Numpy中的数组ndarrays,但是Tensors 支持GPU并行计算,这是其最大的一个优点。
本文首先介绍tensor的基础用法,主要tensor的创建方式以及tensor的常用操作。
以下均为初学者笔记。
tensors 基础用法
- tensors 常用创建方法
# 创建一个5行3列的矩阵,数据类型为long
x = torch.empty(5,3,dtype=torch.long)
# 类似的还有如下创建方式:
x = torch.zeros()
x = torch.ones()
x = torch.rand()
x = torch.tensor([5.5, 3.0])
# 对x重新赋值(第一种是5X3全1矩阵,第二种是随机,size与x相同,新制定type覆盖旧type)
x = x.new_ones(5,3,dtype=torch.double)
x = torch.randn_like(x,dtype=torch.float)
# tensor与numpy array的相互转换,需要注意的是他们两个用的都是共同的内存空间,即不管哪一个的值发生改变,另外一个都会相应改变
# 从numpy array创建tensor
x = torch.from_numpy(np.ones(5))
# tensor转化为numpy array,调用.numpy()即可
y = x.numpy()
# 返回x的规模,返回值类型为元组tuple,张量也支持Numpy的shpae属性
x.size()
# 改变张量的维度,与Numpy的reshape类似
x = torch.randn(4, 4) # torch.Size([4, 4])
y = x.view(16) # torch.Size([16]), equal to y = torch.reshape(x,[16])
z = x.view(-1, 8) # torch.Size([2, 8]),其中-1表示从其他维度大小推断当前维度大小
# note: 当张量使用了permute和transpose后,tensor占用的内存可能就变得不连续了,因此不能用view()函数来改变张量维度。必须先执行函数contiguous()使tensor占用内存空间连续,其次再使用view()函数改变维度才可。但是后续Pytorch增加了函数reshape()来改变tensor维度,相当于x.contigous().view()的功能,因此要改变维度直接使用y=torch.reshape(x,[16])即可。
- tensors 常用操作方式
# tensor的拼接
# cat(),不增加新的维度,在某维度上拼接tensor(理解向量或矩阵的拼接就行)
# example 1
x = torch.randn(2,3)
y = torch.randn(1,3)
z = torch.cat((x, y), 0) # 在0维(行)拼接y (y作为x的新行,增加行),维度为(3,3)
# example 2
x = torch.randn(2,3)
y = torch.randn(2,1)
z = torch.cat((x, y), 1) # 在1维(列)拼接y (y作为x的新列,增加列),维度为(2,4)
# tensor的堆叠
# stack(),增加新的维度,在新的维度上拼接tensor(无法想象,可以理解成新创建一个维度,然后把要堆叠的tensor放上去,新维度的大小就为要堆叠tensor的个数)
# 以下例子请注意堆叠后新size中3的位置
# example 1
x = torch.randn(1,2)
y = torch.randn(1,2)
z = torch.randn(1,2)
p = torch.cat((x, y,z), 0) # 在第0维度上堆叠,维度为 (3x1x2)
# example 2
x = torch.randn(1,2)
y = torch.randn(1,2)
z = torch.randn(1,2)
p = torch.cat((x, y,z), 1) # 在第1维度上堆叠,维度为 (1x3x2)
# example 3
x = torch.randn(1,2)
y = torch.randn(1,2)
z = torch.randn(1,2)
p = torch.cat((x, y,z), 2) # 在第2维度上堆叠,维度为 (1x2x3)
# tensor交换两个维度,size中对应维度大小也交换,二维情况下类比于二维矩阵的转置
# transpose()
# exmample
x = torch.randn(1,2)
x = x.transpose(0,1) # equal to x.transpose_(0,1)
print(x.size()) # torch.Size([2, 1])
# note: 一般情况下,函数后面有加_,如x.transpose_(0,1),才会直接对原始tensor x进行操作,否则是返回一个新的tensor,而原始tensor x保持不变。
# tensor交换多个维度,size中对应维度大小也交换
# permute()
# example
x = torch.randn(1,2,3)
x = x.permute(2,0,1) # 理解为第零维度用原始第二维度填充,第一维度用原始第零维度填充,第二维度用原始第一维度填充
print(x.size()) # torch.Size([3, 1, 2])
# tensor压缩和解压维度
# squeeze(dim):如果dim维为大小为1,则去除,否则不做任何变化。如若不指定dim,则去除所有大小为1的维度。
# unsqueeze(dim):在dim上添加一个维度,维度大小为1。
# example
z = torch.randn(1,2)
z.squeeze_()
print(z.size()) # torch.Size([2])
z.unsqueeze_(1)
print(z.size()) # torch.Size([2, 1])
本文参考-1
本文参考-2