使用Pytorch操作张量(多维数组)
使用Pytorch操作张量(多维数组)
初始化
Pythorch对应的包是torch,在使用前需要安装torch包。
importtorch我们可以通过arange函数来快速初始化一个 0~n 的一维数组:
x=torch.arange(12)print(x)# tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])然后通过reshape函数来重新构建一个数组的形状:
x=torch.arange(12)print("x= ",x)# 也可以通过 x.reshape(3,4) 来实现,‘-1’表示自动计算y=x.reshape(3,-1)print("y= ",y)print("x= ",x)# x= tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])# y= tensor([[ 0, 1, 2, 3],# [ 4, 5, 6, 7],# [ 8, 9, 10, 11]])# x= tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])对于一个数组,我们可以通过shape函数来获取其形状:
print("x.shape= ",x.shape)print("y.shape= ",y.shape)# x.shape= torch.Size([12])# y.shape= torch.Size([3, 4])可以通过numel函数来获取一个数组的元素数量:
print("x.numel= ",x.numel())print("y.numel= ",y.numel())# x.numel= 12# y.numel= 12如果想要快速构建一个元素全为0或元素全为1的数组,可以通过zeros或ones函数:
# 注意这是一个3维数组x=torch.zeros(2,3,4)print("x= ",x)# x= tensor([[[0., 0., 0., 0.],# [0., 0., 0., 0.],# [0., 0., 0., 0.]],## [[0., 0., 0., 0.],# [0., 0., 0., 0.],# [0., 0., 0., 0.]]])y=torch.ones(2,3,4)print("y= ",y)# y= tensor([[[1., 1., 1., 1.],# [1., 1., 1., 1.],# [1., 1., 1., 1.]],## [[1., 1., 1., 1.],# [1., 1., 1., 1.],# [1., 1., 1., 1.]]])我们也可以通过randn函数,来构建一个数组,其元素随机取自 均值为0、标准差为1 的高斯分布:
均值为0、标准差为1 的高斯分布,也就是标准正态分布。
x=torch.randn(3,4)print("x= ",x)# x= tensor([[ 1.6662, 1.0917, 0.5183, 0.7725],# [-0.3504, -0.3056, 1.4037, -0.5792],# [-0.4681, 0.1452, 0.9675, 0.8223]])当然,你也可以自己指定一个数组,通过tensor:
x=torch.tensor([[1,1,1],[2,2,2]])print("x= ",x)# x= tensor([[1, 1, 1],# [2, 2, 2]])运算
对于常见运算:加(+)、减(-)、乘(*)、除(/)、幂(**),必需要两个形状相同的数组进行运算,其运算过程就是将两个数组对应位置上的元素进行运算:
x=torch.tensor([[1,1,1],[2,2,2]])y=torch.tensor([[2,2,2],[3,3,3]])print(x+y)# tensor([[3, 3, 3],# [5, 5, 5]])print(x-y)# tensor([[-1, -1, -1],# [-1, -1, -1]])print(x*y)# tensor([[2, 2, 2],# [6, 6, 6]])print(x/y)# tensor([[0.5000, 0.5000, 0.5000],# [0.6667, 0.6667, 0.6667]])print(x**y)# tensor([[1, 1, 1],# [8, 8, 8]])其实参与运算的两个数组也不一定要完全形状相同,这里有一个广播机制。可以理解为,对于两个形状相同的数组,如果某个数组缺失了某一维度,可以直接将该数组另一个维度复制过来,补充上缺失的维度:
x=torch.tensor([1,1,1])y=torch.tensor([[2,2,2],[3,3,3]])print(x+y)# tensor([[3, 3, 3],# [4, 4, 4]])# 可以看到,这里的数组x,本来(相对于数组y)缺失了一个维度,但在计算过程中通过复制,补充成了:[[1,1,1],[1,1,1]]# 但对于这种情况,就会报错x=torch.tensor([[1,1,1],[3,3,3]])y=torch.tensor([[2,2,2],[3,3,3],[4,4,4]])print(x+y)# 因为广播机制只会对长度为1的维度进行补充。上面的数组x的维度0的长度为2,估不适用广播机制我们也可以对两个数据进行拼接,通过cat函数:
# dim=0 表示拼接第0轴(第0维)print(torch.cat((x,y),dim=0))# tensor([[1, 1, 1],# [2, 2, 2],# [2, 2, 2],# [3, 3, 3]])# dim=1 表示拼接第1轴(第1维)print(torch.cat((x,y),dim=1))# tensor([[1, 1, 1, 2, 2, 2],# [2, 2, 2, 3, 3, 3]])我们当然也可以对两个数组进行比较:
x=torch.tensor([[1,1,1],[2,2,2]])y=torch.tensor([[2,1,2],[3,2,3]])# 分别比较每个元素print(x==y)# tensor([[False, True, False],# [False, True, False]])print(x>y)# tensor([[False, False, False],# [False, False, False]])print(x<y)# tensor([[ True, False, True],# [ True, False, True]])对一个数组调用sum函数,可以得到该数组的所有元素之和:
x=torch.tensor([[1,1,1],[2,2,2]])print(x.sum())# tensor(9)索引
我们可以像索引一维数组一样,索引多维数组:
x=torch.arange(12).reshape(-1,4)print(x)# tensor([[ 0, 1, 2, 3],# [ 4, 5, 6, 7],# [ 8, 9, 10, 11]])# 取最后一个元素print(x[-1])# tensor([ 8, 9, 10, 11])print(x[-1][-1])# tensor(11)# 取从 索引1到索引2的元素(后面是开区间:[1,2))print(x[1:2])# tensor([[4, 5, 6, 7]])# 取第0维的索引0到索引2的元素,然后取第1维的全部元素print(x[0:2][:])# tensor([[0, 1, 2, 3],# [4, 5, 6, 7]])当然也可以像赋值一维数组一样,赋值多维数组:
x=torch.arange(12).reshape(-1,4)print(x)# tensor([[ 0, 1, 2, 3],# [ 4, 5, 6, 7],# [ 8, 9, 10, 11]])# 最后一个元素x[-1]=9print(x)# tensor([[0, 1, 2, 3],# [4, 5, 6, 7],# [9, 9, 9, 9]])x[-1][-1]=0print(x)# tensor([[0, 1, 2, 3],# [4, 5, 6, 7],# [9, 9, 9, 0]])# 索引1到索引2的元素(后面是开区间:[1,2))x[1:2]=0print(x)# tensor([[0, 1, 2, 3],# [0, 0, 0, 0],# [9, 9, 9, 0]])# 第0维的索引0到索引2的元素,然后是第1维的全部元素x[0:2][:]=-1print(x)# tensor([[-1, -1, -1, -1],# [-1, -1, -1, -1],# [ 9, 9, 9, 0]])
