TensorFlow图像分类教程

221 阅读8分钟
原文链接: click.aliyun.com

深度学习算法与计算机硬件性能的发展,使研究人员和 企业 在图像识别、语音识别、推荐引擎和机器翻译等领域取得了巨大的进步。六年前,视觉模式识别领域取得了第一个超凡的 成果 。两年前,Google 大脑团队 开发了TensorFlow ,并将深度学习巧妙的应用于各个领域。现在, TensorFlow 则超越了很多用于深度学习的复杂工具。

利用TensorFlow ,你可以获得 具有强大能力的 复杂功能,其强大的基石来自于TensorFlow 的易用性。

在这个由两部分组成的系列中,我将讲述如何快速的创建一个应用于图像识别的卷积神经网络。TensorFlow 计算步骤是并行的,可对其配置进行逐帧视频分析,也可对其扩展进行时间感知视频分析。

本系列文章直接切入 关键的部分 ,只需要对命令行和Python 有最基本的了解,就可以 在家 快速 地 创建一 些令你激动不已 的项目。本文不会深入探讨TensorFlow 的工作原理,如果你想了解更多,我会提供大量额外的参考资料。本系列所有的库和工具都是免费开源的软件。

工作原理

本教程旨在 把一个事先被放到 训练 过的 类别 里的图片, 通过 运行 一个命令 以识别 该图像 具体 属于哪个类别。 步骤如下图所示:

b0017b83ed5115961d94afe7450be2b89fea9b60 

• 标 注 :管理训练数据。 例如 花卉,将雏菊的图像放到“ 雏菊 ” 目录 下 ,将玫瑰放到“ 玫瑰 ” 目录 下 等等,将 尽可能多的不同种类的花朵按照类别不同 放在不同的目录下。如果我们 不标注“ 蕨类植物 ” ,那么分类器永远也不会返回 “ 蕨类植物 ” 。这需要每个类型的很多样本,因此 这一步很 重要 ,并且很耗时 。(本文使用预先标记好的数据以提高效率)

• 训练:将标记好的数据(图像)提供给模型。 有一个 工具 将 随机抓取一批图像,使用模型猜测每种花的类型,测试 猜测的 准确 性, 重复执行,直到 使用了 大部分训练数据 为止 。最后一批未被使用的图像用于计算 该 训练模型的准确性。

• 分类:在新的图像上使用模型。例如,输入:IMG207.JPG ,输出:雏菊。 这个步骤快速简单,且衡量的代价小 。

训练和分类

本教程将训练一个用于识别不同类型花朵 的 图像分类器。深度学习需要大量的训练数据,因此,我们需要大量已分类的花朵图像。值得庆幸的是,另外一个模型在图像收集和分类这方面做得非常出色,所以我们使用这个 带有脚本的已分类 数据集 ,它 有现成且完全训练过的图像分类模型 , 重新训练模型 的 最后几层 以达到我们想要的结果 ,这种技术称为迁移学习。

我们 重新 训练的模型是 Inception v3 ,最初是在 2015 年 12 月发表的论文 “ 重新思考计算机视觉 Inception架构 ” 中有做 论述。

直到我们做了这个约20 分钟的训练 ,Inception 才 知道如何识别雏菊和郁金香,这就是深度学习中的“ 学习 ” 部分。

安装

首先,在所选的平台上 安装Docker

在很多TensorFlow 教程中 最先且唯一依赖的 就是Docker (应该表明这是个合理的开始) 。 我也更喜欢这种安装TensorFlow 的方法,因为不需要安装一系列的 依赖 项, 这 可以保持主机(笔记本或桌面) 比较 干净 。

Bootstrap TensorFlow

安装Docker 后,我们准备启动一个 训 练和分类 的TensorFlow 容器 。在硬盘上创建一个2GB 空闲空间的 工作目录,创建一个名为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  图像,而不是最新的图像(默认为最近建立/可用图像)。使用nightly 图像而不是latest 图像, 是 因为(在写入时)latest 包含的一个 bug 会 破坏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” 信息 : 说明 文件不正确 。如果上诉curl 或 sha1sum 步骤 失败,请手动下载训练数据包并解压(SHA-1 校验码: db6b71d5d3afff90302ee17fd1fefc11d57f243f ) 到 本地 主机的local 目录下 。

现在把训练数据放好, 然后对再 训练 脚本进行下载和 完整性 检查。

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 的运行,训练图像会自动的分批次训练、测试和验证数据集。

在输出 上 ,我们希望有较高的“ 训练 精度” 和 “ 验证 精度” ,以及较低的 “ 交叉熵 ” 。有关这些术语的详细解释,请参照“ 如何 就新图片类型再训练Inception 的 最后一层 ” 。在 当前的 硬件上的训练约30 分钟。

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

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

这说明我们已经得到了一个模型 : 给定一 张 图像,10 次 中 有9 次 可 正确猜出是五种花朵 类型 中的哪一种。由于 提供给 训练过程的随机数不同,分类的 精确度 也会有所不同。

分类

再添加一个小脚本,就可以将新的花朵图像添加到模型中,并输出测试结果。这就是图像分类。

将下述脚本命名为 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))

为了测试你自己的图像,保存在local 目录下并命名为 test.jpg ,运行(在容器内) 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() 等 作为 图表加载代码。

利用 零基础知识 和 一些 代码,我们 建 了一个 相当好的 花卉图像分类器, 在 现有的笔记本电脑上每秒大约 可以 处理5 张 图像。

    希望你能够继续关注本博客的系列博文 。


以上为译文。

本文由北邮@爱可可-爱生活 老师推荐,阿里云云栖社区组织翻译。

文章原标题《 Learn how to classify images with TensorFlow,译者:Mags,审校:袁虎。

文章为简译,更为详细的内容,请查看原文