Pytorch 入门与提高(1)—创建 Tensor

1,425 阅读5分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

现在文章的标题设计是文章是否获取更多阅读一个关键步骤,我想了半天,不断推翻最后还是用了一个朴实无华的标题——Pytorch 入门与提高(1),不过希望我们分享内容可以给你带来价值,

引入依赖,这里除了今天主角,我们还引入一个 numpy

import numpy as np
import torch

创建 Tensor

data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)

创建 Tensor 非常简单,我们直接用数据输入到 torch.tensor 便创建了一个 Tensor 数据类型。

基于 numpy 和 list 来创建 Tensor

创建 Tensor 方法有很多,我们先来介绍基于既有 numpy 和 list 集合类型来创建 Tensor。

通过 numpy 来创建 Tensor

在 python 项目中,随处可以看到 numpy 的身影、无论是机器学习还是数据分析挖掘项目中都可以会用到 numpy。所以在 tensorflow 和 pytorch 这些当下流行的深度学习框架都提供了对 numpy 的支持。

a = np.array([1,1.2])

使用 torch.from_numpy 将 numpy 的 ndarray 类型转换为 pytorch 的 tensor 类型,并且保持类型不变 float64

a_tensor = torch.from_numpy(a)
a_tensor
tensor([1.0000, 1.2000])

通过 List 来创建 Tensor

除了上边可以通过 numpy 的 ndarray 创建 Tensor 以外,pytorch 还支持通过 list 来创建 Tensor。

a_list = [1,1.2]
a_tensor = torch.tensor(a_list)
a_tensor
tensor([1.0000, 1.2000])
b_tensor = torch.FloatTensor(a_list)
b_tensor
tensor([1.0000, 1.2000], dtype=torch.float32)

注意这里使用 torch.tensor 创建 Tensor,在 torch 中还有一个大写开头 torch.Tensor,他们具有不同用途,也就是接收不同参数来创建 Tensor,小写开头 tensor 接收 list 或者 numpy 对象作为参数来创建 Tensor,而大写开头除此以外还接收表示size来创建一个随机初始化数据的 Tensor。

a_empty = torch.empty(2,3)
a_empty
tensor([[-2.3158e+77, -2.3158e+77, 5.9288e-323],
        [ 0.0000e+00, 2.1220e-314, 2.9805e+179]])
a_tensor = torch.FloatTensor(2,3,3,3)
a_tensor

    tensor([[[[ 2.4174e-06,  2.1780e-04,  1.2914e-11],
              [ 1.6691e+22,  2.6705e+23,  8.2662e-10],
              [ 2.7300e-06,  8.1714e+20,  3.2944e-09]],
    
             [[ 4.2248e-05,  2.3328e-18,  1.6678e+19],
              [ 7.0976e+22,  1.2853e+31,  3.0979e+32],
              [ 2.3329e-18,  4.5447e+30,  7.0062e+22]],
    
             [[ 2.1058e+35,  2.6447e+20,  6.4825e-10],
              [ 1.2849e+31,  1.8395e+25,  6.1963e-04],
              [ 2.0662e+20,  8.1936e-10,  2.1344e-07]]],


​    
            [[[ 1.3236e-08,  4.3964e-05,  6.7498e-07],
              [ 6.6288e-10,  1.3679e+22,  2.3049e-12],
              [ 7.1429e+31,  2.5226e-18,  6.4825e-10]],
    
             [[ 1.0015e-11,  1.2352e-08,  2.6707e-06],
              [ 4.0518e-11,  2.6079e-09,  2.9572e-18],
              [ 7.2646e+22,  7.2250e+28,  2.5226e-18]],
    
             [[ 2.4283e-18,  1.7516e-43,  0.0000e+00],
              [ 0.0000e+00, -8.5899e+09,  1.8190e-27],
              [-3.6902e+19,  1.2612e-44, -8.5899e+09]]]], dtype=torch.float32)

使用 empty 或 FloatTensor 进行未初始化创建 Tensor,其实 Tensor 中也是有随机给定的值,不过这些值过大或者过小。

设置默认类型

如果我们在创建 tesnor 没有指定数据类型时,系统就会使用 torch.FloatTensor 默认数据类型。

a = torch.tensor([1,]).type()
a

设置默认类型,可以通过 set_default_tensor_type 来设置默认 tensor 数据类型。

torch.set_default_tensor_type(torch.DoubleTensor)
a = torch.tensor([1.2,2.1]).type()
a
'torch.DoubleTensor'

使用 rand 方法随机创建 tensor

可以调用 rand 方法来创建 tensor ,rand 创建的 tensor 是由一些随机数初始化而得,rand 方法接收一个指定 tensor 的形状的参数,下面创建一个 2×32 \times 3 tensor。

torch.rand(2,3)
tensor([[0.4056, 0.9493, 0.2661],
        [0.2156, 0.4715, 0.4217]])

使用 rand_like 方法创建 tensor

rand_like 和 rand 相比不同处,rand_like 接收一个 tensor 作为参数,rand_like 创建出的 tensor 会与输入 tensor 的形状一致。

a = torch.tensor([[2.,3.,4.],[1.,2.,3.]])
res = torch.rand_like(a)
print(res.shape)
torch.Size([2, 3])

通常创建好 Tensor 我们都需要查看一下 Tensor 形状

通过随机数来初始化一个 Tensor

randint 用于创建一个整数随机数组成的 Tensor

# [min,max)
torch.randint(1,10,(2,3))
  • 第一个参数(low)默认值为 0 定义从一定范围随机抽取一个随机数起始值
  • 第二个参数(high) 范围的终止值
  • 第三个参数(size) 创建 tensor 形状

    tensor([[6, 1, 9],
            [1, 2, 8]])
# 正态分布,randn 表示均值为 0 方差为 1 的正态分布
torch.randn(3,3)
tensor([[ 0.7808,  0.9283, -0.3443],
        [-0.6449,  0.7878, -0.2888],
        [-0.5749,  0.0562,  2.5841]])
# normal 函数提供自定义均值和方差来创建 tensor,例如我们想要创建 2 * 5 的正态分布,先创建 10 数,然后创建 10 均值,再创建 10 个方差
a = torch.normal(mean=torch.full([10],0.),std=torch.arange(1,0,-0.1))
# full 函数创建 10 为 0 的 Tensor
a
tensor([-0.7043,  2.0245, -0.3698,  0.3927,  0.0138, -0.2230, -0.8763,  0.0090,
         0.2446,  0.0955])
torch.normal(mean=0.5, std=torch.arange(1., 6.))
tensor([ 1.0381, -1.3676, -5.2665,  5.1679, -8.0477])

normal 方法来创建 Tensor

用 normal 来创建一个张量,包含从给定参数means,std的离散正态分布中抽取随机数。 均值means是一个 Tensor,包含每个输出元素相关的正态分布的均值。 std是一个 tensor,包含每个输出元素相关的正态分布的标准差。 均值和标准差的形状不须匹配,但每个 tensor 的元素个数须相同。

torch.normal(mean=torch.arange(1., 11.), std=torch.arange(1, 0, -0.1))
tensor([0.6371, 3.1117, 3.2735, 3.7251, 3.8135, 5.7626, 7.0770, 8.1662, 9.1001,
        9.9700])
tensor_full_a = torch.full((2,3),7.)
tensor_full_a
tensor([[7., 7., 7.],
        [7., 7., 7.]])
torch.full((2, 3), 3.141592)
tensor([[3.1416, 3.1416, 3.1416],
        [3.1416, 3.1416, 3.1416]])
# 使用 reshape 对形状进行变换
a = a.reshape(2,5)
a
tensor([[-0.7043,  2.0245, -0.3698,  0.3927,  0.0138],
        [-0.2230, -0.8763,  0.0090,  0.2446,  0.0955]])

linspace 方法来创建 Tensor

torch.linspace(0,10,steps=4)

创建一个 Tensor,那么 linspace 可以创建出一个什么样的 Tensor,第一个和第二个参数定义区间起始位置和终止位置,steps 在start和end间生成的样本数。

tensor([ 0.0000,  3.3333,  6.6667, 10.0000])
torch.logspace(0,-1,steps=10)
tensor([1.0000, 0.7743, 0.5995, 0.4642, 0.3594, 0.2783, 0.2154, 0.1668, 0.1292,
        0.1000])

通过对于 Tensor 改变其形状也可以获得一个新的 Tensor

b = torch.tensor([[2,3,4],[1,2,3]])
b.reshape(3,2)
tensor([[2, 3],
        [4, 1],
        [2, 3]])

full 方法创建 tensor

full 方法接收两个参数,一个参数用于指定创建的 tensor 的形状,第二参数是填充 tensor 的数值。

# a.reshape(3,2)
torch.full([2,3],7.)
tensor([[7., 7., 7.],
        [7., 7., 7.]])
# 创建一个标量
torch.full([],7)
tensor(7.)
# 创建一个向量
torch.full([1],7)
tensor([7.])

arange 方法创建 tensor

arange 创建 tensor 接收一个区间,区间原则符合左闭右开原则,[)

torch.arange(0,10)
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 第三个参数表示步进
torch.arange(0,10,2)
tensor([0, 2, 4, 6, 8])

等分方法创建 tensor

linspace 是在一个指定区间进行等分,例如 steps 对区间进行 steps 等分。

torch.linspace(0,10,steps=4)
tensor([ 0.0000,  3.3333,  6.6667, 10.0000])
torch.linspace(0,10,steps=10)
tensor([ 0.0000,  1.1111,  2.2222,  3.3333,  4.4444,  5.5556,  6.6667,  7.7778,
         8.8889, 10.0000])
torch.linspace(0,10,steps=11)
tensor([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
torch.logspace(0,-1,steps=10)
tensor([1.0000, 0.7743, 0.5995, 0.4642, 0.3594, 0.2783, 0.2154, 0.1668, 0.1292,
        0.1000])
torch.logspace(0,1,steps=10)
tensor([ 1.0000,  1.2915,  1.6681,  2.1544,  2.7826,  3.5938,  4.6416,  5.9948,
         7.7426, 10.0000])

其他方法创建 tensor

  • ones 方法创建一个全部都是 1 的 tensor,ones 接收参数用于指定 tensor 形状
  • zeros 方法创建一个全部都是 0 的 tensor,ones 接收参数用于指定 tensor 形状
  • eye 方法创建一个对角线全部都是 1 的,其他位置都是 0 的 tensor,ones 接收参数用于指定 tensor 形状

torch.ones(3,3)
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
torch.zeros(3,3)
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])
torch.eye(3,2)
tensor([[1., 0.],
        [0., 1.],
        [0., 0.]])
torch.eye(3)
tensor([[1., 0., 0.],
        [0., 1., 0.],
        [0., 0., 1.]])
a = torch.zeros(3,3)
torch.ones_like(a)
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
# 随机打散 [0,10)
torch.randperm(10)
tensor([1, 3, 0, 2, 9, 5, 6, 7, 4, 8])
a = torch.rand(2,3)
b = torch.rand(2,2)
idx = torch.randperm(2)
idx
tensor([0, 1])
a[idx]
tensor([[0.9753, 0.6958, 0.7198],
        [0.9417, 0.3410, 0.9740]])
b[idx]
tensor([[0.0652, 0.7491],
        [0.9848, 0.7652]])