Pytorch中Tensor类型转换

文章目录

  • 1. Tensor初始化
    • 1.1 常数初始化
    • 1.2 随机初始化
  • 2. Tensor类型转换
    • 2.1 普通类型转Tensor
    • 2.2 torch.tensor与torch.Tensor比较
    • 2.3 Tensor之间类型转换
    • 2.4 Tensor 与numpy之间转换
    • 2.5 Tensor转普通类型

以下测试环境基于

torch==1.8.1+cu101

1. Tensor初始化

1.1 常数初始化

函数 含义
torch.zeros(size) 创建一个全0的张量
torch.ones(size) 创建一个全1的张量
torch.empty(size) 创建一个空的张量
torch.full(size, fill_value) 创建一个全为 full_value 的张量
torch.eye(size) 创建一个全为 full_value 的张量

测试如下:

import torch

empty_test = torch.empty((4, 3))
ones_test = torch.ones((4, 3))
zeros_test = torch.zeros((4, 3))
full_test = torch.full((4, 3), 3)
eye_test = torch.eye(4) # 该API特别适合拿来创建One-hot编码
print('torch.empty输出:')
print(empty_test)
print('torch.ones输出:')
print(ones_test)
print('torch.zeros输出:')
print(zeros_test)
print('torch.full输出:')
print(full_test)
print('torch.eye输出:')
print(eye_test)

输出如下:

torch.empty输出:

tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])

torch.ones输出:

tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])

torch.zeros输出:

tensor([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])

torch.full输出:

tensor([[3, 3, 3],
[3, 3, 3],
[3, 3, 3],
[3, 3, 3]])

torch.eye输出:

tensor([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])

上述的方法除 torch.eye 外,都有一个 like 方法,只需要在上述方法名后面加个 _like 即可,如 torch.zeros_like() ,这些加了 _like 的方法能够传入已有张量,初始化一个与传入张量形状一致的张量,调用 zeros_like() 则初始化张量值为全0,调用 ones_like() 则初始化值为全1。

1.2 随机初始化

函数 含义
torch.rand(size) 创建一个 [0,1) 均匀分布的随机数张量
torch.randn(size) 创建一个 N(0,1) 的正态分布随机数张量
torch.normal(mean, std) mean和std都是tensor,返回的形状由mean和std的形状决定,要求两者形状一样
torch.rand_like(input) 创建一个与输入张量形状一致的 [0,1) 范围的张量
torch.randint(low, high, size) 创建一个范围为 [low, high) 的随机整数张量

测试如下:

import torch

rand_test = torch.rand(2, 3)
randn_test = torch.randn(2, 3)
normal_test = torch.normal(mean=torch.zeros((2, 3)), std=torch.ones((2, 3)))
randint_test = torch.randint(3, 12, (2, 3))
print('torch.rand输出:')
print(rand_test)
print('torch.randn输出:')
print(randn_test)
print('torch.normal输出:')
print(normal_test)
print('torch.randint输出:')
print(randint_test)

输出如下:

torch.rand输出:

tensor([[0.2021, 0.9678, 0.2073],
[0.2188, 0.7407, 0.4630]])

torch.randn输出:

tensor([[-0.1639, -0.3759, -0.0406],
[-1.3173, -0.4895, -0.7410]])

torch.normal输出:

tensor([[-0.1632, 0.0034, 0.4261],
[-0.0843, 0.7650, 1.6820]])

torch.randint输出:

tensor([[ 5, 5, 11],
[ 7, 9, 11]])

2. Tensor类型转换

2.1 普通类型转Tensor

对现有普通类型数据进行初始化一般使用的是两个函数,tensor 以及 Tensor

其用法都是一致的,设 c 为普通数据类型,可以为元组、列表、int、float、long、double类型,直接传入即可以进行初始化,如 a = torch.Tensor(c),注意,这两个方法不能初始化 set 类型和字典。

示例如下:

import torch

# int类型测试
i = 3
a = torch.Tensor(i)
b = torch.tensor(i)
print('int类型测试:')
print(a)
print(b)

# 元组类型测试
i = ((1, 2), (3, 5))
a = torch.Tensor(i)
b = torch.tensor(i)
print('tuple类型测试:')
print(a)
print(b)

# 列表类型测试
i = [[1, 2], [3, 5]]
a = torch.Tensor(i)
b = torch.tensor(i)
print('list类型测试:')
print(a)
print(b)

输出如下:

int类型测试:

tensor([0., 0., 0.])
tensor(3)

tuple类型测试:

tensor([[1., 2.],
[3., 5.]])
tensor([[1, 2],
[3, 5]])

list类型测试:

tensor([[1., 2.],
[3., 5.]])
tensor([[1, 2],
[3, 5]])

注意,如果tuple类型的数据每个一个维度只有一个数据,则初始化时会自动进行降维,list类型则不会,测试如下:

# 元组类型,每个维度只有一个数据
i = ((1), (3))
a = torch.Tensor(i)
b = torch.tensor(i)
print('tuple类型测试:')
print(a)
print(b)

# 列表类型。每个维度只有一个数据
i = [[1], [3]]
a = torch.Tensor(i)
b = torch.tensor(i)
print('list类型测试:')
print(a)
print(b)

输出如下:
tuple类型测试:

tensor([1., 3.])
tensor([1, 3])

list类型测试:

tensor([[1.],
[3.]])
tensor([[1],
[3]])

可以看到,元组类型的维度被降了一个维度再初始化,list类型则没有。

2.2 torch.tensor与torch.Tensor比较

  • 初始化int效果不同

    torch.tensor 初始化 int 数据类型时能够将其是多少就转为多少,torch.Tensor 初始化 int 数据类型时会将其转为传入值维度的张量,如传入 3torch.tensor 会将其转为张量3,torch.Tensor 则会将其转为 1 x 3 维度的空张量。测试如下:

    import torch
    
    # int类型测试
    i = 3
    a = torch.Tensor(i)
    b = torch.tensor(i)
    
    print(a)
    print(b)
    

    输出如下:

    tensor([0., 0., 0.])
    tensor(3)

  • 类型不同

    torch.tensor 是一个函数,默认初始化的类型是 torch.int64torch.Tensor 是一个类,默认初始化类型是 torch.float32

  • 对float类型接收不一样

    如果仅传入一个 float 类型的单值如 i=1.2 初始化,那么 torch.Tensor 会报错,而 torch.tensor 则不会。

综上所述,推荐使用 torch.tensor 进行初始化比较好一些。

2.3 Tensor之间类型转换

张量之间的类型转换也经常会用到,下面我来介绍几种常见的转换张量类型的方法。

  1. int() 方式
    如果需要转换张量的类型,可以直接在张量后面加一个 .int() 进行转换,当然,不同的函数有不同的效果, 各函数的转换能够转换的张量类型如下:

    函数 转换为的类型
    int() torch.int32
    float() torch.float32
    long() torch.int64
    double() torch.float64
    short() torch.int16
    half() torch.float16
    char() torch.int8
    byte() torch.uint8

    测试如下:

    import torch
    
    # 初始化
    i = [[3, 2],[2, 3]]
    b = torch.tensor(i)
    # 转换类型
    int_b = b.int()
    long_b = b.long()
    float_b = b.float()
    double_b = b.double()
    
    print(int_b.dtype)
    print(long_b.dtype)
    print(float_b.dtype)
    print(double_b.dtype)
    

    输出结果如下:

    torch.int32
    torch.int64
    torch.float32
    torch.float64

  2. type() 方式
    假如 a 是一个张量,如果需要对其进行类型转化,那么使用 a.type(torch.int64) 的方式即可将张量进行转化。

  3. 初始化方式
    也可以在初始化的时候就对张量的类型进行指定,如下

    import torch
    
    i = [[3, 2],[2, 3]]
    b = torch.tensor(i, dtype=torch.int64)
    
    print(b.dtype)
    

    输出如下:

    torch.int64

  4. type_as() 方式
    使用 ·type_as(tensor)· 函数,该函数能够将张量转为给定的张量的类型,测试如下:

    a = torch.tensor([5, 6], dtype=torch.float32)
    b = torch.tensor([5, 6])
    print('改变前类型')
    print(b.dtype)
    b = b.type_as(a)
    print('改变后类型')
    print(b.dtype)
    

    输出如下:

    改变前类型
    torch.int64
    改变后类型
    torch.float32

2.4 Tensor 与numpy之间转换

目的 函数
Tensor→numpy tensor.numpy(),其中 tensor 为张量类型
numpy→Tensor torch.from_numpy(data)data 为numpy类型的变量

2.5 Tensor转普通类型

目的 函数
Tensor→list tensor.tolist(),其中 tensor 为张量类型
Tensor→单数据类型 tensor.item(),其中 tensor 为张量类型

你可能感兴趣的:(Pytorch,pytorch,深度学习,python)