深度学习算法和硬件性能的最新进展,使研究人员和公司能够在图像识别、语音识别、推荐引擎和机器翻译等领域取得巨大进步。六年前,首次实现了视觉模式识别方面超越人类的表现。两年前,Google Brain 团队发布了 TensorFlow,巧妙地将应用的深度学习推广到大众。TensorFlow 正在超越许多用于深度学习的复杂工具。
借助 TensorFlow,您将获得具有强大功能的复杂特性。其强大功能的核心是 TensorFlow 的易用性。
在一个分为两部分的系列文章中,我将解释如何快速创建一个用于实际图像识别的 卷积神经网络。计算步骤是极易并行的,可以部署用于逐帧视频分析,并扩展用于时序感知视频分析。
本系列文章直接切入最引人入胜的内容。只需对命令行和 Python 有基本的了解,您就可以在家中一起参与。其目的是让您快速入门,并激励您创建自己的精彩项目。我不会深入探讨 TensorFlow 的工作原理,但如果您渴望了解更多,我将提供大量的补充参考资料。本系列中的所有库和工具都是自由/开源软件。
工作原理
本教程的目标是获取一张属于我们训练过的类别的全新图像,并通过命令运行它,告诉我们图像属于哪个类别。我们将遵循以下步骤

opensource.com
- 标记是整理训练数据的过程。对于花卉,雏菊的图像被拖入“daisies”文件夹,玫瑰的图像被拖入“roses”文件夹,依此类推,可以标记任意多种不同的花卉。如果我们从不标记蕨类植物,分类器将永远不会返回“蕨类植物”。这需要每种类型的大量示例,因此这是一个重要且耗时的过程。(我们将使用预先标记的数据开始,这将使其速度快得多。)
- 训练是将标记数据(图像)馈送到模型的过程。工具将抓取随机批次的图像,使用模型猜测每张图像中花卉的类型,测试猜测的准确性,并重复此过程,直到大部分训练数据被使用。最后一批未使用的图像用于计算训练模型的准确率。
- 分类是在新图像上使用模型。例如,输入:
IMG207.JPG
,输出:daisies
。这是最快、最简单的步骤,并且易于扩展。
训练和分类
在本教程中,我们将训练一个图像分类器来识别不同类型的花卉。深度学习需要大量的训练数据,因此我们需要大量的已分类花卉图像。值得庆幸的是,另一位好心人出色地完成了收集和分类图像的工作,因此我们将使用这个已分类的数据集和一个巧妙的脚本,该脚本将采用现有的、经过充分训练的图像分类模型,并重新训练模型的最后一层,以实现我们想要的功能。这种技术称为迁移学习。
我们正在重新训练的模型称为 Inception v3,最初在 2015 年 12 月的论文“重新思考计算机视觉的 Inception 架构”中指定。
在我们进行此训练之前,Inception 不知道如何区分郁金香和雏菊,这需要大约 20 分钟。这是深度学习的“学习”部分。
安装
迈向机器感知的第一步:在您选择的平台上安装 Docker。
第一个也是唯一的依赖项是 Docker。这在许多 TensorFlow 教程中都是如此(这应该表明这是一个合理的入门方式)。我也更喜欢这种安装 TensorFlow 的方法,因为它通过不安装一堆依赖项来保持您的主机(笔记本电脑或台式机)清洁。
引导 TensorFlow
安装 Docker 后,我们准备启动一个 TensorFlow 容器进行训练和分类。在硬盘驱动器上的某个位置创建一个工作目录,其中有 2 GB 的可用空间。创建一个名为 local
的子目录,并记下该目录的完整路径。
docker run -v /path/to/local:/notebooks/local --rm -it --name tensorflow
tensorflow/tensorflow:nightly /bin/bash
以下是该命令的分解。
-v /path/to/local:/notebooks/local
将您刚刚创建的local
目录挂载到容器中的一个方便位置。如果使用 RHEL、Fedora 或其他启用 SELinux 的系统,请在末尾附加:Z
,以允许容器访问该目录。--rm
告诉 Docker 在我们完成时删除容器。-it
将我们的输入和输出附加到一起,使容器具有交互性。--name tensorflow
给我们的容器命名为tensorflow
,而不是sneaky_chowderhead
或 Docker 可能为我们选择的任何随机名称。tensorflow/tensorflow:nightly
表示运行 Docker Hub(一个公共镜像仓库)中tensorflow/tensorflow
的nightly
镜像,而不是 latest(默认情况下,是最新构建/可用的镜像)。我们使用 nightly 而不是 latest 是因为(在撰写本文时)latest 包含一个错误,该错误会破坏 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
步骤失败,请手动下载并在主机上的 local
目录中解压 训练数据 tarball (SHA-1 校验和:db6b71d5d3afff90302ee17fd1fefc11d57f243f
)。
现在将训练数据放入到位,然后下载并进行健全性检查重新训练脚本。
mv flower_photos.tgz local/
cd local
curl -O https://raw.githubusercontent.com/tensorflow/tensorflow/10cf65b48e1b2f16eaa826d2793cb67207a085d0/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
的进行,训练图像会自动分成批次的 训练、测试和验证数据集。
在输出中,我们希望看到高的“训练准确率”和“验证准确率”以及低的“交叉熵”。有关这些术语的详细解释,请参阅 如何为新类别重新训练 Inception 的最后一层。预计在现代硬件上,训练需要大约 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 run
未终止,以保持此容器运行。
15 条评论