Torch的基本使用
-
判断GPU是否可用
torch.cuda.is_available()
-
张量
Torch 定义了 10 种张量类型,包括 CPU 和 GPU 形式,如下表所示:
数据类型 dtype CPU张量 GPU张量 32位浮点数 torch.float32、torch.float torch.FloatTensor torch.cuda.FloatTensor 64位浮点数 torch.float64、torch.double torch. DoubleTensor torch.cuda.DoubleTensor 16位浮点数 torch.float16、torch.half torch.HalfTensor torch.cuda.HalfTensor 16位浮点数 torch.bfloat16 torch.BFloat16Tensor torch.cuda.BFloat16Tensor 32位复数 torch.complex32、torch.chalf / / 64位复数 torch.complex64、torch.cfloat torch.complex / 128位复数 torch.complex128、torch.cdouble / / 8位整型(无符号) torch.uint8 torch.ByteTensor torch.cuda.ByteTensor 8位整型(有符号) torch.int8 torch.CharTensor torch.cuda.CharTensor 16位整型(有符号) torch.int16、torch.short torch.ShortTensor torch.cuda.ShortTensor 32位整型(有符号) torch.int32、torch.int torch.IntTensor torch.cuda.IntTensor 64位整型(有符号) torch.int64、torch.long torch.LongTensor torch.cuda.LongTensor 布尔 torch.bool torch.BoolTensor torch.cuda.BoolTensor 量化的8位整型(无符号) torch.quint8 torch.ByteTensor / 量化8位整型(有符号) torch.qint8 torch.CharTensor / 量化的32位整型(有符号) torch.qint32 torch.IntTensor / 量化4位整型(无符号) torch.quint4x2 torch.ByteTensor / torch.tensor()和torch.Tensor()的区别:
torch.tensor 是一个工厂函数,它接收多种类型的输入,包括原始数据(如列表、元组或张量)、数据类型和计算设备的指定以及是否需要开启自动求导功能的指示。它的返回值总是新创建的一个张量,即使输入本身就是张量。
torch.Tensor 是一个类,它用于创建空的张量。它的参数可以是张量的形状(shape)或者是另一个张量。该类的实例化不会改变输入张量的内容,而是返回一个新的张量对象。
虽然 torch.tensor 和 torch.Tensor 在功能上是相似的,都用于创建PyTorch中的张量,但 torch.Tensor 作为类,提供了更多灵活性,并且在使用时可以避免一些复杂的类型推断问题。
torch中默认的数据类型为32位浮点型
tensor1 = torch.Tensor(5) tensor1.dtype
输出:
torch.float32
更改默认数据类型:
torch.set_default_tensor_type(torch.FloatTensor)
获取默认数据类型:
torch.get_default_dtype()
输出:
torch.float32
初始化张量
通过传入List初始化:
tensor2 = torch.Tensor([[1, 2], [3, 4]]) tensor2
输出:
tensor([[1., 2.], [3., 4.]])
通过传入数组初始化:
array = np.array([[5, 6], [7, 8]]) tensor3 = torch.Tensor(array) tensor3
输出:
tensor([[5., 6.], [7., 8.]])
按类型初始化:
# 32位浮点数 tensor1 = torch.FloatTensor([1]) # 64位浮点数 tensor2 = torch.DoubleTensor([2]) # 16位浮点数 tensor3 = torch.HalfTensor([3]) # 32位整型 tensor4 = torch.IntTensor([4]) # 64位整型 tensor5 = torch.LongTensor([5]) # 布尔类型 tensor6 = torch.BoolTensor([0, 1, 0, 1]) print(f"tensor1:{tensor1}") print(f"tensor2:{tensor2}") print(f"tensor3:{tensor3}") print(f"tensor4:{tensor4}") print(f"tensor5:{tensor5}") print(f"tensor6:{tensor6}")
输出:
tensor1:tensor([1.]) tensor2:tensor([2.], dtype=torch.float64) tensor3:tensor([3.], dtype=torch.float16) tensor4:tensor([4], dtype=torch.int32) tensor5:tensor([5]) tensor6:tensor([False, True, False, True])
构造全 0 全 1 张量并初始化类型:
# 构造全0张量 并设置类型为torch.float32 zerotensor = torch.zeros([3, 6], dtype=torch.float32) # 构造全1张量 并设置类型为torch.int32 onetensor = torch.ones([3, 6], dtype=torch.int32) print(zerotensor) print(onetensor)
输出:
tensor([[0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.]]) tensor([[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]], dtype=torch.int32)
创建相同大小的全 1 或全 0 张量
# 创建相同大小全1张量 tensor1 = torch.Tensor([[1, 2, 3], [4, 5, 6]]) likeone = torch.ones_like(tensor1) # 创建相同大小全0张量 likezero = torch.zeros_like(tensor1) print(tensor1) print(likeone) print(likezero)
输出:
tensor([[1., 2., 3.], [4., 5., 6.]]) tensor([[1., 1., 1.], [1., 1., 1.]]) tensor([[0., 0., 0.], [0., 0., 0.]])
生成同纬度随机张量
# 生成同纬度随机张量 rantensor = torch.rand_like(tensor1) print(rantensor)
输出:
tensor([[0.1340, 0.2402, 0.7677], [0.6867, 0.7134, 0.0426]])
使用new_full填充张量
newfull = tensor1.new_full((3, 3), fill_value=8) print(newfull)
输出:
tensor([[8., 8., 8.], [8., 8., 8.], [8., 8., 8.]])
使用new_zeros构建全 0 张量
# 使用new_zeros构建全0张量 newzeros = tensor1.new_zeros((3, 3)) print(newzeros)
输出:
tensor([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
使用new_ones构建全 1 张量
# 使用new_ones构建全0张量 newones = tensor1.new_ones((3, 3)) print(newones)
输出:
tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]])
使用new_empty构建全 空 张量
# 使用new_empty构建全0张量 newempty = tensor1.new_empty((3, 3)) print(newempty)
输出:
tensor([[8., 8., 8.], [8., 8., 8.], [8., 8., 8.]])
张量的操作:
张量的类型转换(两种方式):
tensor1 = torch.Tensor([1, 2, 3]) print(tensor1.dtype) # 转换成整型的第一种方法 print(tensor1.int().dtype) # 转换成整形的第二种方法 print(tensor1.to(dtype=torch.int32).dtyp
输出:
torch.float32 torch.int32 torch.int32
获取张量的值(只能获取一个数):
tensor1[0].item()
张量转换成数组:
array = tensor1.numpy()
数组转换为张量:
array = np.ones((3, 3)) tensor1 = torch.as_tensor(array) tensor2 = torch.from_numpy(array) print(tensor1) print(tensor2)
输出:
tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]], dtype=torch.float64) tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]], dtype=torch.float64)
通过指定均值和标准差生成随机数:
# 通过指定均值和标准差生成随机数 torch.manual_seed(456) # 均值为0 标准差为1 a = torch.normal(mean=0, std=torch.tensor(1.0)) print(a)
生成0-1上均匀分布的张量:
# 生成0-1上均匀分布的张量 tensor1 = torch.rand(2, 3) print(tensor1)
生成相同尺寸的随机数张量:
# 生成相同尺寸的随机数张量 tensor1 = torch.rand_like(tensor2) print(tensor1)
生成0-50随机排列的张量:
# 生成0-50随机排列的张量 tensor1 = torch.randperm(50) print(tensor1)
输出:
tensor([42, 16, 43, 39, 28, 4, 5, 45, 48, 25, 34, 1, 21, 33, 13, 29, 15, 12, 40, 6, 10, 22, 17, 2, 26, 14, 47, 36, 0, 38, 11, 18, 37, 31, 7, 27, 3, 41, 9, 49, 23, 30, 8, 19, 44, 24, 35, 20, 32, 46])
张量数据CPU与GPU的转换:
print(tensor1.cpu()) print(tensor1.cuda())
输出:
tensor([1., 2., 3.]) tensor([1., 2., 3.], device='cuda:0')
判断Tensor是否在CUDA上(True在、False不在):
# 判断tensor是否在CUDA上 print(tensor1.is_cuda)
输出Tensor所在位置:
print(tensor1.device)
生成指定范围指定步长的张量:
# 生成指定范围指定步长的张量 tensor1 = torch.arange(start=0, end=100, step=5) print(tensor1)
输出:
tensor([ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95])
使用linspace生成固定数量等间隔的张量:
# 使用linspace生成固定数量等间隔的张量 tensor1 = torch.linspace(start=0, end=100, steps=10) print(tensor1)
输出:
tensor([ 0.0000, 11.1111, 22.2222, 33.3333, 44.4444, 55.5556, 66.6667, 77.7778, 88.8889, 100.0000])
生成以对数为间隔的张量:
# 生成以对数为间隔的张量 tensor1 = torch.logspace(start=0, end=1, steps=10) print(tensor1)
获取张量的维度:
注:shape 是一个属性,直接访问,也返回一个元组(tuple),包含了 PyTorch 张量 x 的各个维度的尺寸信息。
size() 是一个函数,调用时不需要加括号,返回一个元组(tuple),包含了 PyTorch 张量 x 的各个维度的尺寸信息。
print(tensor1.shape) print(tensor1.size())
输出:
torch.Size([3]) torch.Size([3])
计算张量中元素个数
tensor1.numel()
使用requires_grad是否需要计算梯度(只有浮点数可以计算梯度)
tensor1 = torch.tensor((4, 5, 6), dtype=torch.float32, requires_grad=True) print(tensor1)
输出:
tensor([4., 5., 6.], requires_grad=True)
创建具有特定大小的张量
tensor1 = torch.Tensor(2, 3) print(tensor1)
输出:
tensor([[0.0000, 1.8750, 0.0000], [2.0000, 0.0000, 2.1250]])
改变张量形状(reshape):
# 改变张量形状 tensor1 = torch.arange(15) tensor2 = tensor1.reshape(5, 3) tensor3 = torch.reshape(input=tensor1, shape=(3, 5)) print(tensor1) print(tensor2) print(tensor3)
输出:
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) tensor([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11], [12, 13, 14]]) tensor([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
改变张量形状(resize):
tensor2 = tensor1.resize(3, 5) print(tensor2)
输出:
tensor([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
改变张量形状(resize_):
tensor1.resize_(3, 5) print(tensor1)
输出:
tensor([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
将张量B形状设置和A一样:
# 将张量B形状设置和A一样 tensor1 = torch.Tensor([[9, 8, 7], [4, 5, 6]]) tensor2 = torch.randperm(6) print(tensor2) tensor2 = tensor2.resize_as(tensor1) print(tensor2)
输出:
tensor([4, 1, 2, 5, 0, 3]) tensor([[4, 1, 2], [5, 0, 3]])
升维:
# 升维 print(tensor1.shape) tensor1 = torch.unsqueeze(tensor1,dim=0) print(tensor1.shape)
输出:
torch.Size([2, 3]) torch.Size([1, 2, 3])
降维:
# 降维 print(tensor1.shape) tensor1 = torch.squeeze(tensor1, dim=0) print(tensor1.shape)
输出:
torch.Size([1, 2, 3]) torch.Size([2, 3])
使用expand进行张量扩展:
# 使用expand进行张量扩展 tensor1 = torch.arange(5) tensor2 = tensor1.expand(3, -1) print(tensor2)
输出:
tensor([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]])
使用expand_as进行张量扩展:
tensor3 = torch.arange(10).resize(2, 5) tensor2 = tensor1.expand_as(tensor3) print(tensor2)
输出:
tensor([[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]])
根据条件筛选:
# 根据条件筛选 tensor1 = torch.randperm(12).reshape(3, 4) tensor2 = -tensor1 print(tensor1) print(tensor2) tensor3 = torch.where(tensor1 > 6, tensor1, tensor2) print(tensor3)
输出:
tensor([[ 6, 4, 8, 2], [ 3, 0, 11, 10], [ 9, 1, 7, 5]]) tensor([[ -6, -4, -8, -2], [ -3, 0, -11, -10], [ -9, -1, -7, -5]]) tensor([[-6, -4, 8, -2], [-3, 0, 11, 10], [ 9, -1, 7, -5]])
获取矩阵张量下三角:
# 获取矩阵下三角 tensor1 = torch.randperm(16).reshape(4, 4) print(torch.tril(tensor1, diagonal=0))
输出:
tensor([[15, 0, 0, 0], [14, 3, 0, 0], [12, 0, 1, 0], [11, 13, 8, 6]])
获取矩阵张量上三角:
# 获取矩阵上三角 tensor1 = torch.randperm(16).reshape(4, 4) print(torch.triu(tensor1, diagonal=0))
输出:
tensor([[11, 13, 3, 7], [ 0, 4, 6, 14], [ 0, 0, 8, 5], [ 0, 0, 0, 2]])
生成对角阵:
# 生成对角阵 tensor1 = torch.diag(torch.Tensor([1, 2, 3])) print(tensor1)
输出:
tensor([[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
张量的拼接和拆分
拼接张量(cat):
tensor1 = torch.arange(12).reshape(3, 4) tensor2 = torch.linspace(0, 50, 12).reshape(3, 4) # 0维度拼接张量 列上拼接 tensor3 = torch.cat((tensor1, tensor2), dim=0) # 1维度拼接张量 行上拼接 tensor4 = torch.cat((tensor1, tensor2), dim=1) print(tensor3) print(tensor4)
输出:
tensor([[ 0.0000, 1.0000, 2.0000, 3.0000], [ 4.0000, 5.0000, 6.0000, 7.0000], [ 8.0000, 9.0000, 10.0000, 11.0000], [ 0.0000, 4.5455, 9.0909, 13.6364], [18.1818, 22.7273, 27.2727, 31.8182], [36.3636, 40.9091, 45.4545, 50.0000]]) tensor([[ 0.0000, 1.0000, 2.0000, 3.0000, 0.0000, 4.5455, 9.0909, 13.6364], [ 4.0000, 5.0000, 6.0000, 7.0000, 18.1818, 22.7273, 27.2727, 31.8182], [ 8.0000, 9.0000, 10.0000, 11.0000, 36.3636, 40.9091, 45.4545, 50.0000]])
沿新的维度拼接张量(stack):
tensor1 = torch.arange(12).reshape(3, 4) tensor2 = torch.linspace(0, 50, 12).reshape(3, 4) # 0维度拼接张量 列上拼接 tensor3 = torch.stack((tensor1, tensor2), dim=0) # 1维度拼接张量 行上拼接 tensor4 = torch.stack((tensor1, tensor2), dim=1) print(tensor3) print(tensor4)
输出:
tensor([[[ 0.0000, 1.0000, 2.0000, 3.0000], [ 4.0000, 5.0000, 6.0000, 7.0000], [ 8.0000, 9.0000, 10.0000, 11.0000]], [[ 0.0000, 4.5455, 9.0909, 13.6364], [18.1818, 22.7273, 27.2727, 31.8182], [36.3636, 40.9091, 45.4545, 50.0000]]]) tensor([[[ 0.0000, 1.0000, 2.0000, 3.0000], [ 0.0000, 4.5455, 9.0909, 13.6364]], [[ 4.0000, 5.0000, 6.0000, 7.0000], [18.1818, 22.7273, 27.2727, 31.8182]], [[ 8.0000, 9.0000, 10.0000, 11.0000], [36.3636, 40.9091, 45.4545, 50.0000]]])
分割张量(chunk):
tensor1 = torch.arange(12).reshape(2, 6) tensor2 = torch.chunk(tensor1, 2, dim=0) tensor3 = torch.chunk(tensor1, 6, dim=1) print(tensor1) print(tensor2) print(tensor3)
输出:
tensor([[ 0, 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10, 11]]) (tensor([[0, 1, 2, 3, 4, 5]]), tensor([[ 6, 7, 8, 9, 10, 11]])) (tensor([[0], [6]]), tensor([[1], [7]]), tensor([[2], [8]]), tensor([[3], [9]]), tensor([[ 4], [10]]), tensor([[ 5], [11]]))
分割张量指定每个块大小(spilt):
a, b, c = torch.split(tensor1, [1, 2, 3], dim=1) print(a) print(b) print(c)
输出:
tensor([[0], [6]]) tensor([[1, 2], [7, 8]]) tensor([[ 3, 4, 5], [ 9, 10, 11]])