好书快翻--《Python深度学习第二版》第二章 神经网络的数学构建模块

博主有话说:首先感谢您阅读这篇博客!博主做大数据技术,平时喜欢阅读英文原版大数据技术书籍,并翻译成中文,分享出来。如要及时看到翻译的章节,请关注博主微信公众号 登峰大数据,微信号  bigdata_work 

好书快翻--《Python深度学习第二版》第二章 神经网络的数学构建模块

 

本章包括:

  • 神经网络的第一个例子

  • 张量和张量运算

  • 神经网络如何通过反向传播和梯度下降学习

理解深度学习需要熟悉许多简单的数学概念:张量、张量运算、微分、梯度下降等等。我们在这一章的目标是建立你对这些概念的直觉,而不是变得过于专业。特别地,我们将远离数学符号,它可能会让那些没有任何数学背景的人感到不快,并且没有必要很好地解释事情。对数学运算最精确、最明确的描述是它的可执行代码。

为了增加一些关于张量和梯度下降的内容,我们将以一个神经网络的实际例子开始本章。然后我们会逐点复习每一个引入的新概念。请记住,这些概念对后续章节的学习是必要的。

读完这一章后,你将对深度学习背后的数学理论有一个直观的理解,你将准备好在第三章开始深入学习Keras和TensorFlow。

2.1神经网络的第一个例子

让我们来看一个具体的神经网络示例,使用Python库Keras来学习如何对手写数字进行分类。除非您已经有使用Keras或类似库的经验,否则无法立即理解第一个示例的所有内容。你可能还没有安装Keras;这很好。在下一章中,我们将回顾示例中的每个元素并详细解释它们。因此,如果某些步骤在您看来很随意或很神奇,请不要担心!我们总得找个地方开始。

我们试图解决的问题是对灰度图像进行分类的手写数字(28×28个像素)到10个分类(0到9)。我们将使用MNIST数据集,一个经典的机器学习社区,它几乎和这个领域本身一样久远,并且已经被深入研究。它是一组60000张训练图像,加上10000张测试图像,由国家标准与技术研究所(NIST在MNIST中的缩写)在20世纪80年代组装而成。你可以把“解决”MNIST想象成深度学习的“Hello World”——你要做的就是验证你的算法是否如预期的那样工作。当您成为一个机器学习实践者时,您将看到MNIST一次又一次地出现在科学论文、博客帖子等中。您可以在图2.1中看到一些MNIST示例。

类和标签上的注意事项

在机器学习中,分类问题中的“类别”称为“类”。数据点称为样本。与特定示例关联的类称为标签label

好书快翻--《Python深度学习第二版》第二章 神经网络的数学构建模块

您现在不需要尝试在您的机器上重现这个示例。如果您愿意,您首先需要建立一个深度学习workspace,这将在第3章中介绍。

MNIST数据集在Keras中以一组四个NumPy数组的形式预加载。

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

“train_images”和“train_tags”构成训练集,即模型将从中学习的数据。然后将在测试集' test_images '和' test_tags '上测试模型。图像被编码为NumPy数组,标签是数字数组,范围从0到9。图像和标签是一一对应的。

让我们看看训练数据:

>>> train_images.shape
(60000, 28, 28)
>>> len(train_labels)
60000
>>> train_labels
array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)

下面是测试数据:

>>> test_images.shape
(10000, 28, 28)
>>> len(test_labels)
10000
>>> test_labels
array([7, 2, 1, ..., 4, 5, 6], dtype=uint8)

工作流程如下:首先,将训练数据‘train_images’和‘train_label’输入神经网络。然后,网络将学会将图像和标签联系起来。最后,我们将要求网络生成' test_images '的预测,并验证这些预测是否与' test_tags '中的标签匹配。

让我们构建这个网络—再次提醒您,您还不需要了解关于这个示例的所有内容。

from tensorflow.keras import models
from tensorflow.keras import layers
model = models.Sequential([
  layers.Dense(512, activation='relu'),
  layers.Dense(10, activation='softmax')
])

神经网络的核心构件是层(layer),它是一个数据处理模块,您可以将其视为数据的过滤器。一些数据输入,然后以更有用的形式输出。具体来说,层从提供给它们的数据中提取“表示”(representations)——希望这些表示对手头的问题更有意义。大多数深度学习都是将简单的层链接在一起,实现一种渐进的“数据蒸馏”形式。深度学习模型就像一个数据处理的筛子,由一系列越来越精细的数据过滤器——层组成。

 

这里,我们的模型由两个“Dense”层的序列组成,这两个“Dense”层紧密连接(也称为fully connected)神经层。第二层(也是最后一层)是一个10路的softmax分类层,这意味着它将返回一个10个概率分数的数组(总和为1),每个分数将是当前数字图像属于我们的10个分类之一的概率。

为了让模型为训练做好准备,我们需要选择另外三件事,作为编译步骤的一部分:

  • 一个优化器 -该机制,通过该模型将根据它看到的训练数据更新自己,从而提高其性能。

  • 损失函数 -模型如何能够测量其在训练数据上的表现,从而如何能够将自己导向正确的方向。

  • 在训练和测试期间要监控的指标 -在这里,我们只关心准确性(被正确分类的图像的比例)。

损失函数和优化器的确切用途将在接下来的两章中详细说明。

model.compile(optimizer='rmsprop',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

在训练之前,我们将对数据进行预处理,方法是将其重新塑形为模型期望的形状,并对其进行缩放,使所有值都在“[0,1]”区间内。例如,以前我们的训练图像存储在一个shape '(60000, 28, 28) '的数组中,类型为' uint8 ',值的间隔为'[0,255]'。我们将它转换为一个形状'(60000,28 * 28)'的' float32 '数组,其值在0到1之间。

train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255

我们现在准备训练模型,在Keras中是通过调用模型的“fit”方法来完成的——我们“fit”模型到它的训练数据:

>>> model.fit(train_images, train_labels, epochs=5, batch_size=128)
Epoch 1/5
60000/60000 [==============================] - 5s - loss: 0.2524 - acc: 0.9273
Epoch 2/5
51328/60000 [========================>.....] - ETA: 1s - loss: 0.1035 - acc: 0.9692

训练过程中会显示两个量:训练数据上模型的损失和训练数据上模型的准确性。训练数据的准确率达0.989(98.9%)。

现在我们有了一个训练过的模型,你可以用它来预测类概率为新的分类数---图像不属于训练数据的一部分,而是来自测试集:

>>> test_digits = test_images[0:10]
>>> predictions = model.predict(test_digits)
>>> predictions[0]
array([1.0726176e-10, 1.6918376e-10, 6.1314843e-08, 8.4106023e-06,
       2.9967067e-11, 3.0331331e-09, 8.3651971e-14, 9.9999106e-01,
       2.6657624e-08, 3.8127661e-07], dtype=float32)

数组中每个索引“i”的数目对应于数字图像“test_digits[0]”属于类“i”的概率。

第一个测试数字在索引7处有最高的概率分数(0.99999106,几乎是1),所以根据我们的模型,它大概率是7:

>>> predictions[0].argmax()
7
>>> predictions[0][7]
0.99999106

我们可以检查测试标签是否一致:

>>> test_labels[0]
7

平均而言,我们的模型在分类这些从未见过的数字方面有多好?让我们通过计算整个测试集的平均精度来检查一下。

>>> test_loss, test_acc = model.evaluate(test_images, test_labels)
>>> print('test_acc:', test_acc)
test_acc: 0.9785

测试集的准确率为97.8%,比训练集的准确率(98.9%)要低很多。训练准确性和测试准确性之间的这种差距就是“过度拟合”的一个例子:机器学习模型在新数据上的表现往往比在训练数据上的表现更差。过拟合是第三章的中心主题。

这是我们的第一个例子——您刚刚看到了如何使用少于15行Python代码构建和训练一个神经网络来对手写数字进行分类。在这一章和下一章,我们将详细介绍每一个我们刚刚预览过的代码片段,并阐明幕后发生了什么。您将了解张量,即进入模型的数据存储对象;张量运算,由哪些层组成;梯度下降法,它允许你的模型从它的训练数据中学习。

2.2神经网络的数据表示