如何开始使用Keras,深度学习和Python(配源码)
链接: 代码下载.
一、概述内容
1.概述
在此Keras教程中,您将发现深度学习和Python入门非常容易。您将使用Keras深度学习库在自定义图像数据集上训练您的第一个神经网络,然后从那里,您还将实现第一个卷积神经网络(CNN)。
您遇到的大多数Keras都将尝试使用图像分类数据集(例如MNIST(手写识别)或CIFAR-10(基本对象识别))来教您使用该库的基础知识。
这些图像数据集是计算机视觉和深度学习文献中的标准基准,并且可以肯定,它们绝对会让您开始使用Keras…
…但是它们不一定实用,因为它们不会教您如何使用磁盘上的自己的一组映像。相反,您只是调用辅助函数来加载预编译的数据集。
我将在Keras入门案例中采用另一种方式。
我将教您如何使用自定义数据集训练您的第一个神经网络和卷积神经网络,而不是教您如何利用这些预编译的数据集中的一个,因为我们面对现实,您的目标是应用深度学习到您自己的数据集,而不是Keras内置的数据集,对吗?
2.步骤
使用Keras训练您的第一个简单神经网络不需要大量代码,但是我们将逐步开始,逐步进行,以确保您了解如何在自己的自定义数据集上训练网络的过程。 。
我们今天将介绍的步骤包括:
在系统上安装Keras和其他依赖项
从磁盘加载数据
创建训练和测试分组
定义您的Keras模型架构
编译您的Keras模型
根据训练数据训练模型
根据测试数据评估模型
使用训练有素的Keras模型进行预测
我还包括了有关训练您的第一个卷积神经网络的附加部分。
这看起来似乎是很多步骤,但是我向您保证,一旦我们开始使用示例,您将看到示例是线性的,具有直觉的意义,并且将帮助您了解使用Keras训练神经网络的基础知识。
二、使用的数据集
1.收集自己的数据集
您在图像分类中遇到的大多数Keras教程都将使用MNIST或CIFAR-10-我在这里不打算这样做。
首先,MNIST和CIFAR-10并不是非常令人兴奋的示例。
这些教程实际上并未涵盖如何使用您自己的自定义图像数据集。相反,他们只是调用内置的Keras实用程序即可神奇地将MNIST和CIFAR-10数据集作为NumPy数组返回。实际上,您的培训和测试分组已经为您预分配了!
其次,如果您想使用自己的自定义数据集,那么您真的不知道从哪里开始。您会发现自己挠头并问诸如以下的问题:
这些辅助函数从何处加载数据?
磁盘上的数据集应采用哪种格式?
如何将数据集加载到内存中?
我需要执行哪些预处理步骤?
老实说-研究Keras和深度学习的目标不是使用这些预先烘焙的数据集。
相反,我们使用自己的自定义数据集。
我收集了大约3000张动物照片,包含三个种类:
猫
小狗
大熊猫
动物数据集仅包含3,000张图像,是一个入门数据集,我们可以使用我们的CPU或GPU快速训练深度学习模型(并且仍然获得合理的准确性)。
2.如何使用自定义数据集
此外,使用此自定义数据集可以使您了解:
如何在磁盘上组织数据集
如何从磁盘加载图像和类标签
如何将数据划分为训练和测试拆分
如何在训练数据上训练您的第一个Keras神经网络
如何根据测试数据评估模型
如何在训练和测试划分之外的全新数据上重用训练过的模型
三、项目结构及开展
1.项目结构及代码获取
有许多与此项目相关的文件。从“代码下载.”部分中获取压缩文件,然后使用树 命令以显示终端中的项目结构(我提供了两个命令行参数标志 树 使输出清晰美观):
$ tree --dirsfirst --filelimit 10
.
├── animals
│ ├── cats [1000 entries exceeds filelimit, not opening dir]
│ ├── dogs [1000 entries exceeds filelimit, not opening dir]
│ └── panda [1000 entries exceeds filelimit, not opening dir]
├── images
│ ├── cat.jpg
│ ├── dog.jpg
│ └── panda.jpg
├── output
│ ├── simple_nn.model
│ ├── simple_nn_lb.pickle
│ ├── simple_nn_plot.png
│ ├── smallvggnet.model
│ ├── smallvggnet_lb.pickle
│ └── smallvggnet_plot.png
├── pyimagesearch
│ ├── init.py
│ └── smallvggnet.py
├── predict.py
├── train_simple_nn.py
└── train_vgg.py
7 directories, 14 files
如前所述,今天我们将使用动物数据集。注意如何动物 在项目树中进行组织。代替动物(animals)/ ,共有三个类目录: 猫/ , 小狗/ , 熊猫/。在这些目录中的每个目录中,包含与各自类别有关的1,000张图像。
如果您使用自己的数据集,则以相同的方式组织它!理想情况下,您每班至少要收集1,000张图像。这并不总是可能的,但是您至少应该具有班级平衡。一个类文件夹中的大量图像可能会导致模型偏差。
接下来是 图片(images)/ 目录。该目录包含用于测试目的的三个图像,我们将使用它们演示如何
(1)从磁盘加载经过训练的模型,然后
(2)对不属于原始数据集的输入图像进行分类。
这 输出(output)/ 文件夹包含由培训生成的三种文件类型:
model :训练后会生成序列化的Keras模型文件,并且可以在以后的推理脚本中使用。
pickle:序列化的标签二进制文件。该文件包含一个包含类名的对象。它附带一个模型文件。
.png :我总是将训练/验证图图像放在输出文件夹中,因为它是训练过程的输出。
这 pyimagesearch / 目录是一个模块。与我收到的许多问题相反,pyimagesearch 是不是一个点安装的程序包。相反,它位于项目文件夹中,并且其中包含的类可以导入到脚本中。
今天,我们将审阅四个.py文件:
在博客文章的前半部分,我们将训练一个简单的模型。训练脚本是train_simple_nn.py 。
我们将继续培训 smallVGGNet 使用 train_vgg.py 脚本。
这 smallvggnet.py 文件包含我们的 小VGGNet 类,卷积神经网络。
除非我们可以部署序列化模型,否则它有什么好处?在预测,我提供了示例代码供您加载序列化的模型+标签文件并在图像上进行推断。只有在我们成功地以合理的精度训练了模型之后,预测脚本才有用。运行此脚本以测试数据集中未包含的图像比较有效能够验证我们训练模型的精准性。
2.项目环境
本项目需要在ubuntu或macOS系统上配置TensorFlow2.0的环境,该环境自行解决。
3.从磁盘加载数据
4.代码讲解
现在已经在系统上安装了Keras,我们可以开始使用Keras实现第一个简单的神经网络训练脚本。稍后我们将实现功能完善的卷积神经网络,但让我们开始轻松并逐步发展。
打开 train_simple_nn.py 并插入以下代码:
第2-19行导入了我们所需的包。如您所见,此脚本利用了很多工具。让我们回顾一下重要的:
matplotlib:这是Python的必备绘图软件包。就是说,它确实有其细微差别,如果您遇到麻烦,请参阅此博客文章。在第3行,我们指示matplotlib 使用 “阿格” 后端使我们能够将绘图保存到磁盘-这是您的第一个细微差别!
sklearn :scikit-learn库将帮助我们对标签进行二值化处理,拆分数据以进行培训/测试以及在终端中生成培训报告。
tensorflow:您正在阅读本教程以了解Keras —这是我们TensorFlow和其他深度学习后端的高级前端。
imutils:我的便捷功能包。我们将使用路径 模块生成用于训练的图像文件路径列表。
numpy:NumPy用于使用Python进行数值处理。这是另一个必备软件包。如果您安装了适用于Python的OpenCV和scikit-learn,则您将拥有NumPy,因为它是一个依赖项。
cv2:这是OpenCV。在这一点上,即使您可能使用的是OpenCV 3或更高版本,这也是传统,也是坚持2的要求。
执行脚本时,脚本将动态处理通过命令行提供的其他信息。附加信息采用命令行参数的形式。这argparse 模块是内置于Python中的模块,将处理解析您在命令字符串中提供的信息。
我们有四个命令行参数要解析:
- dataset :磁盘上图像数据集的路径。
- modle:我们的模型将序列化并输出到磁盘。此参数包含输出模型文件的路径。
- label-bin:数据集标签被序列化到磁盘上,以便在其他脚本中轻松调用。这是输出标签二进制文件的路径。
- plot:输出训练图图像文件的路径。我们将检查该图以检查数据是否过度/不足。
掌握了数据集信息后,让我们加载图像和类标签:
在这里,我们:
-
初始化我们的清单 数据 和 标签 (第35和36行)。这些将稍后成为NumPy数组。
-
grab imagePaths 并随机洗牌(第39-41行)。这path.list_images 函数方便地找到我们所有输入图像的所有路径 -数据集 目录,然后我们排序和 洗牌 他们。我设置了种子 因此随机重排序是可重现的。
-开始遍历所有对象 imagePaths 在我们的数据集中(第44行)。
对于每个 imagePath ,我们继续: -
加载 图像 进入内存(第48行)。
-
调整大小 图像 至 32x32 像素(忽略宽高比)以及 展平 图像(第49行)。这是至关重要的,以调整大小 我们的图像正确,因为此神经网络需要这些尺寸。每个神经网络都需要不同的维度,因此请注意这一点。展平数据使我们可以轻松地将原始像素强度传递给输入层神经元。稍后您会看到,对于VGGNet,我们将卷传递到网络,因为它是卷积的。请记住,该示例只是一个简单的非卷积网络-我们将在后文中介绍一个更高级的示例。
-将调整大小后的图像附加到 数据 (第50行)。
提取课程 标签 路径中的图像(第54行)并将其添加到标签 清单(第55行)。这标签 list包含与数据列表中的每个图像相对应的类。
现在,我们可以将数组操作应用于数据和标签:
在第58行上,我们将像素强度的缩放范围从[0,255]调整为[0,1](常见的预处理步骤)。
我们还将转换 标签 列出一个NumPy数组(第59行)。
1.构建您的训练和测试单元
现在我们已经从磁盘加载了图像数据,接下来我们需要构建训练和测试拆分:
通常分配一定比例的数据用于培训,而分配较小比例的数据用于测试。scikit-learn提供了一个方便的方法train_test_split 函数将为我们拆分数据。
两个都 trainX 和 testX 弥补图像数据本身 火车 和 测验 组成标签。
我们的班级标签当前以字符串表示;但是,Keras会假定这两个条件:
标签被编码为整数
而且,对这些标签执行一次热编码,使每个标签表示为矢量而不是整数
要完成此编码,我们可以使用 LabelBinarizer 来自scikit-learn的课程:
在第70行,我们初始化LabelBinarizer 目的。
调用 fit_transform 在中找到所有唯一的类标签 train 然后将它们转换为一键编码的标签。
调用调节 transform 上 test 仅执行一次热编码步骤-可能的类标签的唯一集合已由对的调用确定 .fit_transform 。
这是一个例子:
2.定义您的Keras模型架构
下一步是使用Keras定义我们的神经网络架构。在这里,我们将使用一个具有一个输入层,两个隐藏层和一个输出层的网络
由于我们的模型非常简单,因此我们继续在此脚本中对其进行定义(通常,我希望在用于模型体系结构的单独文件中创建单独的类)。
输入层和第一隐藏层在第76行上定义。将有一个input_shape 的 3072 因为有 32x32x3 = 3072 拼合的输入图像中的像素。第一个隐藏层将具有1024 节点。
第二个隐藏层将具有 512 节点(第77行)。
最后,最终输出层(第78行)中的节点数将是可能的类标签的数目-在这种情况下,输出层将具有三个节点,每个节点对应一个我们的类标签(“ cats”,“ dogs” ”和“ panda”)
3.编译您的Keras模型
一旦定义了神经网络架构,下一步就是对其进行“编译”:
首先,我们初始化学习速度和要训练的时期总数(第81和82行)。
然后我们 编译 我们使用随机梯度下降(SGD )优化器 “ categorical_crossentropy” 作为 loss 功能。
分类交叉熵被用作几乎所有训练为执行分类的网络的损失。唯一的例外是2类分类,其中只有两个可能的类标签。在这种情况下,您想换掉“ categorical_crossentropy” 为了 “ binary_crossentropy” 。
4.使您的Keras模型拟合(训练)数据
现在,我们的Keras模型已经编译完毕,我们可以在训练数据上“拟合”(即训练)它:
我们已经讨论了所有输入,除了 batch_size。这batch_size 控制通过网络传递的每组数据的大小。较大的GPU将能够容纳较大的批处理大小。我建议从32 或者 64 然后从那里上来。
5.评估您的Keras模型
我们已经训练了实际模型,但是现在我们需要根据测试数据对其进行评估。
重要的是,我们必须对测试数据进行评估,这样我们才能获得无偏(或尽可能接近无偏)的表示,以表示我们的模型在从未训练过的数据上的性能如何。
要评估我们的Keras模型,我们可以结合使用 。预测 模型的方法以及 分类报告 从scikit-learn:
6.将训练结果绘图直观化
运行此脚本时,您会注意到我们的Keras神经网络将开始训练,一旦训练完成,我们将在测试集上评估该网络:
这个网络很小,并且与一个小的数据集结合使用时,在我的CPU上每个周期仅需要2秒。
在这里您可以看到我们的网络获得了60%的准确性。
由于我们有1/3的机会随机选择给定图像的正确标签,因此我们知道我们的网络实际上已经学会了可用于区分这三个类别的模式。
我们还保存了以下内容的图:
训练损失
验证损失
训练精度
验证准确性
…确保我们可以轻松发现结果中的过度拟合或不足。
查看我们的图,我们可以看到在〜45个时期之后开始出现少量的过度拟合,此时我们的训练和验证损失开始出现分歧,并且出现了明显的差距。
最后,我们可以将模型保存到磁盘,以便以后可以重新使用它而不必重新训练它:
7.使用Keras模型对新数据进行预测
在这一点上我们的模型已经过训练-但是如果我们想在我们的网络已经过训练之后对图像进行预测该怎么办?
那我们该怎么办?
我们如何从磁盘加载模型?
我们如何加载图像,然后对其进行预处理以进行分类?
在 - 的里面 预测 脚本,我将向您展示操作方法,因此请打开它并插入以下代码:
首先,我们将导入所需的包和模块。
您需要显式导入 load_model 从 tensorflow.keras.models 每当您编写脚本以从磁盘加载Keras模型时。OpenCV将用于注释和显示。这泡菜 模块将用于加载我们的标签二值化器。
接下来,让我们分析命令行参数:
- 图像 :输入图片的路径。
- 模型 :我们训练有素的Keras模型路径。
–label-bin :序列化标签二值化器的路径。 - 宽度:CNN的输入形状的宽度。请记住-您不能在此处指定任何内容。您需要指定模型设计的宽度。
- 高度:输入到CNN的图像的高度。指定的高度也必须与网络的输入形状匹配。
- 展平:是否应该使图像变平。默认情况下,我们不会展平图像。如果您需要展平图像,则应传递一个1个 对于这个论点。
接下来,让我们加载图像并根据命令行参数调整其大小:
然后我们将 展平 图像(如果需要):
为标准的全连接网络平整图像非常简单(第33-35行)。
在使用CNN的情况下,我们还添加了批处理尺寸,但没有使图像变平(第39-41行)。后面将介绍一个示例CNN。
从那里,让我们将模型+标签二值化器加载到内存中并进行预测:
我们的模型和标签二值化器通过45和46行加载。
我们可以对输入进行预测 图像 通过打电话 模型预测 (第49行)。
那是什么 Preds 数组是什么样的?
2D数组包含(1)批次中图像的索引(这里只有一个索引,因为只有一个图像传递到NN中进行分类)和(2)对应于每个类标签的百分比,如查询所示我的Python调试器中的变量:
猫:54.6%
狗:45.4%
熊猫:〜0%
换句话说,我们的网络“认为”它看到了“猫”,并确保地狱“知道”它没有看到“熊猫”。
第53行找到最大值的索引(第0个“ cats”索引)。
然后,第54行从标签二值化器中提取“ cats”字符串标签。
容易吧?
现在让我们显示结果:
我们格式化我们的 文本第57行的 字符串。这包括标签 以及预测值的百分比格式。
然后我们将 文本 在 输出 图片(第58和59行)。
最后,我们在屏幕上显示输出图像,并等待用户按下第62行和第63行上的任意键(观看Homer Simpson尝试找到“ any”键)。
我们的预测脚本非常简单。
您可以打开一个终端并尝试在自定义图像上运行我们训练有素的网络
在这里您可以看到,尽管猫的脸部分被一片面包遮盖了,但我们简单的Keras神经网络已将输入图像分类为“猫”,概率为55.87%。
源代码获取链接
链接: 代码下载.