一、改变张量的形状
改变张量的形状在深度学习的使用过程中会经常遇到,而且针对不同的情况对张量形状尺寸的改变有多种函数和方法可以使用
tensor.reshape()方法
import torch
A = torch.arange(12.0).reshape(3,4)
A
# tensor([[ 0., 1., 2., 3.],
# [ 4., 5., 6., 7.],
# [ 8., 9., 10., 11.]])
torch.reshape()方法
import torch
A = torch.arange(12.0).reshape(3,4)
print(A)
print(torch.reshape(input=A,shape=(2,-1)))
# tensor([[ 0., 1., 2., 3.],
# [ 4., 5., 6., 7.],
# [ 8., 9., 10., 11.]])
# tensor([[ 0., 1., 2., 3., 4., 5.],
# [ 6., 7., 8., 9., 10., 11.]])
tensor.resize_()方法
import torch
A = torch.arange(12.0).reshape(3,4)
print(A)
print(A.resize_(2,6))
A.resize_as_(B)方法
import torch
A = torch.arange(12.0).reshape(3,4)
B = torch.arange(10.0,19.0).reshape(3,3)
A.resize_as_(B)
print(A)
print(B)
# tensor([[0., 1., 2.],
# [3., 4., 5.],
# [6., 7., 8.]])
# tensor([[10., 11., 12.],
# [13., 14., 15.],
# [16., 17., 18.]])
torch.unsqueeze()函数可以在张量的指定维度插入新的维度得到维度提升的张量
torch.squeeze()函数可以移除指定维度或者所有维度大小为1的维度,从而得到维度减小的新张量
import torch
A = torch.arange(12.0).reshape(2,6)
B = torch.unsqueeze(A,dim = 0)
print("B.shape:",B.shape)
# torch.Size([1, 2, 6])
C = B.unsqueeze(dim = 3)
print("C.shape:",C.shape)
D = torch.squeeze(C)
print("D.shape:",D.shape)
E = torch.squeeze(C,dim = 0)
print("E.shape:",E.shape)
# B.shape: torch.Size([1, 2, 6])
# C.shape: torch.Size([1, 2, 6, 1])
# D.shape: torch.Size([2, 6])
# E.shape: torch.Size([2, 6, 1])
.expand()方法对张量的维度进行拓展,从而对张量的大小形状进行修改。
A.expand_as©方法,则会将张量A根据张量C的形状进行拓展,得到新的张量。
import torch
A = torch.arange(3)
B = A.expand(3,-1)
print(B)
C = torch.arange(6).reshape(2,3)
D = A.expand_as(C)
print(D)
# tensor([[0, 1, 2],
# [0, 1, 2],
# [0, 1, 2]])
# tensor([[0, 1, 2],
# [0, 1, 2]])
张量的.repeat()方法,可以将张量看作一个整体,然后根据指定的形状进行重复填充,得到新的张量
import torch
A = torch.arange(3)
C = torch.arange(6).reshape(2,3)
D = A.expand_as(C)
print(D)
E = D.repeat(2,2,6)
print(E)
print(E.shape)
# tensor([[0, 1, 2],
# [0, 1, 2]])
# tensor([[[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
# [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
# [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
# [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]],
# [[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
# [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
# [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
# [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]]])
# torch.Size([2, 4, 18])
二、获取张量中的元素
和numpy一致,利用索引和切片的方法提取元素
import torch
A = torch.arange(12).reshape(1,3,4)
print(A)
# tensor([[[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]]])
print(A[0])
# tensor([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
print(A[0,0:2,:]) #获取第0维度下矩阵的前两行元素
# tensor([[0, 1, 2, 3],
# [4, 5, 6, 7]])
print(A[0,-1,-4:-1]) #获取第0维度下的矩阵最后一行-4~-1列
# tensor([ 8, 9, 10])
也可按需将索引设置为相应的布尔值,然后提取为真条件下的内容
import torch
A = torch.arange(12).reshape(1,3,4)
print(A)
# tensor([[[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]]])
B = -A
print(B)
# tensor([[[ 0, -1, -2, -3],
# [ -4, -5, -6, -7],
# [ -8, -9, -10, -11]]])
print(torch.where(A>5,A,B)) #当A>5为true时返回x对应位置值,为false时返回y的值
# tensor([[[ 0, -1, -2, -3],
# [-4, -5, 6, 7],
# [ 8, 9, 10, 11]]])
print(A[A>5])
# tensor([ 6, 7, 8, 9, 10, 11])
torch.tril()函数可以获取张量下三角部分的内容,而将上三角部分的元素设置为0
torch.triu()函数可以获取张量上三角部分的内容,而将下三角部分的元素设置为0
torch.diag()函数可以获取矩阵张量的对角线元素,或者提供一个向量生成一个矩阵张量
import torch
A = torch.arange(12).reshape(1,3,4)
print(A)
# tensor([[[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]]])
print(torch.tril(A,diagonal=0))
# tensor([[[ 0, 0, 0, 0],
# [ 4, 5, 0, 0],
# [ 8, 9, 10, 0]]])
print(torch.tril(A,diagonal = 1)) #diagonal参数控制要考虑的对角线
# tensor([[[0, 0, 0, 0],
# [4, 0, 0, 0],
# [8, 9, 0, 0]]])
print(torch.triu(A,diagonal=0))
# tensor([[[ 0, 1, 2, 3],
# [ 0, 5, 6, 7],
# [ 0, 0, 10, 11]]])
C = A.reshape(3,4)
print(C)
# tensor([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
print(torch.diag(C,diagonal=0))
# tensor([ 0, 5, 10])
print(torch.diag(C,diagonal=1))
# tensor([ 1, 6, 11])
torch.diag(torch.tensor([1,2,3]))
# tensor([[1, 0, 0],
# [0, 2, 0],
# [0, 0, 3]])
三、拼接和拆分
troch.cat()函数
import torch
# 在给定的维度连接给定的张量序列
A = torch.arange(6.0).reshape(2,3)
print(A)
# tensor([[0., 1., 2.],
# [3., 4., 5.]])
B = torch.linspace(0,10,6).reshape(2,3)
print(B)
# tensor([[ 0., 2., 4.],
# [ 6., 8., 10.]])
C = torch.cat((A,B),dim = 0) #在0维度连接张量
print(C)
# tensor([[ 0., 1., 2.],
# [ 3., 4., 5.],
# [ 0., 2., 4.],
# [ 6., 8., 10.]])
D = torch.cat((A,B),dim = 1) #在1维度上连接张量
print(D)
# tensor([[ 0., 1., 2., 0., 2., 4.],
# [ 3., 4., 5., 6., 8., 10.]])
E= torch.cat((A[:,0:2],A,B),dim = 1) #在1维度上连接3个张量
print(E)
# tensor([[ 0., 1., 0., 1., 2., 0., 2., 4.],
# [ 3., 4., 3., 4., 5., 6., 8., 10.]])
E = torch.cat((A[:,1:2],A,B),dim=1)
print(E)
# tensor([[ 1., 0., 1., 2., 0., 2., 4.],
# [ 4., 3., 4., 5., 6., 8., 10.]])
torch.stack()函数
import torch
# 在给定的维度连接给定的张量序列
A = torch.arange(6.0).reshape(2,3)
print(A)
# tensor([[0., 1., 2.],
# [3., 4., 5.]])
B = torch.linspace(0,10,6).reshape(2,3)
print(B)
# tensor([[ 0., 2., 4.],
# [ 6., 8., 10.]])
F = torch.stack((A,B),dim=0) #沿新维度连接张量
print(F)
# tensor([[[ 0., 1., 2.],
# [ 3., 4., 5.]],
# [[ 0., 2., 4.],
# [ 6., 8., 10.]]])
print(F.shape)
# torch.Size([2, 2, 3])
G = torch.stack((A,B),dim = 2)
print(G)
# tensor([[[ 0., 0.],
# [ 1., 2.],
# [ 2., 4.]],
# [[ 3., 6.],
# [ 4., 8.],
# [ 5., 10.]]])
print(G.shape)
# torch.Size([2, 3, 2])
torch.chunk()函数可以将张量分割为特定数量的块
torch.split()函数在将张量分割为特定数量的块时,可以指定每个块的大小
import torch
# 在给定的维度连接给定的张量序列
A = torch.arange(6.0).reshape(2,3)
print(A)
# tensor([[0., 1., 2.],
# [3., 4., 5.]])
B = torch.linspace(0,10,6).reshape(2,3)
print(B)
# tensor([[ 0., 2., 4.],
# [ 6., 8., 10.]])
E= torch.cat((A[:,0:2],A,B),dim = 1) #在1维度上连接3个张量
print(E)
# tensor([[ 0., 1., 0., 1., 2., 0., 2., 4.],
# [ 3., 4., 3., 4., 5., 6., 8., 10.]])
print(torch.chunk(E,2,dim = 0))
# (tensor([[0., 1., 0., 1., 2., 0., 2., 4.]]),
# tensor([[ 3., 4., 3., 4., 5., 6., 8., 10.]]))
D = torch.cat((A,B),dim = 1) #在1维度上连接张量
print(D)
# tensor([[ 0., 1., 2., 0., 2., 4.],
# [ 3., 4., 5., 6., 8., 10.]])
D1,D2 = torch.chunk(D,2,dim = 1)
print(D1)
# tensor([[0., 1., 2.],
# [3., 4., 5.]])
print(D2)
# tensor([[ 0., 2., 4.],
# [ 6., 8., 10.]])
E1,E2,E3 = torch.chunk(E,3,dim = 1) #如果沿给定维度dim的张量大小不能被块整除,则最后一个块最小
print(E1)
# tensor([[0., 1., 0.],
# [3., 4., 3.]])
print(E2)
# tensor([[1., 2., 0.],
# [4., 5., 6.]])
print(E3)
# tensor([[ 2., 4.],
# [ 8., 10.]])
D1,D2,D3 = torch.split(D,(1,2,3),dim = 1) #将张量切分为块,指定每个块的大小
print(D1)
# tensor([[0.],
# [3.]])
print(D2)
# tensor([[1., 2.],
# [4., 5.]])
print(D3)
# tensor([[ 0., 2., 4.],
# [ 6., 8., 10.]])