神经网络的数据表示——张量

一、N阶张量

一般来说,当前所有机器学习系统都使用张量作为基本数据结构。张量这一概念的核心在于,它是一个数据容器。它包含的数据几乎总是数值数据,因此它是数字的容器。张量是矩阵向任意维度的推广[注意,张量的维度(dimension)通常叫作轴(axis)]。

标量(0D 张量)

仅包含一个数字的张量叫作标量(scalar,也叫标量张量、零维张量、0D 张量)。在Numpy中,一个float32 或float64 的数字就是一个标量张量(或标量数组)。你可以用ndim 属性来查看一个Numpy 张量的轴的个数。标量张量有0 个轴(ndim == 0)。张量轴的个数也叫作阶(rank)。

向量(1D 张量)
数字组成的数组叫作向量(vector)或一维张量(1D 张量)。一维张量只有一个轴。下面是一个Numpy 向量。

x = np.array([12, 3, 6, 14, 7])

这个向量有5 个元素,所以被称为5D 向量。 5D 向量只有一个轴,沿着轴有5 个维度。5D 张量有5 个轴(沿着每个轴可能有任意个维度)。

矩阵(2D 张量)

向量组成的数组叫作矩阵(matrix)或二维张量(2D 张量)。矩阵有2 个轴(通常叫作行和列)。

3D 张量与更高维张量

将多个矩阵组合成一个新的数组,可以得到一个3D 张量,你可以将其直观地理解为数字组成的立方体。将多个3D 张量组合成一个数组,可以创建一个4D 张量,以此类推。深度学习处理的一般是0D 到4D 的张量,但处理视频数据时可能会遇到5D 张量。

二、张量的关键属性

  • 轴的个数(阶):例如,3D 张量有 3 个轴,矩阵有 2 个轴。这在 Numpy 等 Python 库中也叫张量的ndim。
  • 形状:这是一个整数元组,表示张量沿每个轴的维度大小(元素个数)。例如,前面矩阵示例的形状为(3, 5),3D 张量示例的形状为(3, 3, 5)。向量的形状只包含一个元素,比如(5,),而标量的形状为空,即()。
  • 数据类型:(在 Python 库中通常叫作 dtype)。这是张量中所包含数据的类型,例如,张量的类型可以是float32、uint8、float64 等。在极少数情况下,你可能会遇到字符(char)张量。注意,Numpy(以及大多数其他库)中不存在字符串张量,因为张量存储在预先分配的连续内存段中,而字符串的长度是可变的,无法用这种方式存储。

三、数据批量的概念

通常来说,深度学习中所有数据张量的第一个轴(0 轴,因为索引从0 开始)都是样本轴(samples axis,有时也叫样本维度)。在MNIST 的例子中,样本就是数字图像。

此外,深度学习模型不会同时处理整个数据集,而是将数据拆分成小批量。具体来看,下面是MNIST 数据集的一个批量,批量大小为128。

batch = train_images[:128]

然后是下一个批量。

batch = train_images[128:256]

然后是第n 个批量。

batch = train_images[128 * n:128 * (n + 1)]

对于这种批量张量,第一个轴(0 轴)叫作批量轴(batch axis)或批量维度(batch dimension)。在使用Keras 和其他深度学习库时,你会经常遇到这个术语。

四、现实世界中的数据张量

需要处理的数据几乎总是以下类别之一。

  • 向量数据:2D 张量,形状为 (samples, features)。
  • 时间序列数据或序列数据:3D 张量,形状为 (samples, timesteps, features)。
  • 图像:4D张量,形状为(samples, height, width, channels)或(samples, channels,height, width)。
  • 视频:5D张量,形状为(samples, frames, height, width, channels)或(samples,frames, channels, height, width)。

向量数据

这是最常见的数据。对于这种数据集,每个数据点都被编码为一个向量,因此一个数据批量就被编码为2D 张量(即向量组成的数组),其中第一个轴是样本轴,第二个轴是特征轴。

时间序列数据或序列数据

当时间(或序列顺序)对于数据很重要时,应该将数据存储在带有时间轴的3D 张量中。每个样本可以被编码为一个向量序列(即2D 张量),因此一个数据批量就被编码为一个3D 张量。根据惯例,时间轴始终是第2 个轴(索引为1 的轴)。

图像数据

图像通常具有三个维度:高度、宽度和颜色深度。虽然灰度图像(比如MNIST 数字图像)只有一个颜色通道,因此可以保存在2D 张量中,但按照惯例,图像张量始终都是3D 张量,灰度图像的彩色通道只有一维。因此,如果图像大小为256×256,那么128 张灰度图像组成的批量可以保存在一个形状为(128, 256, 256, 1) 的张量中,而128 张彩色图像组成的批量则可以保存在一个形状为(128, 256, 256, 3) 的张量中。

图像张量的形状有两种约定:通道在后(channels-last)的约定(在TensorFlow 中使用)和通道在前(channels-first)的约定(在Theano 中使用)。Google 的TensorFlow 机器学习框架将颜色深度轴放在最后:(samples, height, width, color_depth)。与此相反,Theano将图像深度轴放在批量轴之后:(samples, color_depth, height, width)。如果采用Theano 约定,前面的两个例子将变成(128, 1, 256, 256) 和(128, 3, 256, 256)。Keras 框架同时支持这两种格式。

视频数据

视频数据是现实生活中需要用到5D 张量的少数数据类型之一。视频可以看作一系列帧,每一帧都是一张彩色图像。由于每一帧都可以保存在一个形状为(height, width, color_depth) 的3D 张量中,因此一系列帧可以保存在一个形状为(frames, height, width,color_depth) 的4D 张量中,而不同视频组成的批量则可以保存在一个5D 张量中,其形状为(samples, frames, height, width, color_depth)。举个例子,一个以每秒4 帧采样的60 秒YouTube 视频片段,视频尺寸为144×256,这个视频共有240 帧。4 个这样的视频片段组成的批量将保存在形状为(4, 240, 144, 256, 3)的张量中。总共有106 168 320 个值!如果张量的数据类型(dtype)是float32,每个值都是32 位,那么这个张量共有405MB。好大!你在现实生活中遇到的视频要小得多,因为它们不以float32 格式存储,而且通常被大大压缩,比如MPEG 格式。

五、张量运算

深度神经网络学到的所有变换都可以简化为数值数据张量上的一些张量运算(tensor operation),例如加上张量、乘以张量等。

在最开始的例子中,我们通过叠加Dense 层来构建网络。Keras 层的实例如下所示。

keras.layers.Dense(512, activation='relu')

这个层可以理解为一个函数,输入一个2D 张量,返回另一个2D 张量,即输入张量的新表示。具体而言,这个函数如下所示(其中W 是一个2D 张量,b 是一个向量,二者都是该层的属性)。

output = relu(dot(W, input) + b)

我们将上式拆开来看。这里有三个张量运算:输入张量和张量W 之间的点积运算(dot)、得到的2D 张量与向量b 之间的加法运算(+)、最后的relu 运算。relu(x) 是max(x, 0)。

六、张量的几种重要运算

(1)逐元素运算

relu 运算和加法(张量的shape相同)都是逐元素(element-wise)的运算,即该运算独立地应用于张量中的每个元素,也就是说,这些运算非常适合大规模并行实现(向量化实现,这一术语来自于1970—1990 年间向量处理器超级计算机架构)。如果你想对逐元素运算编写简单的Python 实现,那么可以用for 循环。

(2)广播

如果将两个形状不同的张量相加,会发生什么?如果没有歧义的话,较小的张量会被广播(broadcast),以匹配较大张量的形状。广播包含以下两步。

  • 向较小的张量添加轴(叫作广播轴),使其ndim 与较大的张量相同。
  • 将较小的张量沿着新轴重复,使其形状与较大的张量相同。

(3)张量点积

点积运算,也叫张量积(tensor product,不要与逐元素的乘积弄混),是最常见也最有用的张量运算。与逐元素的运算不同,它将输入张量的元素合并在一起。在Numpy、Keras、Theano 和TensorFlow 中,都是用* 实现逐元素乘积。TensorFlow 中的点积使用了不同的语法,但在Numpy 和Keras 中,都是用标准的dot 运算符来实现点积。

(4)张量变形

张量变形是指改变张量的行和列,以得到想要的形状。变形后的张量的元素总个数与初始张量相同。

发布了195 篇原创文章 · 获赞 59 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_36622009/article/details/105645940