《Deep Learning with Python》中文版我爱编程

《Deep Learning with Python》第二章 2

2018-01-28  本文已影响30人  神机喵算
2.2 神经网络的数据表示

在上面的例子中,数据存储为多维Numpy数组,也称为张量(tensor)。当前流行的机器学习系统都以张量作为基本数据结构。所以Google的TensorFlow也拿张量命名。那张量是什么呢?

张量是数据的容器(container)。这里的数据一般是数值型数据,所以是数字的容器。大家所熟悉的矩阵是二维(2D)张量。张量是广义的矩阵,它的某一维也称为轴(axis)。

只包含一个数字的张量称为标量(或者数量张量,零维张量,0D张量)。在Numpy中,一个float32或者float64位的数值称为数量张量。Numpy张量可用其ndim属性显示轴的序数,数量张量有0个轴(ndim == 0)。张量的轴的序数也称为阶(rank)。下面是Numpy标量:

>>> import numpy as np
        >>> x = np.array(12)
        >>> x
        array(12)
>>> x.ndim 0

数字的数组也称为向量,或者一维张量(1D张量)。一维张量只有一个轴。下面来看一个Numpy向量:

>>> x = np.array([12, 3, 6, 14])
        >>> x
        array([12, 3, 6, 14])
        >>> x.ndim
1

该向量有5项,也称为5维的向量。但是不要混淆5D向量和5D张量!一个5D向量只有一个轴,以及沿该轴有5个维数(元素);然而一个5D张量有5个轴,并且沿每个轴可以有任意个的维数。维度既能表示沿某个轴的项的数量(比如,上面的5D向量),又能表示一个张量中轴的数量(比如,上面的5D张量),时常容易混淆。对于后者,用更准确地技术术语来讲,应该称为5阶张量(张量的阶即是轴的数量),但人们更常用的表示方式是5D张量。

向量的数组称为矩阵,或者二维张量(2D张量)。矩阵有两个轴,也常称为行和列。你可以将数字排成的矩形网格看成矩阵,下面是一个Numpy矩阵:

>>> x = np.array([[5, 78, 2, 34, 0],
                  [6, 79, 3, 35, 1],
                  [7, 80, 4, 36, 2]])
>>> x.ndim
2

沿着第一个轴的项称为行,沿着第二个轴的项称为列。上面的例子中,[5, 78, 2, 34, 0]是矩阵 x 第一行,[5, 6, 7]是第一列。

矩阵的数组称为三维张量(3D张量),你可以将其看成是数字排列成的立方体,下面是一个Numpy三维张量:

>>> 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

同理,将三维张量放进数组可以创建四维张量,其它更高维的张量亦是如此。深度学习中常用的张量是 0D 到 4D。如果处理视频数据,你会用到5D。

下面来几个具体的例子,回看MNIST数据集。首先加载MNIST数据集:

from keras.datasets import moist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

接着,用ndim属性显示张量train_images的轴数量:

>>> print(train_images.ndim)
3

打印形状:

>>> print(train_images.shape)
(60000, 28, 28)

使用dtype属性打印数据类型:

>>> print(train_images.dtype)
uint8

所以train_images是一个8-bit 整数的三维张量。更确切地说,它是一个包含60,000个矩阵的数组,其中每个矩阵是28 x 28 的整数。每个矩阵是一个灰度图,其值为0到255。

下面使用Python Matplotlib库显示三维张量中的第四幅数字图,见图2.2:

#Listing 2.6 Displaying the fourth digit
digit = train_images[4]
import matplotlib.pyplot as pet
plt.imshow(digit, cmap=plt.cm.binary)
plt.show()
image

图2.2 数字图样例

上面的例子中,使用了train_images[i]沿第一个轴选择指定的数字图。选择张量的指定元素称为张量分片(tensor slicing),下面看Numpy数组中的张量切片操作:

选择#10到#100(不包括#100)的数字图,对应的张量形状为(90,28,28):

>>> my_slice = train_images[10:100]
>>> print(my_slice.shape)
(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)

一般,你可以沿着张量每个轴任意选择两个索引之间的元素。例如,选择所有图片的右下角的14 x 14的像素:

my_slice = train_images[:, 14:, 14:]

你也可以用负索引。就像Python list中的负索引一样,它表示相对于当前轴末端的位置。剪切图片中间14 x 14像素,使用如下的方法:

my_slice = train_images[:, 7:-7, 7:-7]

未完待续。。。

Enjoy!

翻译本书系列的初衷是,觉得其中把深度学习讲解的通俗易懂。不光有实例,也包含作者多年实践对深度学习概念、原理的深度理解。最后说不重要的一点,François Chollet是Keras作者。
声明本资料仅供个人学习交流、研究,禁止用于其他目的。如果喜欢,请购买英文原版。


侠天,专注于大数据、机器学习和数学相关的内容,并有个人公众号:bigdata_ny分享相关技术文章。

若发现以上文章有任何不妥,请联系我。

image
上一篇下一篇

猜你喜欢

热点阅读