您的第一个具有迁移学习功能的 Keras 模型

1. 概览

在本实验中,您将学习如何构建 Keras 分类器。我们并不尝试找出神经网络层的完美组合来识别花卉,而是首先使用一种名为迁移学习的技术使强大的预训练模型适应我们的数据集。

本实验包含关于神经网络的必要理论解释,是开发者学习深度学习的一个很好的切入点。

本实验是“TPU 上的 Keras”的第 2 部分系列视频您可以按以下顺序执行这些操作,也可以单独执行这些操作。

ca8cc21f6838eccc.png

学习内容

  • 使用 softmax 层和交叉熵损失构建您自己的 Keras 图像分类器
  • 使用迁移学习而不是构建自己的模型来作弊 😈?。

反馈

如果您发现此 Codelab 中存在错误,请告诉我们。您可以通过 GitHub 问题 [反馈链接] 提供反馈。

2. Google Colaboratory 快速入门

此实验使用 Google 协作工具,无需您进行任何设置。Colaboratory 是一个用于教学的在线笔记本平台。它提供免费的 CPU、GPU 和 TPU 训练。

688858c21e3beff2

您可以打开此示例笔记本并运行几个单元,以熟悉 Colaboratory。

c3df49e90e5a654f.png Welcome to Colab.ipynb

选择 TPU 后端

8832c6208c99687d

在 Colab 菜单中,选择运行时 >更改运行时类型,然后选择 TPU。在此 Codelab 中,您将使用一个支持硬件加速训练的强大 TPU(张量处理单元)。首次执行时会自动连接到运行时,您也可以使用“Connect”按钮。

笔记本执行

76d05caa8b4db6da

通过点击单元格并使用 Shift-ENTER 一次执行一个单元格。您还可以使用 Runtime >运行全部

目录

429f106990037ec4

所有笔记本都有一个目录。您可以使用左侧的黑色箭头将其打开。

隐藏单元格

edc3dba45d26f12a.png

部分单元格将仅显示标题。这是 Colab 特有的笔记本功能。您可以双击它们来查看其中的代码,但通常不是很有趣。通常是支持函数或可视化函数。您仍然需要运行这些单元才能定义其中的函数。

Authentication

cdd4b41413100543.png

如果您使用已获授权的账号进行身份验证,则 Colab 可以访问您不公开的 Google Cloud Storage 存储分区。上面的代码段将触发身份验证过程。

3. [INFO] 神经网络分类器 101

简述

如果你已经知道下一段落中以粗体显示的所有术语,可以接着进行下一个练习。如果您刚开始接触深度学习,欢迎继续阅读。

对于构建为一系列层的模型,Keras 可提供 Sequential API。例如,使用 3 个密集层的图片分类器可以在 Keras 中编写为:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2

密集神经网络

这是最简单的图像分类神经网络。它由“神经元”组成并层层叠放在一起。第一层处理输入数据,并将其输出馈送到其他层。称为“密集”因为每个神经元都与前一层中的所有神经元相连。

c21bae6dade487bc.png

您可以将图片馈送到此类网络中,方法是将其所有像素的 RGB 值展平为长矢量并将其用作输入。这不是图片识别的最佳技术,但我们稍后会对其进行改进。

神经元、激活、RELU

一个“神经元”计算所有输入的加权和,然后添加一个名为“偏差”的值并通过所谓的“激活函数”提供结果。权重和偏差最初是未知的。它们会随机初始化并“学习”通过使用大量已知数据训练神经网络来实现。

644f4213a4ee70e5

最常用的激活函数称为修正线性单元的 RELU。如上图所示,这是一个非常简单的函数。

Softmax 激活

上述网络以 5 神经元层结尾,因为我们将花卉分为 5 类(玫瑰、郁金香、蒲公英、雏菊、向日葵)。中间层的神经元使用经典的 RELU 激活函数进行激活。不过,在最后一层中,我们需要计算 0 到 1 之间的数字,表示这朵花是玫瑰、郁金香等的概率。为此,我们将使用一个名为“softmax”的激活函数。

对向量应用 Softmax 的方法是取每个元素的指数,然后对向量进行归一化,通常使用 L1 范数(绝对值总和),使值加起来为 1,并且可以解释为概率。

ef0d98c0952c262d.png d51252f75894479e.gif

交叉熵损失

现在,我们的神经网络可以根据输入图片生成预测,接下来我们需要衡量预测的好坏,即网络告诉我们的信息与正确答案之间的距离,通常称为“标签”。请记住,数据集中的所有图片都有正确的标签。

任何距离都有效,但对于分类问题而言,所谓的“交叉熵距离”是最有效的。我们将这种情况称为错误或“损失”。函数:

7bdf8753d20617fb.png

梯度下降法

“训练”神经网络实际上意味着使用训练图片和标签来调整权重和偏差,以便最大限度地降低交叉熵损失函数的值。其运作方式如下。

交叉熵是训练图片的权重、偏差、像素及其已知类别的函数。

如果我们计算交叉熵相对于所有权重和所有偏置的偏导数,就会得到一个“梯度”,该梯度针对给定图像、标签以及权重和偏差的现值进行了计算。请记住,我们可以有数百万个权重和偏差,因此计算梯度声就像是大量的工作。幸运的是,Tensorflow 可以为我们做到这一点。渐变的数学属性是它指向“向上”。由于我们想去交叉熵较低的地方,因此会前往相反的方向。我们以梯度的分数更新权重和偏差。然后,我们在训练循环中使用下一批训练图片和标签重复执行相同的操作。我们希望这可以收敛到交叉熵极低的位置,但无法保证此最小值是唯一的。

梯度下降法 2.png

小批量和动量

您可以仅对一张样本图片计算梯度,并立即更新权重和偏差,但对一批 128 张图片(例如 128 张图片)执行此操作将产生一个梯度,该梯度可以更好地表示不同样本图片施加的限制,因此可能会更快地收敛于解决方案。小批次的大小是一个可调整的参数。

这种技术有时称为“随机梯度下降”还有一个更实际的好处:使用批量处理还意味着使用较大的矩阵,这些矩阵通常更易于在 GPU 和 TPU 上进行优化。

不过,收敛可能仍然有点混乱,即使梯度矢量都为零,收敛也可能会停止。这是否意味着我们找到了一个最低值?不一定。梯度分量可以为零的最小值或最大值。对于包含数百万个元素的梯度矢量,如果这些元素全部为零,则每个零对应于一个最小值而没有一个对应于最大点的概率非常小。在具有很多维度的空间中,马鞍点很常见,我们不想就此止步。

52e824fe4716c4a0

插图:马鞍点。梯度为 0,但并非在所有方向上的最小值。(图片出处 维基媒体:Nicoguaro - 自创内容,CC BY 3.0

解决方法是为优化算法增加一些动力,使其不停地驶过马鞍点。

术语库

batchmini-batch:始终对批量训练数据和标签执行训练。这样做有助于算法收敛。“批次”维度通常是数据张量的第一个维度。例如,形状为 [100, 192, 192, 3] 的张量包含 100 张 192x192 像素的图片,每个像素有三个值 (RGB)。

交叉熵损失:分类器中常用的一种特殊损失函数。

密集层:一个神经元层,其中每个神经元都与前一层中的所有神经元连接。

特征:神经网络的输入有时称为“特征”。弄清楚将数据集的哪些部分(或部分组合)馈送到神经网络以获得良好预测结果的过程称为“特征工程”。

labels:“类”的另一种名称在监督式分类问题中,

学习速率:权重和偏差在训练循环的每次迭代中更新时的梯度百分比。

logits:在应用激活函数之前,一层神经元的输出称为“logits”。这个术语来自“逻辑函数”也称为“S 型函数”这曾是最常用的激活函数。"逻辑函数之前的中子输出"已简化为“logits”。

loss:将神经网络输出与正确答案进行比较的误差函数

神经元:计算其输入的加权和,添加偏差并通过激活函数馈送结果。

独热编码:第 3 类(共 5 类)编码为 5 个元素(第三个元素为 1 除外)的向量。

relu:修正的线性单元。一种热门的神经元激活函数。

S 型函数:另一种过去很流行的激活函数,在特殊情况下仍然有用。

softmax:一个作用于向量的特殊激活函数,用于增大最大分量与所有其他分量之间的差值,同时对该向量进行归一化,使其总和为 1,以便将其解释为概率向量。用作分类器中的最后一步。

tensor:“张量”类似于矩阵,但维度数量没有限制。一维张量是一个向量。二维张量就是一个矩阵。然后,您可以得到具有 3 个、4 个、5 个或更多维度的张量。

4. 迁移学习

对于图像分类问题,密集层可能不够用。我们必须了解卷积层以及排列它们的多种方式。

不过,我们也可以走捷径!有经过全面训练的卷积神经网络可供下载。您可以剪掉最后一层(softmax 分类头),并将其替换为自己的层。所有训练的权重和偏差都保持不变,您只需重新训练添加的 softmax 层即可。这项技术称为“迁移学习”,令人惊讶的是,只要用于预训练神经网络的数据集“足够接近”,它就可以发挥作用。属于你的。

动手实践

请打开以下笔记本,执行单元格 (Shift-ENTER),然后按照显示“必须完成的工作”提示操作标签。

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

其他信息

通过迁移学习,您既可以从顶尖研究人员开发的高级卷积神经网络架构中受益,又可以从大型图像数据集预训练中受益。在本例中,我们将从一个使用 ImageNet 训练的网络中迁移学习,后者是一个包含许多植物和户外场景的图像数据库,与花朵非常接近。

b8fc1efd2001f072.png

图解:使用一个已经训练过的复杂卷积神经网络,黑盒子,仅重新训练分类头。这是迁移学习。我们稍后将看到这些复杂的卷积层排列方式。目前是别人的问题。

Keras 中的迁移学习

在 Keras 中,您可以将 tf.keras.applications.* 集合中的预训练模型实例化。以 MobileNet V2 为例,它就是一种非常棒的卷积架构,在大小方面保持合理。选择 include_top=False 后,您可以获得不含最终 softmax 层的预训练模型,以便添加自己的模型:

pretrained_model = tf.keras.applications.MobileNetV2(input_shape=[*IMAGE_SIZE, 3], include_top=False)
pretrained_model.trainable = False

model = tf.keras.Sequential([
    pretrained_model,
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(5, activation='softmax')
])

另请注意 pretrained_model.trainable = False 设置。它会冻结预训练模型的权重和偏差,以便您仅训练 softmax 层。这通常涉及相对较少的权重,并且可以快速完成,而无需非常庞大的数据集。但是,如果您确实有大量数据,那么使用 pretrained_model.trainable = True 可以更好地运行迁移学习。然后,预训练的权重将提供出色的初始值,并且仍然可以通过训练进行调整,以更好地拟合您的问题。

最后,请注意在密集 softmax 层之前插入的 Flatten() 层。密集层可处理数据的扁平矢量,但我们不知道预训练模型会返回什么。这就是我们需要展平的原因。在下一章中,我们将深入探讨卷积架构,并解释卷积层返回的数据格式。

使用这种方法,准确率应该接近 75%。

解决方案

以下是解决方案笔记本。如果您遇到困难,可以使用它。

c3df49e90e5a654f.png Keras Flowers transfer learning (solution).ipynb

所学内容

  • 🤔? 如何在 Keras 中编写分类器
  • 🤓? 配置了 softmax 最后一层和交叉熵损失
  • 😈? 迁移学习
  • 🤔? 训练您的首个模型
  • 🧐? 在训练期间跟踪损失和准确率

请花点时间回想一下这份核对清单。

5. 恭喜!

您现在可以构建 Keras 模型了。请继续完成下一个实验,了解如何组建卷积层。

TPU 使用实例

Cloud AI Platform 上提供 TPU 和 GPU:

最后,欢迎您提供反馈。如果您发现此实验中存在错误,或者您认为需要改进,请告诉我们。您可以通过 GitHub 问题 [反馈链接] 提供反馈。

HR.png

马丁·戈尔纳 ID small.jpg
作者:Martin Görner
Twitter:@martin_gorner

TensorFlow 徽标.jpg
www.tensorflow.org