如何将keras模型转换为tensorflow .pb和.pbtxt而没有问题?

时间:2019-08-09 14:54:30

标签: python opencv tensorflow keras

我正在研究教程https://www.pyimagesearch.com/2019/03/11/liveness-detection-with-opencv/。本教程完美地工作,我想使用.pb和.pbtxt文件将keras模型转换为tensorflow模型。 我在大量教程中搜索了如何在Python中将keras模型转换为.pb和pb.txt。 我建立了一个函数“ freeze_session”,可以在这些文件中进行转换。 没关系,当我尝试使用OpenCV导入这些文件时,它会触发多个错误。

我第一次导入文件pb和pbtxt时收到此错误:

  错误:(-215:声明失败)const_layers.insert(std :: make_pair(name,li))。second in function'cv :: dnn :: dnn4_v20190122 ::`anonymous-namespace':: addConstNodes'< / p>

我已经在论坛中成立了,他们说我们必须设置学习阶段以在导出图形之前使用以下行代码测试值为0:

K.set_learning_phase(0)

此后,我已经成功导入仅带pb文件的TensorFlow了:

cvNet = cv.dnn.readNetFromTensorflow('./model/tf_model.pb')

在这些之后,当我想使用以下命令测试TensorFlow神经网络时,会触发一个新错误:

blob2 = cv2.dnn.blobFromImage(cv2.resize(face, (32, 32)), 1.0)

cvNet.setInput(blob2)
detections2 = cvNet.forward()

错误:

  

detections2 = cvNet.forward()cv2.error:OpenCV(4.1.0)   C:\ projects \ opencv-python \ opencv \ modules \ dnn \ src \ dnn.cpp:524:错误:   (-2:未指定的错误)无法创建类型为“ flatten_1 / Shape”的图层   函数'cv :: dnn中的“形状”:   :dnn4_v20190122 :: LayerData :: getLayerInstance'

我在几个论坛上看到我们必须删除节点和优化图,但是它对我不起作用:

https://answers.opencv.org/question/183507/opencv-dnn-import-error-for-keras-pretrained-vgg16-model/

事实上,我不能导入带有两个文件的模型,导入仅与pb文件一起使用,但不适用于检测。

我如何轻松进行此转换? 为什么有时用户仅导入pb文件,而有时又使用pb和pbtxt导入?

import tensorflow as tf

def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
    """
    Freezes the state of a session into a pruned computation graph.

    Creates a new computation graph where variable nodes are replaced by
    constants taking their current value in the session. The new graph will be
    pruned so subgraphs that are not necessary to compute the requested
    outputs are removed.
    @param session The TensorFlow session to be frozen.
    @param keep_var_names A list of variable names that should not be frozen,
                          or None to freeze all the variables in the graph.
    @param output_names Names of the relevant graph outputs.
    @param clear_devices Remove the device directives from the graph for better portability.
    @return The frozen graph definition.
    """
    from tensorflow.python.framework.graph_util import convert_variables_to_constants
    graph = session.graph
    with graph.as_default():
        freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
        output_names = output_names or []
        output_names += [v.op.name for v in tf.global_variables()]
        # Graph -> GraphDef ProtoBuf
        input_graph_def = graph.as_graph_def()
        if clear_devices:
            for node in input_graph_def.node:
                node.device = ""
        frozen_graph = convert_variables_to_constants(session, input_graph_def,
                                                      output_names, freeze_var_names)
        return frozen_graph

from keras import backend as K

K.set_learning_phase(0)  # all new operations will be in test mode from now on

sess = K.get_session()

model = load_model("liveness2.model")

frozen_graph = freeze_session(K.get_session(), output_names=[out.op.name for out in model.outputs])

# inputs:  ['conv2d_1_input']
print('inputs: ', [input.op.name for input in model.inputs])

# outputs:  ['activation_6/Softmax']
print('outputs: ', [output.op.name for output in model.outputs])


tf.train.write_graph(frozen_graph, "model", "tf_model.pb", as_text=False)
tf.train.write_graph(frozen_graph, "model", "tf_model.pbtxt", as_text=True)

net = cv2.dnn.readNetFromTensorflow("model/tf_model.pb");
  

detections2 = cvNet.forward()cv2.error:OpenCV(4.1.0)   C:\ projects \ opencv-python \ opencv \ modules \ dnn \ src \ dnn.cpp:524:错误:   (-2:未指定的错误)无法创建类型为“ flatten_1 / Shape”的图层   功能上的“形状”   'cv :: dnn :: dnn4_v20190122 :: LayerData :: getLayerInstance'

0 个答案:

没有答案