简体   繁体   English

将 tf1.x saved_model.pb 重新保存到新的 tf2.0 saved_model.pb

[英]resave tf1.x saved_model.pb into new tf2.0 saved_model.pb

I have an old trained tf1.x model (let it be Model1 ), constructed with Placeholders, tf.contrib and so on.我有一个旧的训练有素的 tf1.x 模型(让它成为Model1 ),用占位符、tf.contrib 等构建。 I can use this model by restoring graph from .ckpt checkpoint in tf.Session (in tf1.x).我可以通过从 tf.Session(在 tf1.x 中)中的 .ckpt 检查点恢复图形来使用这个模型。 I resolved the easiest way to use the Model1 is to export it:我解决了使用Model1的最简单方法是导出它:

# tf1.x code
tf.saved_model.simple_save(sess, saved_Model1_path,
    inputs={'input':'Placeholder:0'}, outputs={'output':'.../Sigmoid:0'})

I can use the obtained saved_model.pb even in tf2.0:即使在 tf2.0 中,我也可以使用获得的 saved_model.pb:

# tf2.0 code
Model1 = tf.saved_model.load(saved_Model1_path)
out = Model1.signatures['serving_default'](tf.convert_to_tensor(data))['output'].numpy()
out = Model1.signatures['serving_default'].prune('Placeholder:0', '.../Sigmoid:0')(data)
out = Model1.prune('Placeholder:0', '.../Sigmoid:0')(data)

Now imagine, I have a pre/post processing written with tf2.0 tf.function.现在想象一下,我有一个用 tf2.0 tf.function 编写的前/后处理。

I wish the construction of preprocessing -> Model1-> postprocessing to be exported in a single saved_model.pb in tf2.0.我希望预处理-> Model1-> 后处理的构建在tf2.0 中的单个saved_model.pb 中导出。 And here come the problems due to saved_model.pb of Model1 utilizes tf.Placeholders (smth like this, I'm not an expert here).由于Model1 的saved_model.pb 使用了 tf.Placeholders(像这样,我不是这里的专家),这里出现了问题。

At the same time, I can easily build saved_model.pb from other tf2.0 exported model:同时,我可以轻松地从其他 tf2.0 导出模型构建 saved_model.pb:

import os
import tensorflow as tf
assert tf.__version__[0] == '2'

class M1(tf.Module):
    def __init__(self):
        super(M1, self).__init__()
        self.v = tf.Variable(2.)
    @tf.function(input_signature=[tf.TensorSpec([], tf.float32)])
    def M1_func(self, x):
        return x * self.v

# build some saved_model.pb
m1 = M1()
path_1 = './save1'
path_to_save = os.path.realpath(path_1)
tf.saved_model.save(m1, path_to_save)

# load built saved_model.pb and check it works
m1 = tf.saved_model.load(path_1)
assert 6 == m1.M1_func(3.).numpy()

# build other saved_model.pb using first saved_model.pb as a part of computing graph
class M2(tf.Module):
    def __init__(self):
        super(M2, self).__init__()
        self.run = m1
        self.v = tf.Variable(3.)
    @tf.function(input_signature=[tf.TensorSpec([], tf.float32)])
    def M2_func(self, x):
        return self.run.M1_func(x) * self.v
m2 = M2()
path_2 = './save2'
path_to_save = os.path.realpath(path_2)
tf.saved_model.save(m2, path_to_save)

m2 = tf.saved_model.load(path_2)
assert 18 == m2.M2_func(3.).numpy()

But when I'm trying to do the same, except replacing first saved_model.pb from tf2.0 saving on tf1.x saving, It doesn't work:但是当我尝试做同样的事情时,除了在 tf1.x 保存时从 tf2.0 中替换第一个 saved_model.pb,它不起作用:

# save first saved_model.pb with tf1.x
import tensorflow as tf
assert tf.__version__[0] == '1'
inp = tf.placeholder(shape=[],dtype=tf.float32)
a = tf.Variable(1.5)
out = a*inp
sess = tf.Session()
sess.run(tf.global_variables_initializer())
assert 7.5 == out.eval({inp:5.}, sess)
path_3 = './save3'
path_to_save = os.path.realpath(path_3)
tf.saved_model.simple_save(sess, path_to_save, inputs={'input': inp}, outputs={'output': out})

Now switch to tf2.0 and try to build new saved_model.pb with first one as a part of a computing graph:现在切换到 tf2.0 并尝试使用第一个作为计算图的一部分构建新的 saved_model.pb:

import os
import tensorflow as tf
assert tf.__version__[0] == '2'

path_3 = './save3'
path_to_save = os.path.realpath(path_3)
m1 = tf.saved_model.load(path_to_save)

class M2(tf.Module):
    def __init__(self):
        super(M2, self).__init__()
        self.run = m1.signatures['serving_default'].prune('Placeholder:0', 'mul:0')
        self.v = tf.Variable(3.)

    @tf.function(input_signature=[tf.TensorSpec([], tf.float32)])
    def M2_func(self, x):
        return self.run(x) * self.v

m2 = M2()
assert 22.5 == m2.M2_func(5.) # ofc eager execution works

# now save M2 to saved_model.pb and check it works (it does not)
path_4 = './save4'
path_to_save = os.path.realpath(path_4)
tf.saved_model.save(m2, path_to_save)
m2 = tf.saved_model.load(path_4)
m2.M2_func(5.)  # error:
tensorflow.python.framework.errors_impl.FailedPreconditionError:  Attempting to use uninitialized value StatefulPartitionedCall/StatefulPartitionedCall/Variable
     [[{{node StatefulPartitionedCall/StatefulPartitionedCall/Variable/read}}]] [Op:__inference_restored_function_body_207]

Function call stack:
restored_function_body

So the question is: how to save this architecture in a single saved_model.pb in tf2.0所以问题是:如何在 tf2.0 中的单个 saved_model.pb 中保存此架构

preprocessing (tf2.0 @tf.function) -> Model1 (saved_model.pb created in tf1.x) -> postprocessing (tf2.0 @tf.function)预处理(tf2.0 @tf.function) -> Model1 (saved_model.pb 创建于 tf1.x) -> 后处理(tf2.0 @tf.function)

The problem was solved.问题解决了。 Look at this exporting function and how to use it.看看这个导出函数以及如何使用它。 This function implementation accepts a single input tensor name and a list of out tensor names.此函数实现接受单个输入张量名称和输出张量名称列表。

import tensorflow as tf

def export_tf1(session, in_tnsr_fullname, out_tnsrS_fullname, export_dir='./export'):
    assert isinstance(in_tnsr_fullname, str)
    assert all([isinstance(out_tnsr_fullname, str) for out_tnsr_fullname in out_tnsrS_fullname])

    in_tnsr_name = in_tnsr_fullname.split(':')[0]
    out_tnsrS_name = [out_tnsr_fullname.split(':')[0] for out_tnsr_fullname in out_tnsrS_fullname]

    graph_def = tf.graph_util.convert_variables_to_constants(session, session.graph.as_graph_def(), out_tnsrS_name)

    tf.reset_default_graph()
    outs = tf.import_graph_def(graph_def, name="", return_elements=out_tnsrS_fullname)
    g = outs[0].graph

    builder = tf.saved_model.builder.SavedModelBuilder(export_dir)

    with tf.Session(graph=g) as sess:
        input_signatures = {in_tnsr_name: g.get_tensor_by_name(in_tnsr_fullname)}
        output_signatures = {}
        for out_tnsr_name, out_tnsr_fullname in zip(out_tnsrS_name, out_tnsrS_fullname):
            output_signatures[out_tnsr_name] = g.get_tensor_by_name(out_tnsr_fullname)
        signature = tf.saved_model.signature_def_utils.predict_signature_def(input_signatures, output_signatures)

        builder.add_meta_graph_and_variables(
            sess,
            [tf.saved_model.tag_constants.SERVING],
            {tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature},
            clear_devices=True
        )

    builder.save()

How to use the exporting function to receive .pb from tf1_ckpt checkpoint:如何使用导出函数从 tf1_ckpt 检查点接收 .pb:

import tensorflow as tf
assert tf.__version__[0] == '1'

g = tf.get_default_graph()
sess = tf.Session(graph=g)
ckpt_tf1_path = 'some_directory/name.ckpt'  # just an example
tf.train.Saver().restore(sess, ckpt_tf1_path)
input_tensor_name = 'x_tnsr:0'  # just an example
out_tensor_name = 'y_tnsr:0'  # just an example
export_tf1(sess, input_tensor_name, [out_tensor_name], export_dir)

How to reuse .pb from tf1_ckpt in .pb with tf2.0:如何使用 tf2.0 在 .pb 中重用来自 tf1_ckpt 的 .pb:

import tensorflow as tf
assert tf.__version__[0] == '2'

class Export(tf.Module):
    def __init__(self):
        super(Export, self).__init__()
        tf1_saved_model_directory = 'directory/saved_model'  # just an example
        self.tf1_model = tf.saved_model.load(tf1_saved_model_directory)
        input_tensor_name = 'x_tnsr:0'  # just an example
        out_tensor_name = 'y_tnsr:0'  # just an example
        self.tf1_model = self.tf1_model.prune(input_tensor_name, out_tensor_name)

    @tf.function
    def __call__(self, x):
        out = self.tf1_model(x)
        return out

export_dir = './saved_model'
tf.saved_model.save(Export(), export_dir)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从 tf.Session 保存到 saved_model.pb? - How to save to saved_model.pb from tf.Session? 如何正确创建saved_model.pb? - How to correctly create saved_model.pb? 将 saved_model.pb 转换为 model.tflite - Converting saved_model.pb to model.tflite 在ML引擎上进行训练后,获取save_model.pb的路径 - Get the path of saved_model.pb after training on ML engine frozen_inference_graph.pb 和saved_model.pb 有什么区别? - What is difference frozen_inference_graph.pb and saved_model.pb? OSError:SavedModel 文件不存在于:/content\model\2016/{saved_model.pbtxt|saved_model.pb} - OSError: SavedModel file does not exist at: /content\model\2016/{saved_model.pbtxt|saved_model.pb} SavedModel 文件不存在于:model.h5/{saved_model.pbtxt|saved_model.pb} - SavedModel file does not exist at: model.h5/{saved_model.pbtxt|saved_model.pb} OSError:SavedModel 文件不存在于:C:\Users\Munib\New folder/{saved_model.pbtxt|saved_model.pb} - OSError: SavedModel file does not exist at: C:\Users\Munib\New folder/{saved_model.pbtxt|saved_model.pb} 为什么 saved_model_cli 有效而加载 saved_model.pb 无效? - Why saved_model_cli works and loading saved_model.pb does not? OSError:SavedModel 文件不存在于:cnnCat2.h5\{saved_model.pbtxt|saved_model.pb} - OSError: SavedModel file does not exist at: cnnCat2.h5\{saved_model.pbtxt|saved_model.pb}
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM