首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

基于TensorFlow和Keras的图像识别

使用CNN进行图像识别

到目前为止,本文已讲述很多内容,如果这些概念理解起来较为困难,那么结合在数据集上训练样本分类器的实例可能会更加清晰。因此,下面将介绍一个使用Keras进行图像识别的完整示例,从加载数据到评估。

首先,我们需要一个数据集来训练。本示例中,将采用著名的CIFAR-10数据集。CIFAR-10是一个大型图像数据集,包含超过60,000个图像,代表10种不同类别的对象,如猫、飞机和汽车。

CIFAR-10数据集中的图像是全彩RGB的,但它们的尺寸较小,只有32×32。它的一个优势在于它预先包装了Keras,因此数据集很容易被加载并且图像无需过多的预处理。

接下来需要导入必要的库,我们将使用Numpy以及与Keras相关的各种模块,后续将依次展示如何使用它们:

这里将使用随机种子,以便复制本文中的结果,这就是本文需要导入numpy的原因:

准备数据

我们还需要导入数据集。

加载数据集时,可以指定数据载入的变量,然后使用load_data()函数来实现:

多数情况下,在使用数据集之前,需要对其进行预处理。但是由于文中使用了预先打包的数据集,因此无需过多的预处理,我们要做的就是输入数据的规范化。

如果输入数据的值的范围过大,会对网络的性能产生负面影响。这种情况下,输入值是图像中的像素,其范围在0到255之间。

因此,为了规范化数据,可以简单地将图像值除以255。为此,首先需要将数据由整型转换为浮点类型。此过程可以通过Numpy中的astype()函数实现,然后声明所需的数据类型:

数据准备的另一项工作就是对值进行独热编码。这里对其细节将不予详细的讨论,但是既然了解数据集不能直接用于网络训练,而是需要经过编码处理,那么在二分类之前独热编码是最好的选择。

这里的二分类非常有效,因为图像要么属于某个类,要么不属于它,不会介于二者之间。Numpy中的to_categorical()函数用于独热编码,需要从Keras中导入np_utils。

此外,还需指定数据集中类的数目,这样可以知道最后一层压缩到多少个神经元:

设计模型

下面进入CNN模型设计阶段。首先要定义模型格式,Keras提供几种不同的格式来构建模型,其中Sequential是最常用的,因此需要从Keras导入。

创建模型

模型的第一层是卷积层,它将接收输入的图像并对它们执行卷积滤波。

在Keras中进行实现时,需要指定通道/滤波器的数目(即下面的32),滤波器大小(此情况下为3×3),张量的形状(当创建第一层时),激活函数以及填充。

如上所述,relu是最常见的激活函数,padding='same'表示不会改变图像大小。

注意:还可以将激活函数和池化写在一起,如下所示:

接下来需要实现一个dropout层来防止过度拟合,它通过随机消除层之间的一些连接来发挥作用(0.2表示它会丢弃20%的现有连接):

这里可能还需要批量标准化,它将输入标准化到下一层,保证网络始终创建与所需相同分布的激活函数:

下面是另一个卷积层,但是由于滤波器尺寸增加,网络可以学习更复杂的表示:

下面是池化层,如上所述,有助于使图像分类器更加健壮,因此它可以学习相关模式。还有dropout和批量标准化:

如上是实现CNN前半部分的基本流程:卷积,激活,dropout以及池化。这就是需要导入Dropout,BatchNormalization,Activation,Conv2d以及MaxPooling2d的原因。

可以根据个人需要改变卷积层数目,但每多一层都会增加计算量。请注意,在增加卷积层时,通常也会增加滤波器的数量,以便模型可以学习更复杂的表示。如果层数的选择上看起来有些随意,只需知道通常情况下,继续增加滤波器并建议将值设置为2的乘方,这将有助于GPU上的训练。

重要的是不要有太多的池化层,因为每个池化层都会丢失一些数据。太频繁的池化将导致稠密层在数据到达时几乎没有任何可以学习的信息了。

池化层数目的取值与正在执行的任务有关。由于文中的图像太小,这里将不会对其池化超过两次。

现在可以重复这些层,使网络可以学习更多的表示:

在完成卷积层的处理之后,需要Flatten数据,这就是导入上述函数的原因。同时还需要再次添加一层dropout:

在使用Dense创建第一个稠密层时,需要指定神经元的数目。注意,后继层的神经元数目减少,最终和数据集中类的数目相同(在本示例中为10)。核约束可以在学习时对数据进行规范化,这有助于过度拟合。这就是导入maxnorm的原因。

在最后一层,传入类的数目作为神经元的数目。每个神经元代表一个类,该层的输出将是一个包含10个神经元的向量,每个神经元存储了所讨论图像属于它所代表的类的概率。

最后,激活函数softmax选择概率最高的神经元作为输出,表明图像属于该类:

既然已经设计了想要使用的模型,我们只需编译它。下面要指定训练的epoch数目以及要使用的优化器。

优化器将调整网络中的权重以接近最低损失点。其中,Adam算法是最常用的优化器之一,因为它在多数问题上表现了出色的性能:

接下来用选择的参数编译模型,并且指定所使用的指标。

如下可输出模型摘要。

通过摘要可以了解更多信息:

现在开始训练模型,可以通过调用fit()函数并传递设置的相关参数进行实现。

为了再现的目的,这里使用了种子。

我们将对50000个样本进行训练,并对10000个样本进行验证。

运行如下代码将产生:

请注意,多数情况下,测试集应与验证集不同,因此需要指定作为验证集的训练数据的百分比。在此情况下,只需传入测试数据以确定测试数据未被训练过。出于简便,本示例中仅用测试数据。

现在可以评估模型,只需调用model.evaluate():

将获取如下结果:

至此,一个用于图像识别的CNN已经训练完成。对于第一次运行而言,结果还算不错,不过您可以通过调整模型结构和参数来尝试达到更优的性能。

结论

既然已经在Keras中实现了图像识别网络,那么最好反复研究模型并观察参数的调整对其性能的影响。

这将使您拥有关于不同模型参数的最佳选择的直觉。在执行此操作时,您还应当了解不同的参数和超参数选项。熟悉这些后,您可以尝试在不同的数据集上实现自己的图像分类器。

如果您想进一步学习此项目,请移步GitHub!

英文原文:https://stackabuse.com/image-recognition-in-python-with-tensorflow-and-keras/

译者:我是昵称耶~

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190624A053QT00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券