如何使用来自 Google AutoML 视觉分类的 TensorFlow Frozen GraphDef (single saved_model.pb) 进行推理和迁移学习

Posted

技术标签:

【中文标题】如何使用来自 Google AutoML 视觉分类的 TensorFlow Frozen GraphDef (single saved_model.pb) 进行推理和迁移学习【英文标题】:How to do Inference and Transfer Learning with TensorFlow Frozen GraphDef (single saved_model.pb) from Google AutoML Vision Classification 【发布时间】:2020-03-03 05:22:34 【问题描述】:

我正在使用从 Google AutoML Vision 导出的分类模型,因此我只有一个 saved_model.pb 并且没有变量、检查点等。 我想将此模型图加载到本地 TensorFlow 安装中,将其用于推理并继续使用更多图片进行训练。

主要问题:

此计划是否可行,即使用没有变量、检查点等的单个 saved_model.pb 并使用新数据训练结果图?

如果是:如何使用编码为字符串的图像获得(?,) 的输入形状?

理想情况下,展望未来:培训部分需要考虑哪些重要事项?


关于代码的背景信息:

为了读取图像,我使用与使用 Docker 容器进行推理时相同的方法,因此使用 base64 编码图像。

为了加载图表,我通过 CLI (saved_model_cli show --dir input/model) 检查了图表所需的标签集,即serve

要获取输入张量名称,我使用 graph.get_operations(),它为 image_bytes 提供 Placeholder:0,为 key 提供 Placeholder:1_0(只是任意字符串标识图像)。两者都有维度dim -1

import tensorflow as tf
import numpy as np
import base64

path_img = "input/testimage.jpg"
path_mdl = "input/model"

# input to network expected to be base64 encoded image
with io.open(path_img, 'rb') as image_file:
    encoded_image = base64.b64encode(image_file.read()).decode('utf-8')

# reshaping to (1,) as the expecte dimension is (?,)
feed_dict_option1 = 
    "Placeholder:0":  np.array(str(encoded_image)).reshape(1,) , 
    "Placeholder_1:0" : "image_key"


# reshaping to (1,1) as the expecte dimension is (?,)
feed_dict_option2 = 
    "Placeholder:0": np.array(str(encoded_image)).reshape(1,1), 
    "Placeholder_1:0" : "image_key"


with tf.Session(graph=tf.Graph()) as sess:
    tf.saved_model.loader.load(sess, ["serve"], path_mdl)

    graph = tf.get_default_graph()

    sess.run('scores:0',
               feed_dict=feed_dict_option1)

    sess.run('scores:0',
               feed_dict=feed_dict_option2)



输出:

# for input reshaped to (1,)
ValueError: Cannot feed value of shape (1,) for Tensor 'Placeholder:0', which has shape '(?,)'

# for input reshaped to (1,1)
ValueError: Cannot feed value of shape (1, 1) for Tensor 'Placeholder:0', which has shape '(?,)'

如何获得(?,) 的输入形状?

非常感谢。

【问题讨论】:

【参考方案1】:

是的!有可能,我有一个应该类似的对象检测模型,我可以在 tensorflow 1.14.0 中运行如下:

import cv2
cv2.imread(filepath)
flag, bts = cv.imencode('.jpg', img)
inp = [bts[:,0].tobytes()]
out = sess.run([sess.graph.get_tensor_by_name('num_detections:0'),
                sess.graph.get_tensor_by_name('detection_scores:0'),
                sess.graph.get_tensor_by_name('detection_boxes:0'),
                sess.graph.get_tensor_by_name('detection_classes:0')],
               feed_dict='encoded_image_string_tensor:0': inp)

我使用 netron 来查找我的输入。

在 tensorflow 2.0 中更简单:

import cv2
cv2.imread(filepath)
flag, bts = cv.imencode('.jpg', img)
inp = [bts[:,0].tobytes()]
saved_model_dir = '.'
loaded = tf.saved_model.load(export_dir=saved_model_dir)
infer = loaded.signatures["serving_default"]
out = infer(key=tf.constant('something_unique'), image_bytes=tf.constant(inp))

另外saved_model.pb 不是frozen_inference_graph.pb,参见:What is difference frozen_inference_graph.pb and saved_model.pb?

【讨论】:

感谢您简洁的回答!您帮我在我的代码中找到了两个问题:首先,网络不需要 numpy-Array (np.array) 中的输入图像,而是常规 python 列表 ([...]) 中的输入图像。其次,通过base64.b64encode 编码不起作用,但是通过带有cv2.imreadcv2.imencode 的opencv-python 就可以了。也感谢关于保存模型与冻结图的说明!

以上是关于如何使用来自 Google AutoML 视觉分类的 TensorFlow Frozen GraphDef (single saved_model.pb) 进行推理和迁移学习的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Web GUI 停止 Google Cloud AutoML(现为 Vertex AI)批量预测作业?

(GCP) AutoML 视觉图像预测——模型的预测功能究竟如何?

Google Vertex AI AutoML - 无法为 CSV 数据集指定架构

如何使用 Google 的 AutoML 进行 OCR

多次训练同一个 Google AutoML 模型

如何杀死正在运行的 google AUTOML 训练作业