2.3 核心数据结构——Tensor

张量初认识

经过前两小节的铺垫,大家一定对pytorch有了初步认识,本小节就展开讲pytorch的核心数据结构——Tensor(张量)。Tensor 中文被翻译为张量。张量在不同学科中有不同的意义,在深度学习中张量表示的是一个多维数组,它是标量、向量、矩阵的拓展。标量是零维张量,向量是一维张量,矩阵是二维张量,一个RGB图像的数组就是一个三维张量,第一维是图像的高,第二维是图像的宽,第三维是图像的颜色通道。

在pytorch中,有两个张量的相关概念极其容易混淆,分别是torch.Tensor和torch.tensor。其实,通过命名规范,可知道torch.Tensor是Python的一个类, torch.tensor是Python的一个函数。通常我们调用torch.tensor进行创建张量,而不直接调用torch.Tensor类进行创建。为了进一步区分两者,我们来看看它们代码实现。

torch.Tensor:类定义与torch/_tensor.py#L80,它继承torch._C._TensorBase,这里看到_C就知道要接触C++代码了。

1

跳转到torch/C/\_init__.pyi #L839 可以看到:

# Defined in torch/csrc/autograd/python_variable.cpp
class _TensorBase(metaclass=_TensorMeta):
    requires_grad: _bool
    shape: Size

张量的定义和底层C++实现是在python_variable.cpp代码中,感兴趣的朋友可以进一步探究。

torch.tensor:pytorch的一个函数,用于将数据变为张量形式的数据,例如list, tuple, NumPy ndarray, scalar等。

同样,torch.tensor的底层实现也是C++代码,具体实现位于torch_C_VariableFunctions.pyi文件。如2.1节所述,.pyi文件用于Python类型检查,而其底层实现在对应的C++代码中。

后续将不再区分Tensor和tensor,主要用小写tensor表示张量这个数据类型(数据结构)。

张量的作用

tensor之于pytorch等同于ndarray之于numpy,它是pytorch中最核心的数据结构,用于表达各类数据,如输入数据、模型的参数、模型的特征图、模型的输出等。这里边有一个很重要的数据,就是模型的参数。对于模型的参数,我们需要更新它们,而更新操作需要记录梯度,梯度的记录功能正是被张量所实现的(求梯度是autograd实现的)。

张量的历史演变

讲tensor结构之前,还需要介绍一小段历史,那就是Variable与Tensor。在0.4.0版本之前,Tensor需要经过Variable的包装才能实现自动求导。从0.4.0版本开始,torch.Tensor与torch.autograd.Variable合并,torch.Tensor拥有了跟踪历史操作的功能。虽然Variable仍可用,但Variable返回值已经是一个Tensor(原来返回值是Variable),所以今后无需再用Variable包装Tensor。

虽然Variable的概念已经被摒弃,但是了解其数据结构对理解Tensor还是有帮助的。Variable不仅能对Tensor包装,而且能记录生成Tensor的运算(这是自动求导的关键)。在Variable类中包含5个属性:data,grad,grad_fn,is_leaf,requires_grad

1

  • data: 保存的是具体数据,即被包装的Tensor;
  • grad: 对应于data的梯度,形状与data一致;
  • grad_fn: 记录创建该Tensor时用到的Function,该Function在反向传播计算中使用,因此是自动求导的关键;
  • requires_grad: 指示是否计算梯度;
  • is_leaf: 指示节点是否为叶子节点,为叶子结点时,反向传播结束,其梯度仍会保存,非叶子结点的梯度被释放,以节省内存。

从Variable的主要属性中可以发现,除了data外,grad,grad_fn,is_leaf和requires_grad都是为计算梯度服务,所以Variable在torch.autogard包中自然不难理解。

但是我们的数据载体是tensor,每次需要自动求导,都要用Variable包装,这明显太过繁琐,于是PyTorch从0.4.0版将torch.Tensor与torch.autograd.Variable合并。

张量的结构

tensor是一个类,我们先来认识它有哪些属性,再去观察它有哪些方法函数可使用。

Tensor主要有以下八个主要属性,data,dtype,shape,device,grad,grad_fn,is_leaf,requires_grad。

132

  • data:多维数组,最核心的属性,其他属性都是为其服务的;

  • dtype:多维数组的数据类型,tensor数据类型如下,常用到的三种已经用红框标注出来;

  • shape:多维数组的形状;

  • device: tensor所在的设备,cpu或cuda;

  • grad,grad_fn,is_leaf和requires_grad就与Variable一样,都是梯度计算中所用到的。

    张量的属性还有很多,大家可以通过Pycharm的debug功能进行查看

1

更多关于张量的概念背景,请查看官方文档,下一小节,我们进行张量的操作介绍。

Copyright © TingsongYu 2021 all right reserved,powered by Gitbook文件修订时间: 2024年04月26日21:48:10

results matching ""

    No results matching ""