張量這一概念的核心在于,它是一個數據容器。它包含的數據幾乎總是數值數據,因此它是數字的容器。
你可能對矩陣很熟悉, 它是二維張量。 張量是矩陣向任意維度的推廣[注意, 張量的維度(dimension)通常叫作軸(axis)]。
張量的維度
- 包含一個數字的張量叫作標量(scalar,也叫標量張量、零維張量、0D 張量)。
張量有 0 個軸( ndim == 0 )。張量軸的個數也叫作階(rank)。下面是一個 Numpy 標量。
>>> import numpy as np
>>> x = np.array(12)
>>> x array(12)
>>> x.ndim
0
- 向量(1D 張量)
數字組成的數組叫作向量(vector)或一維張量(1D 張量)。一維張量只有一個軸。
>>> x = np.array([12, 3, 6, 14, 7])
>>> x array([12, 3, 6, 14, 7])
>>> x.ndim
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
- 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)