[译] 使用 Python 和 Keras 实现卷积神经网络

你有没有想过?Snapchat 是如何检测人脸的?自动驾驶汽车是怎么知道路在哪里?你猜的没错,他们是使用了卷积神经网络这种专门用于处理计算机视觉的神经网络。在前一篇文章中,咱们研究了它们是怎么工做的。咱们讨论了这些神经网络的层及其功能。基本上,卷积神经网络的附加层会将图像处理成神经网络可以支持的标准格式。这样作的第一步是检测某些特征或属性,这些工做是由卷积层完成的。前端

这一层使用过滤器来检测低层次的特征(好比边缘和曲线)以及更高层次的特征(好比脸和手)。而后卷积神经网络使用附加层消除图像中的线性干扰,这些干扰会致使过度拟合。当线性干扰移除后,附加层会将图像下采样并将数据进行降维。最后,这些信息会被传递到一个神经网络中,在卷积神经网络中它叫全链接层。一样,本文的目标是如何实现这些层,所以关于这些附加层的更多细节以及如何工做和具体用途均可以在前一篇文章中找到。python

在咱们开始解决问题和开始码代码以前,请正确配置好你的环境。与本系列以前的全部文章同样,我会使用 Python 3.6。另外,我使用的是 Anaconda 和 Spyder,可是你也可使用其余的 IDE。而后,最重要的是安装 Tensorflow 和 Keras。安装和使用 Tensorflow 的说明请查看此处,而安装和使用 Keras 的说明请查看此处android

MNIST 数据集

所以,在本文中,咱们将训练咱们的网络来识别图像中的数字。为此,咱们将使用另外一个著名的数据集 —— MNIST 数据集。在前身 NIST 的基础上,这个数据集由一个包含 60,000 个样本的训练集和一个包含 10,000 个手写数字图像的测试集组成。全部数字都已大小归一化并居中了。图像的大小也是固定的,所以预处理图像数据已被最简化了。这也是这个数据集为什么如此流行的缘由。它被认为是卷积神经网络世界中的 “Hello World” 样例。ios

MNIST 数据集样例

此外,使用卷积神经网络,咱们能够获得与人类判断相差无几的结果。目前,这一纪录由 Parallel Computing Center(赫梅尔尼茨基,乌克兰)保持。他们只使用了由 5 个卷积神经网络组成的集合,并将错误率控制在 0.21%。很酷吧?git

导入库和数据

本系列前面的文章同样,咱们首先导入全部必要的库。其中一些是咱们熟悉的,可是其中一些须要进一步讲解。github

正如你所见,咱们将使用 numpy,这是咱们在前面的示例中用于操做多维数组和矩阵的库。另外,也能够看到,咱们会使用一些本系列以前 Keras 库中用过的特性,也会使用一些新特性。好比建立模型和标准层(好比全链接层)会使用到 SequentialDense算法

此外,咱们还会使用一些 Keras 中的新类。Conv2D 是用于建立卷积层的类。MaxPooling2D 则是用于建立池化层的类,而 Flatten 是用于降维的类。咱们也使用 Keras util 中的 to_categorical。该类用于将向量(整形量)转化为二值类别矩阵,即它用于 one-hot 编码。最后,注意咱们将使用 matplotlib 来显示结果。后端

导入必要的库和类以后,咱们须要处理数据。幸运的是,Keras 提供了 MNIST 数据集, 因此咱们不须要下载它。如前所述,全部这些图像都已经进行了部分预处理。这意味着他们有相同的大小和数字位于合适的位置。所以,让咱们导入这个数据集并为咱们的模型准备数据:数组

如你所见,咱们从 Keras 数据集中导入了 MNIST 数据集。而后,咱们将数据加载到训练和测试矩阵中。在此基础上,利用形状属性获得图像的维数,并对输入数据进行重构,从而获得输入图像的一个通道。基本上,咱们只使用这个图像的一个通道,而不是常规的三个通道(RGB)。这样作是为了简化实现的难度。而后对输入矩阵中的数据进行归一化处理。最后,咱们使用 to_categorical 对输出矩阵进行编码。网络

模型建立

如今,数据已经准备好了,咱们能够开始最有趣的环节了 —— 建立模型:

理所固然的,咱们为此须要使用 Sequential,并首先使用 Conv2D 类添加卷积层。正如你所见的,这个类使用的参数不多,因此让咱们一块儿来研究下。第一个参数是定要使用的过滤器个数,即要检测的特征个数。一般来讲咱们从 32 开始随后逐步增大这个数字。这正是咱们在作的,在第一个卷积层中咱们检测 32 个特征,第二层中 64 个,最后的第三层中 128 个。使用的过滤器大小则由下一个参数 —— kernel_size 来定义,咱们已经选择了 3*3 的过滤器。

在激活函数中,咱们使用整流器函数。这样,在每一个卷积层中非线性程度都会天然增长。实现这一点的另外一种方法是使用 keras.layers.advanced_activations 中的 LeakyReLU。它不像标准的整理器函数,不是将全部低于某一固定值的值压缩为零,而是有一个轻微的负斜率。若是你决定使用它,请注意必须使用 Conv2D 中的线性激活。下面就是这种方式的样例:

咱们有点跑题了。讲回到 Conv2D 及其参数。另外一个很是重要的参数是 input_shape。使用这个参数,定义输入图像的维数。如前所述,咱们只使用一个通道,这是为何咱们的 input_shape 最终维度是 1。这是咱们从输入图像中提取的维度。

此外,咱们还在模型中添加了其它层。Dropout 层能帮助咱们防止过度拟合,此后,咱们使用 MasPooling2D 类添加池化层。显然,这一层使用的是 max-pool 算法,池化过滤器的大小则是 2*2。池化层以后是降维层,最后是全链接层。对于最后的全链接层,咱们添加了两层的神经网络,对于这两层,咱们使用了 Dense 类。最后,咱们编译模型,并使用了 Adam 优化器。

若是你不明白其中的一些概念,你能够查看以前的文章,其中解释了卷积层的原理机制。另外,若是你对于一些 Keras 的内容有疑惑,那么这篇文章会帮助到你。

训练

很好,咱们的数据预处理了,咱们的模型也建好了。下面咱们将他们合并到一块儿,并训练咱们的模型。为了使咱们正在使用的可以运转正常。咱们传入输入矩阵并定义 batch_sizeepoch 数。咱们要作的另一件事是定义 validation_split。这个参数用于定义将测试数据的哪一个部分用做验证数据。

基本上,该模型将保留部分训练数据,但它使用这部分数据在每一个循环结束时计算损失和其余模型矩阵。这与测试数据不一样,由于咱们在每一个循环结束后都会使用它。

在咱们的模型已经训练完成并准备好以后,咱们使用 evaluate 方法并将测试集传入。这里咱们可以得出这个卷积神经网络的准确率。

预测

咱们能够作的另外一件事是在测试数据集中收集对对神经网络的预测。这样,咱们就能够将预测结果和实际结果进行比较。为此,咱们将使用 predict 方法。使用这个方法咱们还能够对单个输入进行预测。

结果

让咱们使用这些咱们刚刚收集到的预测来完成咱们实现的最后一步。咱们将显示预测的数字与实际的数字。咱们还会显示咱们预测的图像。基本上,咱们将为咱们的实现作很好的可视化展现。毕竟,咱们在处理图像。

在这里,咱们使用了 pyplot 来显示十幅图像,并给出了实际结果和咱们的预测。当咱们运行咱们的实现时,以下图所示:

咱们运行了 20 轮并获得了 99.39% 的准确率。并不差,固然这还有提高空间。

结论

卷积神经网络是计算机视觉领域中一个很是有趣的分支,也是最有影响力的创新之一。本文中咱们实现了这些神经网络中的一个简易版本并用它来检测 MNIST 数据集上的数字。

感谢阅读!


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索