PyTorch入门笔记-基本数据类型

2021-04-28 10:42:42 浏览数 (1)

本小节主要介绍 PyTorch 中的基本数据类型,先来看看 Python 和 PyTorch 中基本数据类型的对比。

Python 中的基本数据类型在 PyTorch 中几乎都有对应,只不过 PyTorch 的基本数据类型的名称都是以 Tensor 结尾。「Tensor 就是张量,张量是一个数据容器,里面包含的数据通常为数值数据,张量是任意维度的推广。」 我们将标量称为 0D 张量(0维张量),向量称为 1D 张量(1维张量),矩阵称为 2D 张量(2维张量),依次类推。

PyTorch 是一个面向数值计算的高级深度学习框架,因此并没有像 Python 这些编程语言一样内置字符串类型(string),不过使用深度学习处理 NLP(自然语言处理)任务时,输入的样本通常是原始的文本语料,既然 PyTorch 中没有内置字符串类型,并且还需要将这些字符串输入到深度学习模型之中,这就需要使用一些映射方法将字符串类型的文本转换为 PyTorch 能够处理的数值类型,常见的两种文本映射方法为:

  • One - hot 编码:首先将文本分词,对其中唯一的词进行编号构建长度为 n 的词典,使用 0 表示对应编号位置的词没有出现,使用 1 表示对应编号位置的词出现。例如:现在有一个三个词的字典{"cat":0, "fish":1, "dog":2},使用 one-hot 编码以后,"cat" 被表示为 1, 0, 0,"fish" 被表示为 0, 1, 0,"dog" 被表示为 0, 0, 1;
  • Embedding 词嵌入:在实际任务中, 「构造的词典可能会非常庞大,此时使用 one-hot 编码可能会引发维度灾难,并且 one-hot 编码没有考虑词的语义信息以及词与词之间的关系。」 比如"dog"和"cat"很相近,"cat"爱吃"fish",这些关系使用 one-hot 编码都不能表示出来。Embedding 是通过相邻词语义相似的原理将词映射到低维度的词向量空间中,由于使用相邻词语义相似的原理进行训练,因此词向量可以表示语义信息,并且可以使用余弦相似性来计算词与此之间的相似度。常见的 Embedding 词嵌入方法有很多,比如 Word2vec、glove等;

PyTorch 分别为 CPU tensor 和 GPU tensor 定义了 10 种张量基本类型,具体如下所示。

「通过上表可以发现相同的数据在 CPU 上运行和在 GPU 上运行为不同的数据类型。」 比如定义一个 float64 类型的 tensor,如果将这个 tensor 放在 CPU 上运行,这个 tensor 的数据类型为 torch.DoubleTensor。如果将这个 tensor 送到 GPU 中运行,这个 tensor 的数据类型为 torch.cuda.DoubleTensor。

张量的类型推断

我们可以使用三种方式来推断张量的类型:

  • type(tensor):Python 内置函数,因为只能输出数据为 tensor 类型,不能够提供具体的基本类型信息,所以很少使用;
  • tensor.type():PyTorch 内置函数,能够输出 tensor 的具体数据类型;
  • isinstance(tensor, torch.XXXTensor):tensor 类型的合法化检验,可以检查 tensor 的数据类型是否为 torch.XXXTensor;
代码语言:txt复制
import torch

# 创建形状为(2, 3)的二维张量
# 其中生成的元素值服从正太分布
a = torch.randn(2, 3)

>>> print(type(a)) 
<class 'troch.Tensor'>
>>> print(a.type()) 
torch.FloatTensor
>>> print(isinstance(a, torch.FloatTensor))
True

刚刚提到过 tensor 在 CPU 和 GPU 上运行有不同的数据类型,下面就可以使用刚刚介绍的 isinstance 函数来检验一下。

代码语言:txt复制
import torch

a = torch.randn(2, 3)
# 默认在CPU上执行
>>> print(isinstance(a, torch.cuda.DoubleTensor)) 
False

# 将tensor放到GPU上面执行
a_cuda = a.cuda()

>>> print(isinstance(a_cuda, torch.cuda.DoubleTensor)) 
True

不同维度的张量

在深度学习中会经常会遇到不同维度的张量。不过在介绍深度学习中不同维度张量之前,先来看看在 PyTorch 中查看 tensor 形状以及 tensor 维度的属性和函数:

  • 查看 tensor 的形状:
    • tensor.shape:shape 为 tensor 的属性;
    • tensor.size():size 为 tensor 的函数;
  • 查看 tensor 的维度:
    • len(tensor.shape)
    • tensor.dim()

接下来看看在深度学习中一些常见的张量维度。

  • 0D 张量
代码语言:txt复制
import torch

a = torch.tensor(1.)
>>> print(a) 
tensor(1.)
>>> print(a.size()) 
torch.Size([])

b = torch.tensor(1.3)
>>> print(b)
tensor(1.3000)
>>> print(b.dim())
0

0D 张量仅包含一个数字,我们也可以称 0D 张量为标量,PyTorch 提供了一个非常方便的函数能够将 0D 张量转换为 Python 的基本数据类型。

代码语言:txt复制
import torch

a = torch.tensor([1.0])
>>> print(a.type()) 
torch.FloatTensor

b = a.item()

>>> print(type(b)) 
<class 'float'>

深度学习中损失函数的值通常为 0D 张量。

  • 1D 张量
代码语言:txt复制
import torch

a = torch.tensor([1.1])
>>> print(a) 
tensor([1.1000])
>>> print(a.size()) 
torch.Size([1])
>>> print(a.dim()) 
1

b = torch.Tensor(1)
b2 = torch.Tensor(2)

>>> print(b)
tensor([8.8002e-43])
>>> print(b2) 
tensor([-2.9972e 36,  3.0819e-41])

>>> print(b.size()) 
torch.Size([1])
>>> print(b.dim()) 
1

>>> print(b2.size()) 
torch.Size([1])
>>> print(b2.dim()) 
1

这里需要区分 torch.tensor 和 torch.Tensor 两个函数的区别:

  • torch.tensor 接受的只能是数据的内容;
  • torch.Tensor 接受的可以是数据的内容,也可以是数据的形状;

「当接受数据的内容生成新的张量推荐使用 torch.tensor。当为 torch.Tensor 传入数据的形状时会生成指定形状且包含未初始化数据的张量,torch.Tensor 更像是 torch.tensor 和 torch.empty 的混合。还有一点需要注意,当接受数据内容时,torch.tensor 从传入的数据中推断出数据类型,而 torch.Tensor 则会使用默认的全局数据类型。」

1D 张量称为向量,在深度学习中阈值通常为向量的形式,不过在后期计算时阈值的维度会被广播机制进行推广。

  • 2D 张量
代码语言:txt复制
import torch

a = torch.randn(2, 3)
>>> print(a.size()) 
torch.Size([2, 3])
>>> print(a.dim()) 
2

# 可以为size函数传入指定索引来获取对应维度上的元素个数
>>> print(a.size(0))
2
>>> print(a.size(1)) 
3

2D 张量称为矩阵,在深度学习中常用于向量数据。在前面介绍的手写数字识别问题中,我们将 (28 x 28) 的像素矩阵打平成 (784, ) 的向量特征。为了方便矩阵计算以及提高效率,我们使用批梯度下降算法,即每次训练小批量的样本数据,因此我们通常会为 (784, ) 的向量特征添加一个批量维度 batch_size,784 就是 features 特征,即 (batch_size, features)。

  • 3D 张量
代码语言:txt复制
import torch

a = torch.rand(1, 2, 3)

>>> print(a.size()) 
torch.Size([1, 2, 3])
>>> print(a.dim()) 
3

3D 张量通常用于时间序列的数据或者文本序列的数据,比如对于文本序列的数据,通常形状为 (batch_size, timesteps, features):

  • batch_size:处理的文档数;
  • timesteps:处理每篇文档的长度,由于每篇文档长度不一,需要人为指定一个长度阈值,超过长度阈值的文档进行裁剪,少于长度阈值的文档进行填充;
  • features:词的表示,如果使用 one-hot 编码,则 features 为构成词典的大小。如果使用 Embedding 词嵌入,则 features 为设置词嵌入的维度;
  • 4D 张量
代码语言:txt复制
import torch

a = torch.rand(2, 3, 28, 28)

>>> print(a.size())
torch.Size([2, 3, 28, 28])
>>> print(a.dim())
4

4D 张量通常用于图像数据,形状为 (batch_size, height, width, channels) 或 (batch_size, channels, height, width),channel 的位置和具体使用的深度学习框架有关,在 TensorFlow 2.X 中图像形状为 (batch_size, height, width, channels),而在 PyTorch 中图像的形状为 (batch_size, channels, height, width),这点注意即可。

5D 张量通常用于视频数据,形状为 (batch_size, frames, height, width, channels) 或 (batch_size, frames, channels, height, width),channels 通道的位置和在图像中的一致,不同框架中可能表示 channels 通道维度不同,视频和图像数据相比仅仅是增加了 frames 帧数这一个维度。5D 以上的张量在深度学习中并不常见这里不再赘述。

References: 1. 龙良曲深度学习与PyTorch入门实战:https://study.163.com/course/introduction/1208894818.htm

原文地址:https://mp.weixin.qq.com/s/ZsUtUbUC9MO8PWbw23qr5Q

0 人点赞