在TensorFlow中重新训练冻结的*.pb模型

在TensorFlow中重新训练冻结的*.pb模型,tensorflow,Tensorflow,如何导入冻结的protobuf以使其能够重新训练 我在网上找到的所有方法都需要检查点。有没有办法读取protobuf,从而将内核和偏差常量转换为变量 编辑1: 这与以下问题类似: 我看了DeepSpeech,这是在对那个问题的回答中推荐的。他们似乎需要从冻结的模型中初始化。我找不到原因 编辑2:我尝试创建一个新的GraphDef对象,用变量替换内核和偏差: probable_variables=[…]#Conv2D和MatMul的内核和偏差 新的_图形_def=tf.GraphDef() 使

如何导入冻结的protobuf以使其能够重新训练

我在网上找到的所有方法都需要检查点。有没有办法读取protobuf,从而将内核和偏差常量转换为变量


编辑1: 这与以下问题类似:

我看了DeepSpeech,这是在对那个问题的回答中推荐的。他们似乎需要从冻结的模型中初始化。我找不到原因


编辑2:我尝试创建一个新的GraphDef对象,用变量替换内核和偏差:

probable_variables=[…]#Conv2D和MatMul的内核和偏差
新的_图形_def=tf.GraphDef()
使用tf.Session(graph=graph)作为sess:
对于sess.graph_def.node中的n:
如果n.name在或然变量中:
#创建变量op
nn=新建图定义节点添加()
nn.name=n.name
nn.op='VariableV2'
nn.attr['dtype'].CopyFrom(attr_value_pb2.AttrValue(type=dtype))
nn.attr['shape'].CopyFrom(attr_value_pb2.AttrValue(shape=shape))
其他:
nn=新建_model.node.add()
nn.CopyFrom(n)
不确定我是否走对了路。不知道如何在
nodededef
对象中设置
trainable=True

您提供的代码片段实际上方向正确:)


步骤1:获取以前可训练变量的名称 最棘手的部分是获取以前可训练变量的名称。希望该模型是使用一些高级框架创建的,比如or——它们将变量很好地包装在
conv2d\u 1/kernel
densite\u 1/bias
batch\u normalization/gamma
等内容中

如果您不确定,最有用的方法是可视化图形

#读取图形定义
将tf.gfile.gfile('freezed.pb','rb')作为f:
graph_def=tf.GraphDef()
graph_def.ParseFromString(f.read())
#现在在内存中构建图形并将其可视化
将tf.Graph()作为\u default()作为图形:
tf.import_graph_def(graph_def,name=“prefix”)
writer=tf.summary.FileWriter('out',graph)
writer.close()
。。。带张力板:

$ tensorboard --logdir out/
你自己看看这个图是什么样子,名字是什么


步骤2:用变量替换常量(有趣的部分:D) 你所需要的只是一个叫做的魔法图书馆。现在,假设您已将以前可培训的OP的名称(以前是变量,但现在是常量)存储在
可能变量中(如编辑2中)

注意:记住
ops
张量
变量之间的区别。Ops是图形的元素,张量是包含Ops结果的缓冲区,变量围绕张量,有3个Ops:
assign
(在初始化变量时调用)、
read
(由其他Ops调用,例如
conv2d
)和(保存值)

注2:
graph\u编辑器
只能在会话之外运行——不能在线修改任何图形

将numpy导入为np
将tensorflow.contrib.graph_编辑器作为ge导入
#将graphdef加载到内存中,如步骤1所示
图=加载图('freezed.pb')
#为每个常量创建一个变量,注意命名
const_var_name_pairs=[]
对于可能的_变量中的名称:
var_shape=graph.get_tensor_by_name({}:0).format(name)).get_shape()
var_name='{}_a'。格式(名称)
var=tf.get\u变量(name=var\u name,shape=var\u shape,dtype='float32')
const_var_name_pairs.append((name,var_name))
#从现在起,我们将与GraphDef合作
name_to_op=dict([(n.name,n)表示图中的n.as_-graph_-def().node])
#魔术:现在我们交换const的输出并创建变量
对于常量名称,常量变量名称对中的变量名称:
const_op=name_to_op[const_name]
var_reader_op=name_to_op[var_name+'/read']
ge.swap_输出(ge.sgv(const_op)、ge.sgv(var_reader_op))
#现在我们可以安全地创建会话并复制值
sess=tf.Session(graph=graph)
对于常量名称,常量变量名称对中的变量名称:
ts=graph.get\u tensor\u by\u name(“{}:0.”格式(const\u name))
var=tf.get\u变量(var\u名称)
变负荷(ts.eval(sess))
#全部完成!现在,您可以通过可视化来确保一切都是正确的
#并计算一些输入的输出。

PS:此代码未经测试;然而,我最近一直在使用
graph\u editor
并经常执行网络手术,所以我认为它应该基本正确:)

我已经用测试过的代码验证了@FalconUA的解决方案。需要稍微修改(特别是,我使用
get_variable
中的
initializer
选项来正确初始化变量)。给你

假设您的冻结模型存储在
冻结图.pb
中:

probable_variables=[…]#Conv2D和MatMul的内核和偏差
tf_-graph=load_-pb('freezed_-graph.pb'))
const_var_name_pairs=[]
使用tf_graph.as_default()作为g:
对于可能的_变量中的名称:
tensor=g.get_tensor_by_name(“{}:0.”格式(名称))
使用tf.Session()作为sess:
张量数组=sess.run(张量)
var_shape=tensor.get_shape()
#为每个变量指定一个图中不存在的名称
var_name='{}{u_var'.格式(名称)
#创建由原始常量值初始化的TensorFlow变量。
var=tf.get\u变量(name=var\u name,dtype='float32',shape=var\u shape,\
初始值设定项=tf.常数初始值设定项(张量作为numpy数组))
#我们希望为以后跟踪变量名称。
const_var_name_pairs.append((name,var_name))
#在这一点上,我们向图中添加了一组tf.变量,但它们是
def protobuf_to_checkpoint_conversion(pb_model, ckpt_dir):
    graph = tf.Graph()
    with graph.as_default():
        od_graph_def = tf.GraphDef()
        with tf.gfile.GFile(pb_model, 'rb') as fid:
            serialized_graph = fid.read()
            od_graph_def.ParseFromString(serialized_graph)
            tf.import_graph_def(od_graph_def,name='')
    image_tensor = graph.get_tensor_by_name('image_tensor:0')
    dummy = np.random.random((1, 512, 512, 3))
    with graph.as_default():
        config = tf.ConfigProto()
        with tf.Session(graph=graph, config=config) as sess:
            constant_ops = [op for op in graph.get_operations() if op.type == "Const"]
            vars_dict = {}
            ass = []
            for constant_op in constant_ops:
                name = constant_op.name
                const = constant_op.outputs[0]
                shape = const.shape
                var = tf.get_variable(name, shape, dtype=const.dtype, initializer=tf.zeros_initializer())
                vars_dict[name] = var
            print('INFO:Initializing variables')
            init = tf.global_variables_initializer()
            sess.run(init)
            print('INFO: Loading vars')
            for constant_op in tqdm(constant_ops):
                name = constant_op.name
                if 'FeatureExtractor' in name or 'BoxPredictor' in name:
                    const = constant_op.outputs[0]
                    shape = const.shape
                    var = vars_dict[name]
                    var.load(sess.run(const, feed_dict={image_tensor:dummy}), sess)
            saver = tf.train.Saver(var_list=vars_dict)
            ckpt_path = os.path.join(ckpt_dir, 'model.ckpt')
            saver.save(sess, ckpt_path)
graph = tf.Graph()
with graph.as_default():
    od_graph_def = tf.GraphDef()
    with tf.gfile.GFile(pb_model, 'rb') as fid:
        serialized_graph = fid.read()
        od_graph_def.ParseFromString(serialized_graph)
        tf.import_graph_def(od_graph_def,name='')

image_tensor = graph.get_tensor_by_name('image_tensor:0')
dummy = np.random.random((1, 512, 512, 3))

with graph.as_default():
    config = tf.ConfigProto()
    with tf.Session(graph=graph, config=config) as sess:
        constant_ops = [op for op in graph.get_operations() if op.type == "Const"]
        vars_dict = {}
        ass = []
        for constant_op in constant_ops:
            name = constant_op.name
            const = constant_op.outputs[0]
            shape = const.shape
            var = tf.get_variable(name, shape, dtype=const.dtype, initializer=tf.zeros_initializer())
            vars_dict[name] = var

        print('INFO:Initializing variables')
        init = tf.global_variables_initializer()
        sess.run(init)

        print('INFO: Loading vars')
        for constant_op in tqdm(constant_ops):
            name = constant_op.name
            if 'FeatureExtractor' in name or 'BoxPredictor' in name:
                const = constant_op.outputs[0]
                shape = const.shape
                var = vars_dict[name]
                var.load(sess.run(const, feed_dict={image_tensor:dummy}), sess)

        saver = tf.train.Saver(var_list=vars_dict)
        ckpt_path = os.path.join(ckpt_dir, 'model.ckpt')
        saver.save(sess, ckpt_path)