张量

张量这一概念的核心在于,它是一个数据容器。它包含的数据几乎总是数值数据,因此它是数字的容器。

你可能对矩阵很熟悉, 它是二维张量。 张量是矩阵向任意维度的推广[注意, 张量的维度(dimension)通常叫作轴(axis)]。

张量的维度

  1. 包含一个数字的张量叫作标量(scalar,也叫标量张量、零维张量、0D 张量)。
    张量有 0 个轴( ndim == 0 )。张量轴的个数也叫作阶(rank)。下面是一个 Numpy 标量。
>>> import numpy as np
>>> x = np.array(12)
>>> x array(12)
>>> x.ndim 
0
  1. 向量(1D 张量)
    数字组成的数组叫作向量(vector)或一维张量(1D 张量)。一维张量只有一个轴。
>>> x = np.array([12, 3, 6, 14, 7])
>>> x array([12, 3, 6, 14, 7])
>>> x.ndim 
1
  1. 矩阵(2D 张量)
    向量组成的数组叫作矩阵(matrix)或二维张量(2D 张量)。矩阵有 2 个轴(通常叫作行和列)
    第一个轴上的元素叫作行(row),第二个轴上的元素叫作列(column)
>>> x = np.array([[5, 78, 2, 34, 0],
                  [6, 79, 3, 35, 1], 
                  [7, 80, 4, 36, 2]])
>>> x.ndim 
2
  1. 3D 张量与更高维张量
    将多个矩阵组合成一个新的数组,可以得到一个 3D 张量,你可以将其直观地理解为数字 组成的立方体。
>>> x = np.array([[[5, 78, 2, 34, 0], 
                   [6, 79, 3, 35, 1], 
                   [7, 80, 4, 36, 2]], 
                  [[5, 78, 2, 34, 0], 
                   [6, 79, 3, 35, 1], 
                   [7, 80, 4, 36, 2]], 
                  [[5, 78, 2, 34, 0],
                   [6, 79, 3, 35, 1], 
                   [7, 80, 4, 36, 2]]])
>>> x.ndim 
3

将多个 3D 张量组合成一个数组,可以创建一个 4D 张量,以此类推。深度学习处理的一般 是 0D 到 4D 的张量,但处理视频数据时可能会遇到 5D 张量。

关键属性

  • 轴的个数(阶)。 例如,3D 张量有 3 个轴, 矩阵有 2 个轴。 这在 Numpy 等 Python 库中也叫张量的 ndim 。 �

  • 形状。 这是一个整数元组, 表示张量沿每个轴的维度大小(元素个数)。 例如, 前面矩阵示例的形状为 (3, 5) ,3D 张量示例的形状为 (3, 3, 5) 。向量的形状只包含一个元素,比如 (5,) ,而标量的形状为空,即 () 。

  • 数据类型(在 Python 库中通常叫作 dtype )。这是张量中所包含数据的类型,例如,张量的类型可以是 float32 、 uint8 、 float64 等。在极少数情况下,你可能会遇到字符 ( char )张量。

张量的切片同python数组的切片一样。

数据批量的概念

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

>>> my_slice = train_images[10:100]
>>> print(my_slice.shape) (90, 28, 28)

上面的例子表示 :在MNIST数据集中,将 10~100 个数字(不包括第 100 个), 并将其放在形状为 (90, 28, 28) 的数组中。

>>> my_slice = train_images[10:100, :, :]
>>> my_slice.shape (90, 28, 28)
>>> my_slice = train_images[10:100, 0:28, 0:28]
>>> my_slice.shape (90, 28, 28)

这些代码效果都是等同的。

此外,深度学习模型不会同时处理整个数据集,而是将数据拆分成小批量
比如下面的每个批量 大小是128.

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

对于这种批量张量,第一个轴(0 轴)叫作批量轴(batch axis)批量维度(batch dimension)

现实世界中的数据张量

向量数据: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) 。

举例:

  • 时间序列组成的3D张量


    根据惯例,时间轴始终是第 2 个轴(索引为 1 的轴)

  • 图像数据组成的4D张量


    图像张量的形状有两种约定:通道在后(channels-last)的约定(在 TensorFlow 中使用)和通道在前(channels-first)的约定(在 Theano 中使用)。
    Google 的 TensorFlow 机器学习框架将颜色深度轴放在最后: (samples, height, width, color_depth) 。 与此相反,Theano 将图像深度轴放在批量轴之后: (samples, color_depth, height, width) 。

  • 视频数据组成的5D张量
    视频数据是现实生活中需要用到 5D 张量的少数数据类型之一。 视频可以看作一系列帧, 每一帧都是一张彩色图像。由于每一帧都可以保存在一个形状为 (height, width, color_ depth) 的 3D 张量中, 因此一系列帧可以保存在一个形状为 (frames, height, width, color_depth) 的 4D 张量中,而不同视频组成的批量则可以保存在一个 5D 张量中,其形状为 (samples, frames, height, width, color_depth) 。

张量变形

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

>>> x = np.array([[0., 1.], 
                  [2., 3.], 
                  [4., 5.]])
>>> print(x.shape) (3, 2)
>>> x = x.reshape((6, 1))
>>> x 
array([[ 0.], 
       [ 1.], 
       [ 2.], 
       [ 3.], 
       [ 4.], 
       [ 5.]])
>>> x = x.reshape((2, 3))
>>> x 
array([[ 0., 1., 2.], 
       [ 3., 4., 5.]])

经常遇到的一种特殊的张量变形是转置(transposition)。对矩阵做转置是指将行和列互换, 使 x[i, :] 变为 x[:, i] 。

>>> x = np.zeros((300, 20))
>>> x = np.transpose(x)
>>> print(x.shape) 
(20, 300)

推荐阅读更多精彩内容