pytorch中常用的方法(二)

注意:千万不要想着把pytorch中的方法给全部记住,我们只需要对这个方法的使用有个大致印象就行,等到需要的时候再上网查一下具体的用法即可。因为就算你现在对这个方法很了解,如果长时间不使用该方法,那么你还是会忘记的(啊哈哈哈哈哈),所以切记不要想着背住这些方法。

1.1 reshape()、view()方法

pytorch中reshape()、view()都可以用来改变tensor的shape(形状、大小),但tensor本身的数据保持不变。reshape(*shape) -> Tensor view(*shape) -> Tensorshape可以为:tuple、list或int。这两种方法的用法如下所示。

import torch

x = torch.tensor([[1, 3, 5], [2, 4, 6]])
y1 = x.reshape(3, 2)
y2 = x.view(3, 2)
y3 = x.reshape(-1,2) # 某个维度为-1时,会根据原tensor数据大小推出其它维度的大小。
print(f"reshape方法:{y1}") 
print(f"view方法:{y2}")
print(f"自适应生成其它维度的大小:{y3}")

输出:
reshape方法:tensor([[1, 3],
        [5, 2],
        [4, 6]])
view方法:tensor([[1, 3],
        [5, 2],
        [4, 6]])
自适应生成其它维度的大小:tensor([[1, 3],
        [5, 2],
        [4, 6]])

我们还可以使用函数torch.reshape(input, shape),该函数和上面的reshape()、view()实现的功能相同。

import torch

x = torch.tensor([[1, 3, 5], [2, 4, 6]])
y1 = torch.reshape(x, (3, 2))
y2 = torch.reshape(x, (-1, 2))
print(f"torch.reshape方法:{y1}")
print(f"自适应生成其它维度的大小:{y2}")

输出:
torch.reshape方法:tensor([[1, 3],
        [5, 2],
        [4, 6]])
自适应生成其它维度的大小:tensor([[1, 3],
        [5, 2],
        [4, 6]])

参考:Pytorch基础:Tensor的reshape方法

1.2 expand()、repeat()方法

  1. pytorch中expand()repeat()方法常用于张量数据的复制和维度扩展。其中对应方法的表示形式分别为:tensor.expand(*sizes)tensor.repeat(*sizes)。
  2. expand()可以将tensor数据中形状(shape)维度为1的数据扩充到指定大小。例如:某个tensor数据的shape为torch.Size([1, 4, 4]),其中第一个维度为1、第二、三个维度分别为4、4,expand()方法只能在第一个维度(即为1)上进行扩展,无法作用于第二、三个维度(即分别为4,4)。从下面代码可以看出,对于shape为[1,2,2]的tensor数据将维度1扩展为维度3,相当于把原始tensor数据复制了3份。举个例子:假如每个人手里都有2个苹果和2个香蕉(shape为[1,2,2]),我们将三个人的苹果和香蕉聚集在一起(也就是扩展:expand()),最后得到了3个人的苹果和香蕉(shape为[3,2,2])
import torch

tensor = torch.randn(1, 2, 2)
# 记住:只能在1这个维度上面进行扩展,其它的维度不可以。
tensor_expand = tensor.expand(3, 2, 2)
print(f"tensor:  {tensor}")
print(f"tensor_expand:  {tensor_expand}")
print(f"扩展后的维度大小:  {tensor_expand.shape}")

输出:
tensor:  tensor([[[ 1.4252,  0.4148],
         [-1.2340,  0.4633]]])
tensor_expand:  tensor([[[ 1.4252,  0.4148],
         [-1.2340,  0.4633]],

        [[ 1.4252,  0.4148],
         [-1.2340,  0.4633]],

        [[ 1.4252,  0.4148],
         [-1.2340,  0.4633]]])
扩展后的维度大小:  torch.Size([3, 2, 2])
  1. 由上面可知,expand()只能作用于维度为1的tensor数据,那么对于不是1的维度我们可以借助repeat()方法。其方法的形式为tensor.repeat(*sizes)size 表示在原始tensor数据的各个维度上复制的次数。废话少说,看下面代码吧,给各位一个建议,如果对某个方法的定义不太了解的话,那就亲自敲一下这个代码,这样慢慢的你就对该方法有个初步认识了。
import torch

tensor = torch.randn(1, 2, 2)
tensor_repeat = tensor.repeat(2, 2, 2)  # 在原始tensor数据的第1、2、3个维度上均复制2次
print(f"tensor:  {tensor}")
print(f"tensor_repeat:  {tensor_repeat}")
print(f"扩展后的维度大小:  {tensor_repeat.shape}")\

输出:
tensor:  tensor([[[ 0.6281, -0.9614],
         [ 0.7230,  1.2946]]])
tensor_repeat:  tensor([[[ 0.6281, -0.9614,  0.6281, -0.9614],
         [ 0.7230,  1.2946,  0.7230,  1.2946],
         [ 0.6281, -0.9614,  0.6281, -0.9614],
         [ 0.7230,  1.2946,  0.7230,  1.2946]],

        [[ 0.6281, -0.9614,  0.6281, -0.9614],
         [ 0.7230,  1.2946,  0.7230,  1.2946],
         [ 0.6281, -0.9614,  0.6281, -0.9614],
         [ 0.7230,  1.2946,  0.7230,  1.2946]]])
扩展后的维度大小:  torch.Size([2, 4, 4])

参考:【Pytorch】对比expand和repeat函数
「PyTorch」repeat() 和 expand()

1.3 item()、tolist()方法

  1. item()方法:将包含一个元素的tensor数据转为python数字,这仅适用于具有一个元素的张量tensor;
  2. tolist()方法:将tensor数据转为python列表或数字返回。
import torch

tensor1 = torch.tensor([6], dtype=int)
num1 = tensor1.item()
tensor2 = torch.tensor([1, 2, 3, 4, 5, 6])
list1 = tensor2.tolist()
print(type(num1))
print(type(list1))

输出:
<class 'int'>
<class 'list'>

1.4 sum()、min()、mean()函数

  1. torch.sum() 表示对输入tensor数据的某一维度进行求和。共有两种用法:torch.sum(input, dtype=None) torch.sum(input, list: dim, bool: keepdim=False, dtype=None) → Tensor。其中 input:输入的tensor数据;dim:进行求和的维度,可以是一个列表;keepdim:默认为False,若keepdim=True,则返回的Tensor除dim之外的维度与input相同。因为求和之后这个dim的元素个数为1,所以要被去掉,如果要保留这个维度,则应当keepdim=True。
import torch

tensor1 = torch.tensor([[1, 3, 5], [2, 4, 6]])
sum1 = torch.sum(tensor1)
sum2 = torch.sum(tensor1, dim=0)
sum3 = torch.sum(tensor1, dim=1)
print(sum1)
print(sum2)
print(sum3)

输出:
tensor(21)
tensor([ 3,  7, 11])
tensor([ 9, 12])
  1. torch.min() :返回tensor数据中的最小值。具体用法可以参考Pytorch的max()与min()函数
import torch

tensor1 = torch.tensor([[1, 3, 5], [2, 4, 6]])
min1 = torch.min(tensor1)
min2 = torch.min(tensor1, dim=0)
min3 = torch.min(tensor1, dim=1)
value, indices = torch.min(tensor1, dim=1)
print(min1)
print("------min dim=0-------")
print(min2)
print("------min dim=1-------")
print(min3)
print("------value indices-------")
print(f"value={value},indices={indices}")

输出:
tensor(1)
------min dim=0-------
torch.return_types.min(
values=tensor([1, 3, 5]),
indices=tensor([0, 0, 0]))
------min dim=1-------
torch.return_types.min(
values=tensor([1, 2]),
indices=tensor([0, 0]))
------value indices-------
value=tensor([1, 2]),indices=tensor([0, 0])

由上面代码返回结果可知:torch.min() 函数的返回值由values(值)和indices(索引)组成,values中存放最小值,indices存放最小值对应的索引。
3. torch.max():返回tensor数据中的最大值。用法和torch.min() 类似,就不解释这个方法了。

1.5 squeeze()、unsqueeze方法

  1. torch.squeeze(input, dim=None, out=None) :该函数功能是维度压缩,其中 input 中大小为1的所有维都已删除。例如:如果 input 的大小为(A×1×B×C×1×D),那么返回的tensor的大小则为(A×B×C×D)。当我们指定 dim 时,那么只在给定的维度上进行压缩操作。
import torch

tensor1 = torch.randn(512, 1, 1, 10)
squee1 = torch.squeeze(tensor1)
squee2 = torch.squeeze(tensor1, dim=1)
print(tensor1.shape)
print(squee1.shape)
print(squee2.shape)

输出:
torch.Size([512, 1, 1, 10])
torch.Size([512, 10])
torch.Size([512, 1, 10])
  1. torch.unsqueeze(input, dim):该函数功能是提高tensor数据的维度,dim 表示在指定的地方增加一个维度。
import torch

tensor1 = torch.randn(512, 10)
unsquee1 = torch.unsqueeze(tensor1, dim=1)
unsquee2 = torch.unsqueeze(tensor1, dim=2)
print(tensor1.shape)
print(unsquee1.shape)
print(unsquee2.shape)

输出:
torch.Size([512, 10])
torch.Size([512, 1, 10])
torch.Size([512, 10, 1])

1.6 tensor与numpy之间的转换

  1. 通过numpy()方法将Tensor转化为NumPy数组;
  2. 通过from_numpy()将NumPy数组转Tensor;
  3. numpy()、from_numpy()两个函数所产生的NumPy数组和Tensor共享相同的内存(所以他们之间的转换很快),改变其中⼀个时另⼀个也会改变!参考如何将Tensor和NumPy相互转换
import torch
import numpy as np

print("----Tensor 转化为 NumPy----")
tensor1 = torch.tensor([1, 2, 3, 4, 5, 6])
npy1 = tensor1.numpy()
print(type(npy1))
npy1 += 1  # 修改npy1中的数据,tensor1数据也会发生改变
print(tensor1)

print("----NumPy 转化为 Tensor----")
npy2 = np.ones(5)
tensor2 = torch.from_numpy(npy2)
print(tensor2.type())
tensor2 += 1  # 修改tensor2中的数据,npy2数据也会发生改变
print(npy2)

输出:
----Tensor 转化为 NumPy----
<class 'numpy.ndarray'>
tensor([2, 3, 4, 5, 6, 7])
----NumPy 转化为 Tensor----
torch.DoubleTensor
[2. 2. 2. 2. 2.]

1.7 pytorch中拼接函数:cat()、stack()、add()

  1. cat() 函数: 在给定维度上对输入张量序列进行连接操作。函数表示为:torch.cat(inputs, dim=?) → Tensor),其中inputs : 待连接的张量序列,可以是任意相同Tensor类型的python序列;dim : 沿着该维度连接张量序列。
import torch

tensor1 = torch.ones(2, 4)
tensor2 = torch.zeros(3, 4)
out1 = torch.cat([tensor1, tensor2], dim=0)
print("-------------dim=0-------------")
print(out1)
tensor3 = torch.zeros(2, 2)
out2 = torch.cat([tensor1, tensor3], dim=1)
print("-------------dim=1-------------")
print(out2)

输出:
-------------dim=0-------------
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]])
-------------dim=1-------------
tensor([[1., 1., 1., 1., 0., 0.],
        [1., 1., 1., 1., 0., 0.]])

注意
  对于形状大小(shape)为[b,c,h,w]的tensor数据来说,第一个维度(b)的下标索引为0,第二个维度( c)的下标索引为1,第三个维度(h)的下标索引为2,第四个维度(w)的下标索引为3。 如果我们把cat()函数中的参数dim看成是shape某个维度的下标索引,那么当dim=0时,除了第一个维度的大小可以不同,其它维度大小均需要保持相同,否则会报错。当dim=1时,除了第二个维度的大小可以不同,其它维度大小均需要保持相同,… 。
  由上面代码可知:当dim=0时,张量tensor1和tensor2的形状大小(shape)分别为[2,4]和[3,4],第一个维度大小不同,但第二个维度大小必须相同。同理,当dim=1时,张量tensor1和tensor3的形状大小(shape)分别为[2,4]和[2,2],第二个维度大小可以不同,但第一个维度大小必须相同。
  总结一句话:cat() 函数沿着dim这个维度进行拼接时,需要保证除了dim以外的其它维度大小相同。
参考:Pytorch中的torch.cat()函数
torch.cat()函数

  1. stack() 函数:沿着一个新维度对输入张量序列进行连接,输入序列中张量的形状(shape)均应该相同,拼接之后会将tensor数据的维度增加1。该函数表示形式为torch.stack(inputs, dim=0) → Tensor,其中inputs为待拼接的张量序列,可以是列表或者元组;dim :新的维度 。代码如下:
import torch

a = torch.randn(6, 6)
b = torch.randn(6, 6)
out1 = torch.stack([a, b], dim=0)
out2 = torch.stack([a, b], dim=1)
out3 = torch.stack([a, b], dim=2)
print(f"dim=0:  {out1.shape}")
print(f"dim=1:  {out2.shape}")
print(f"dim=2:  {out3.shape}")

输出:
dim=0:  torch.Size([2, 6, 6])
dim=1:  torch.Size([6, 2, 6])
dim=2:  torch.Size([6, 6, 2])

参考:torch.stack()的官方解释,详解以及例子
【Pytorch】torch.stack()的使用
除了cat()stack(), pytorch还提供了其它方式的拼接方法hstack()函数、vstack()函数和dstack()函数。其中:hstack() 是将张量序列沿着水平方向进行连接;vstack() 是将张量序列沿着垂直方向进行连接;dstack() 是将张量序列沿着深度方向进行连接。

import torch

a = torch.randn(6, 6)
b = torch.randn(6, 6)
out_h = torch.hstack([a, b])  # 水平方向
out_v = torch.vstack([a, b])  # 垂直方向
out_d = torch.dstack([a, b])  # 深度方向
print(f"水平方向合并:  {out_h.shape}")
print(f"垂直方向合并:  {out_v.shape}")
print(f"深度方向合并:  {out_d.shape}")

输出:
水平方向合并:  torch.Size([6, 12])
垂直方向合并:  torch.Size([12, 6])
深度方向合并:  torch.Size([6, 6, 2])

参考:Pytorch 合并两个维度不同的张量
pytorch每日一学33(torch.hstack())从水平方向(列方向)叠加向量

  1. add() 函数:用于对两个张量进行逐元素加法运算。
import torch

a = torch.tensor([12, 6, 1])
b = torch.tensor([8, 14, 19])
out = torch.add(a, b)
print(out)

输出:
tensor([20, 20, 20])

参考:torch.cat()、 torch.add()、torch.subtract()、torch.subtract()和torch.div()函数详解和示例

1.8 pytorch中的拆分函数:split()、chunk()

  1. split() 函数:按照块的大小拆分tensor数据,返回一个拆分后的张量序列组成的"元组-tuple"。torch.split(tensor, split_size_or_section, dim=0),其中tesnor :输入数据;split_size_or_section:需要拆分的大小(int或者list);dim:需要拆分的维度。
import torch

tensor = torch.randn(3, 64, 64)
tuple1, tuple2 = torch.split(tensor, [1, 2], dim=0)  # 将第一个维度"3"进行拆分,拆分成一个"1"和一个"2"。
print(tuple1.shape)
print(tuple2.shape)

输出:
torch.Size([1, 64, 64])
torch.Size([2, 64, 64])
  1. chunk() 函数:按照块的数量拆分tensor数据,返回一个拆分后的张量序列组成的"元组-tuple"。torch.chunk(input, chunks, dim=0) → List of Tensors
import torch

tensor = torch.randn(8, 64, 64)
tuple1, tuple2 = torch.chunk(tensor, 2, dim=0)  # 将第一个维度"8"拆分成两份,也就变成了两个4。
print(tuple1.shape)
print(tuple2.shape)

输出:
torch.Size([4, 64, 64])
torch.Size([4, 64, 64])

参考:torch.split() 与 torch.chunk()
3. 还可以使用split()、chunk() 方法对tensor数据进行拆分。

import torch

tensor = torch.randn(8, 64, 64)
tuple1_split, tuple2_split = tensor.split([6, 2], dim=0)
tuple1_chunk, tuple2_chunk = tensor.chunk(2, dim=0)
print("---------split()方法------------")
print(tuple1_split.shape)
print(tuple2_split.shape)
print("---------chunk()方法------------")
print(tuple1_chunk.shape)
print(tuple2_chunk.shape)

输出:
---------split()方法------------
torch.Size([6, 64, 64])
torch.Size([2, 64, 64])
---------chunk()方法------------
torch.Size([4, 64, 64])
torch.Size([4, 64, 64])

1.9 flatten()函数

torch.flatten(input, start_dim=0, end_dim=-1) 是一个对多维数据的降维函数。其中,input 表示要被扁平化的tensor;start_dim :扁平化的起始维度;end_dim:扁平化的结束维度。

import torch

tensor = torch.randn(10, 5, 2)
flat1 = torch.flatten(tensor)  # torch.flatten(tensor)等于torch.flatten(tensor,0)
flat2 = torch.flatten(tensor, 0)
flat3 = torch.flatten(tensor, 1)  # dim=1表示从第二个维度开始扁平化
flat4 = torch.flatten(tensor, 2)  # dim=2表示从第三个维度开始扁平化
print(f"dim=0: {flat1.shape}")
print(f"dim=0: {flat2.shape}")
print(f"dim=1: {flat3.shape}")
print(f"dim=2: {flat4.shape}")

输出:
dim=0: torch.Size([100])
dim=0: torch.Size([100])
dim=1: torch.Size([10, 10])
dim=2: torch.Size([10, 5, 2])
  1. torch.nn.Flatten() 默认从第二维开始扁平化。
import torch

tensor = torch.randn(10, 5, 2)
flat = torch.nn.Flatten()
tensor_flat = flat(tensor)  # 默认从第二维开始扁平化
print(tensor_flat.shape)

输出:
torch.Size([10, 10])

参考:torch.flatten()与torch.nn.Flatten()

1.10 torch.eq()、torch.argmax()

  1. torch.eq() 函数:用于对两个张量进行逐元素的比较,若同一位置的两个元素相同,则返回True;否则返回False。torch.eq(input, other, *, out=None),其中input :必须是tensor数据,该张量用于比较;other:可以是张量tensor,也可以是一个值value,该函数返回一个Boolean类型的张量。
import torch

pre_label = torch.tensor([1, 2, 3, 4, 6])
true_label = torch.tensor([1, 2, 3, 4, 5])
out = torch.eq(pre_label, true_label)
print(out)
print(out.sum())  # 统计两个张量中同一位置下相同元素的个数。

输出:
tensor([ True,  True,  True,  True, False])
tensor(4)

参考:torch.eq与torch.ne——判断数组中的数值是否相等

  1. torch.argmax() 函数:返回指定维度下最大值对应的下标索引。
import torch

pred = torch.tensor([[3, 1, 4, 5, 6, 2], [1, 2, 3, 4, 5, 6]])
pred_label = torch.argmax(pred)   # 没有指定dim的值,表示把pred中的元素平整化为一维向量,然后找最大值的索引。
pred_label0 = torch.argmax(pred, dim=0)  # 求出每一列最大值的索引
pred_label1 = torch.argmax(pred, dim=1)  # 求出每一行最大值的索引
print(pred_label)
print(pred_label0)
print(pred_label1)

输出:
tensor(4)
tensor([0, 1, 0, 0, 0, 1])
tensor([4, 5])

参考:Pytorch中torch.argmax()函数解析

1.11 pytorch中cuda相关操作

import torch

print(f"查看pytorch的版本: {torch.__version__}")
print(f"查看cuda是否可用: {torch.cuda.is_available()}")
print(f"查看GPU的数量: {torch.cuda.device_count()}")
print(f"查看GPU的索引号(默认从0开始): {torch.cuda.current_device()}")
print(f"根据索引号查看GPU的名字: {torch.cuda.get_device_name(0)}")

"""
将tensor数据转移到相应的GPU上。
使用".cuda()"可以将内存中的Tensor转换到GPU上。
如果有多块GPU,可以使用.cuda(i)来表示第i块GPU所对应的显存(从0开始),cuda(0)和cuda()等价.
"""
tensor1 = torch.tensor([1, 2, 3]).cuda()
print(tensor1)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
tensor2 = torch.tensor([1, 2, 3]).to(device)
print(tensor2)
tensor3 = torch.tensor([1, 2, 3], device=device)
print(tensor3)

输出:
查看pytorch的版本: 1.10.0
查看cuda是否可用: True
查看GPU的数量: 1
查看GPU的索引号(默认从0开始): 0
根据索引号查看GPU的名字: NVIDIA GeForce RTX 3060 Laptop GPU
tensor([1, 2, 3], device='cuda:0')
cuda:0
tensor([1, 2, 3], device='cuda:0')
tensor([1, 2, 3], device='cuda:0')
  • 16
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值