【干货】TensorFlow实战——图像分类神经网络模型

Learn how to classify images with TensorFlow

使用TensorFlow创建一个简单而强大的图像分类神经网络模型

by Adam Monsen


引言



 

由于深度学习算法和硬件性能的快速发展,研究人员和各大公司在图像识别,语音识别,推荐引擎和机器翻译等领域取得了长足的进步。六年前,在计算机视觉领域首先出现重大突破,这其中以CNN模型在ImageNet数据集上的成功为代表。两年前,Google Brain团队开源TensorFlow,使得我们可以灵巧快速地开发自己的深度学习模型。 目前来看, TensorFlow已经超越许多其他深度学习的工具库。

 

TensorFlow可以赋予你强大的能力,其具有良好的易用性,使你轻松实现各种复杂功能。

 

本文由两部分组成,我将解释如何快速创建用于实际图像识别的卷积神经网络。当然该网络还可以对视频中的逐帧图像进行分析,从而扩展基于时间序列的视频分析。

 

本文提供你最需要的干货,你只需要了解一些命令行和Python的基础知识就行了。 本系列目的在于让你快速动手,并激励你创造属于自己的新项目。限于篇幅,我不会深入探讨TensorFlow的工作原理,但如果你想了解更多,我会提供大量额外的参考资料。本系列中的所有库和工具都是免费的、开源的。

 

它是怎么工作的



 

我们在本教程中的目标是:通过一个命令给出一个新图像属于哪个类别,我们将按照以下步骤操作:

 

 

1.标注(Labeling)是对训练数据进行管理的过程。比如对于花卉,为了根据需要挑选出不同类别的花朵,我们要将雏菊的图像归入“雏菊”类,将玫瑰归入“玫瑰”类等等。当然如果我们不给任何图像贴上“蕨类植物”的标签,分类器将永远不会返回“蕨类植物”。因此这个过程需要每个类型的很多例子,故而是很重要并且耗时的一步。(我们将从已经标记的数据着手,这使我们处理数据的速度更快。)


2.训练(Training)的过程是在我们标注的数据(图像)的基础上,使用某种工具随机抓取其中的一些数据(图像),然后输入到模型中,再使用模型来猜测每种花的类型并且测试猜测的准确性,重复这一过程直到大部分训练数据都被使用。最后一批未使用的图像(测试集)用于检验训练模型的准确性。


3.分类(classification)使用模型分类新图像。例如,输入:IMG207.JPG,输出:雏菊。这是最快,最简单的一步。

 

训练和分类




在本教程中,我们将训练一个图像分类器来识别不同类型的花朵。 深度学习需要大量的训练数据,所以我们需要大量的不同种类的花的图像。值得庆幸的是,已经有人在收集和分类图像方面做得非常出色,所以我们将使用整理好的数据集,采取一个现有的,完全训练的图像分类模型,并重新训练模型的最后一层,来做我们想要的任务。 这种技术被称为迁移学习(transfer learning)。

 

我们正在重新训练的模型叫做Inception v3,这个模型在2015年12月的论文"Rethinking the Inception Architecture for Computer Vision."中首次提出。

模型训练之前我们不知道如何从雏菊分辨出郁金香,训练模型大约花费了20分钟。 这是深度学习的“学习”部分。

 

  • 安装



第一步,机器感知:在您选择的平台上安装Docker。在许多TensorFlow教程中,安装Docker都被认为是最合理的选择。 我也喜欢这种安装TensorFlow的方法,因为它不安装一堆依赖项从而保持主机的清洁。

 

  • TensorFlow向导



安装Docker后,我们准备启动一个TensorFlow容器进行训练和分类。在您的硬盘驱动器上创建一个有2G空闲空间的工作目录。另外再创建一个名为local的子目录,并记下该目录的完整路径。


docker run -v /path/to/local:/notebooks/local --rm -it --name tensorflow 

tensorflow/tensorflow:nightly /bin/bash

 

下面是该命令的详细解释。

-v / path / to / local:/ notebooks / local将刚刚创建的本地目录装载到容器中合适的位置。 如果使用RHEL,Fedora或其他支持SELinux的系统,请附加Z到刚才的位置从而允许容器访问目录。

--rm告诉Docker在完成后删除容器。

-它附加我们的输入和输出,与容器交互。

--name tensorflow给我们的容器命名tensorflow,而不是sneaky_chowderhead或其他我们随机选择的名字。

tensorflow / tensorflow:nightly,从Docker Hub(一个公共图像库)运行tensorflow / tensorflow的nightly图像,而不使用最新的图像(默认情况下,使用最近构建的/可用的图像)。


 我们之所以使用nightly图像而不是最近获得的图像,是因为最近获得的图像包含一个bug导致TensorBoard出问题,其中TensorBoard又是一个数据可视化工具,我们稍后会介绍。


/ bin / bash表示不要运行Bash shell这个默认命令。

 

  • 训练模型



在容器内,运行下面的命令下载和检查训练数据。


curl -O http://download.tensorflow.org/example_images/flower_photos.tgz

echo 'db6b71d5d3afff90302ee17fd1fefc11d57f243f  flower_photos.tgz' | sha1sum -c


如果你没有看到flower_photos.tgz:OK的消息,那么你就没有得到正确的文件。 如果上述curl或sha1sum步骤失败,请手动下载并分解本地目录中的训练数据tarball(SHA-1 checksum: db6b71d5d3afff90302ee17fd1fefc11d57f243f)。

 

现在把训练数据放在原处,然后下载并且检查再训练的脚本。


mv flower_photos.tgz local/

cd local

curl -O https://raw.githubusercontent.com/tensorflow/tensorflow/10cf65b48e1b2f16eaa82

6d2793cb67207a085d0/tensorflow/examples/image_retraining/retrain.py

echo 'a74361beb4f763dc2d0101cfe87b672ceae6e2f5  retrain.py' | sha1sum -c


为了确认retrain.py的内容是否正确。你应该看到:retrain.py: OK. 当看到这个命令时,说明成功了。

最后,该进行模型学习了! 运行再训练脚本。


python retrain.py --image_dir flower_photos --output_graph output_graph.pb 

--output_labels output_labels.txt


如果遇到下面这个错误,请忽略它:


TypeError: not all arguments converted during string formatting Logged from file

tf_logging.py, line 82.


随着retrain.py的进行,训练图像会自动分成训练、测试和验证数据集。

在输出中,我们希望高的“训练准确性”和“验证准确性”,以及低的“交叉熵”。 有关这些术语的详细解释,请参阅How to retrain Inception's final layer for new categories。在最新硬件上的训练需要大约30分钟。

注意你控制台输出的最后一行:


INFO:tensorflow:Final test accuracy = 89.1% (N=340)


这说明我们已经有了一个模型,有近九成的把握猜出给定图像是五种花型中的哪一种。 由于训练过程中数据输入的随机性,您的准确性可能会有所不同。

 

  • 分类:



再加上一个脚本,我们可以将新的花朵图像添加到模型中,并输出它的类别。这是图像分类过程。

将以下内容命名为classify.py并保存在主机的local目录中:

import tensorflow as tf, sys

image_path = sys.argv[1]
graph_path = 'output_graph.pb'
labels_path = 'output_labels.txt'

# Read in the image_data
image_data = tf.gfile.FastGFile(image_path, 'rb').read()

# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line
in tf.gfile.GFile(labels_path)]

# Unpersists graph from file
with tf.gfile.FastGFile(graph_path, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
_ = tf.import_graph_def(graph_def, name='')

# Feed the image_data as input to the graph and get first prediction
with tf.Session() as sess:
softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')
predictions = sess.run(softmax_tensor,
                          {'DecodeJpeg/contents:0': image_data})
# Sort to show labels of first prediction in order of confidence
   top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]
for node_id in top_k:
human_string = label_lines[node_id]
score = predictions[0][node_id]
print('%s (score = %.5f)' % (human_string, score))


为了测试你的图像,把图片保存为test.jpg到你的local目录,并运行python classify.py test.jpg。 输出结果如下所示:

sunflowers (score = 0.78311)
daisy (score = 0.20722)
dandelion (score = 0.00605)
tulips (score = 0.00289)
roses (score = 0.00073)


 模型表明有78.311%把握确定图像中的花是向日葵。 较高的分数表示匹配正确的可能性越大。 注意,这里只能匹配上一个标签多标签分类需要使用其他的方法。

更多详细信息,请查看classify.py的更多解释。

 

分类器脚本中的图像加载代码不能使用了,所以我用了graph_def = tf.GraphDef()代码来加载图像。

 

我们使用少量的代码创造了一个合适的花朵图像分类器,在笔记本电脑上每秒处理大约五个图像。

 

在下周发布的这个系列的第二部分中,我们将使用这些信息来训练一个不同的图像分类器,然后用TensorBoard来查看分类器内的内容。 如果你想尝试TensorBoard,那就需要确保docker运行没有停止。


原文链接:https://opensource.com/article/17/12/tensorflow-image-classification-part-1


-END-

专 · 知

人工智能领域主题知识资料查看获取【专知荟萃】人工智能领域26个主题知识资料全集(入门/进阶/论文/综述/视频/专家等)

同时欢迎各位用户进行专知投稿,详情请点击

诚邀】专知诚挚邀请各位专业者加入AI创作者计划了解使用专知!

请PC登录www.zhuanzhi.ai或者点击阅读原文,注册登录专知,获取更多AI知识资料

请扫一扫如下二维码关注我们的公众号,获取人工智能的专业知识!

请加专知小助手微信(Rancho_Fang),加入专知主题人工智能群交流!

点击“阅读原文”,使用专知

展开全文
Top
微信扫码咨询专知VIP会员