11.3 案例实战:基于TensorFlow Hub的迁移学习开发
在2018年的TensorFlow开发峰会上,一个最大的焦点就是TensorFlow Hub的正式发布。它是一个可重用TensorFlow模型库,其中收纳了很多被训练良好的语言模型与图像识别模型,其目的就是允许使用者基于这些基础模型进行迁移学习开发。
本节解析TensorFlow Hub官网上的花卉识别项目,指导读者完成迁移学习的实战开发。在实践之前,通过pip3命令安装TensorFlow Hub:
# pip3 install tensorflow-hub
11.3.1 下载并训练
如图11-5所示,迁移学习开发的前提是具备:
◎ 训练样本。
◎ 原模型。
在基于TensorFlow Hub的迁移学习开发中,前者需要开发者自己准备(或者从TensorFlow网站下载示例样本),后者可以通过TensorFlow Hub所提供的API从GitHub上下载。从官网下载本项目训练样本的方法如下。
# curl -LO http://download.tensorflow.org/example_images/flower_photos. tgz
# tar -zxvf flower_photos.tgz
然后下载示例迁移学习训练程序并运行:
# curl -LO https://github.com/tensorflow/hub/raw/r0.1/examples/image_ retraining/retrain.py
# python3 retrain.py --image_dir ./flower_photos
该程序首先自动从官网下载一个inception_v3花卉识别已训练好的模型,然后利用该模型在flower_photos上进行迁移学习训练。其中flower_photos中的样本不包括在训练原始inception_v3模型的样本中。
11.3.2 检验学习成果
在训练结束后,新模型保存在/tmp/output_graph.pb文件中。可以下载官方GitHub上的另外一个程序,检验新模型对花卉的识别能力。比如:
# curl -LO https://github.com/tensorflow/tensorflow/raw/master/ tensorflow/examples/label_image/ label_image.py
# python3 label_image.py --graph=/tmp/output_graph.pb --labels=/tmp/ output_labels.txt --input_layer=Placeholder --output_layer=final_result --image=./flower_photos/roses/12240303_80d87f77a3_n.jpg
其中image参数指定的是要识别图像文件的名称。这里传入的仍然是下载的flower_photos样本集中的文件,该样本集的内容如图11-6所示。
对于图11-6中所示图片给出的预测结果为:
roses 0.9862179
tulips 0.013723418
sunflowers 3.7595066e-05
daisy 1.3961036e-05
dandelion 7.034586e-06
即模型认为超过98%的可能是:该图片为玫瑰。显然效果非常不错。
11.3.3 迁移学习开发
本案例的模型分类程序label_image.py与第9章内容相比没有新知识点,留给读者自己分析。接下来讲解retrain.py中用于迁移学习的关键代码:
(1)通过hub.load_module_spec()可以下载TensorFlow Hub上的已训练模型,比如:
import tensorflow_hub as hub
module_spec = hub.load_module_spec(FLAGS.tfhub_module)
graph, bottleneck_tensor, resized_image_tensor, wants_quantization = (
create_module_graph(module_spec))
其中tfhub_module是形如'https://tfhub.dev/google/imagenet/inception_v3/feature_vector /1'的模型地址。create_module_graph() 函数从下载的模型中提取出图模型、bottleneck层等变量。
思考:还记得bottleneck层是指什么吗?
(2)用得到的bottleneck_tensor执行图结构,可以得到图11-5中bottleneck层产生的“新样本”:
resized_input_values = sess.run(decoded_image_tensor, # 转换图像大小
{image_data_tensor: image_data})
bottleneck_values = sess.run(bottleneck_tensor, # 读取bottleneck样本
{resized_input_tensor: resized_input_values})
(3)新建一个分类层,接续在bottleneck层之后:
with graph.as_default(): # 使用原模型图结构
(train_step, cross_entropy, bottleneck_input,
ground_truth_input, final_tensor) = add_final_retrain_ops(# 追加一层
class_count, FLAGS.final_tensor_name, bottleneck_tensor,
wants_quantization, is_training=True)
这样,新模型的最终输出张量是final_tensor。
(4)用bottleneck样本训练新模型:
train_accuracy, cross_entropy_value = sess.run(
[evaluation_step, cross_entropy],
feed_dict={bottleneck_input: train_bottlenecks, # bottleneck样本
ground_truth_input: train_ground_truth}) # 样本标签
代码文件retrain.py中的代码有逾千行,不再详细列举。读者在阅读时只需要抓住这里列出的关键点,就可以很容易地掌握迁移学习的开发技巧。
![]()
11.4 本章内容回顾
谷歌在Android上发布了很多已训练的图像/文本深度学习模型,非常便于集成;苹果在iOS 11及其后续版本中也制作了很多已训练模型。
CoreML Tool可以将用TensorFlow、scikit-learn训练的模型转换为在iOS上可以直接使用的模型。
迁移学习是一种基于已训练模型、通过较少样本即可训练出泛化能力较强新模型的机器学习方式。
迁移学习模型的训练方式为,先通过已有模型生成bottleneck样本,然后用bottleneck样本训练新模型。
在TensorFlow Hub上发布了很多用于迁移学习的基础模型,可查询官方网站获取最新模型信息。