c ++中readNetFromTensorflow中的错误

时间:2018-06-01 12:02:55

标签: c++ opencv tensorflow keras

我是深度学习的新手。在第一步中,我使用keras在python中创建和训练模型,并使用此代码冻结:

def export_model(MODEL_NAME, input_node_name, output_node_name):

    tf.train.write_graph(K.get_session().graph_def, 'out', \
        MODEL_NAME + '_graph.pbtxt')

    tf.train.Saver().save(K.get_session(), 'out/' + MODEL_NAME + '.chkp')

    freeze_graph.freeze_graph('out/' + MODEL_NAME + '_graph.pbtxt', None, \
        False, 'out/' + MODEL_NAME + '.chkp', output_node_name, \
        "save/restore_all", "save/Const:0", \
        'out/frozen_' + MODEL_NAME + '.pb', True, "")

    input_graph_def = tf.GraphDef()
    with tf.gfile.Open('out/frozen_' + MODEL_NAME + '.pb', "rb") as f:
        input_graph_def.ParseFromString(f.read())

    output_graph_def = optimize_for_inference_lib.optimize_for_inference(
            input_graph_def, [input_node_name], [output_node_name],
            tf.float32.as_datatype_enum)

    with tf.gfile.FastGFile('out/opt_' + MODEL_NAME + '.pb', "wb") as f:
        f.write(output_graph_def.SerializeToString())

它的输出:

  • 检查点
  • Model.chkp.data-00000-的-00001
  • Model.chkp.index
  • Model.chkp.meta
  • Model_graph.pbtxt
  • frozen_Model.pb
  • opt_Model.pb

当我想通过readNetFromTensorflow在opencv c ++中读取网络时:

String weights = "frozen_Model.pb";
String pbtxt = "Model_graph.pbtxt";
dnn::Net cvNet = cv::dnn::readNetFromTensorflow(weights, pbtxt);

这会产生错误:

  

OpenCV(4.0.0-pre)错误:未指定错误(FAILED:ReadProtoFromBinaryFile(param_file,param)。无法解析cv :: dnn :: ReadTFNetParamsFromBinaryFileOrDie中的GraphDef文件:frozen_Model.pb,文件D:\ LIBS \ OpenCV-4.00 \ modules \ dnn \ src \ tensorflow \ tf_io.cpp,第44行

  

OpenCV(4.0.0-pre)错误:断言失败(const_layers.insert(std :: make_pair(name,li))。second)在cv :: dnn :: experimental_dnn_v4 ::`anonymous-namespace':: addConstNodes,文件D:\ LIBS \ OpenCV-4.00 \ modules \ dnn \ src \ tensorflow \ tf_importer.cpp,第555行

如何解决此错误?

3 个答案:

答案 0 :(得分:1)

Amin,我可以请你尝试在测试模式下保存图表:

K.backend.set_learning_phase(0)  # <--- This setting makes all the following layers work in test mode

model = Sequential(name = MODEL_NAME)
model.add(Conv2D(filters = 128, kernel_size = (5, 5), activation = 'relu',name = 'FirstLayerConv2D_No1',input_shape = (Width, Height, image_channel)))
...
model.add(Dropout(0.25))
model.add(Dense(100, activation = 'softmax', name = 'endNode'))

# Create a graph definition (with no weights)
sess = K.backend.get_session()
sess.as_default()
tf.train.write_graph(sess.graph.as_graph_def(), "", 'graph_def.pb', as_text=False)

然后使用freeze_graph.py脚本新创建的graph_def.pb冻结检查点文件(不要忘记使用--input_binary标记)。

答案 1 :(得分:0)

部分代码: 创建模型,培训和export_model

train_batch = gen.flow_from_directory(path + 'Train', target_size = (Width, Height), shuffle = False, color_mode = color_mode,
       batch_size = batch_size_train, class_mode = 'categorical')
.
.
X_train, Y_train = next(train_batch)
.
.
X_train = X_train.reshape(X_train.shape).astype('float32')
.  
.
model = Sequential(name = MODEL_NAME)
model.add(Conv2D(filters = 128, kernel_size = (5, 5), activation = 'relu',name = 'FirstLayerConv2D_No1',input_shape = (Width, Height, image_channel)))
model.add(Conv2D(filters = 128, kernel_size = (3, 3), activation = 'relu'))
model.add(MaxPool2D(pool_size = (2, 2)))
model.add(BatchNormalization())
.
.
.
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(200, activation = 'tanh'))
model.add(BatchNormalization())
model.add(Dropout(0.25))
model.add(Dense(100, activation = 'softmax', name = 'endNode'))
model.compile(loss = 'categorical_crossentropy', 
   optimizer = SGD(lr = 0.01, momentum = 0.9), metrics = ['accuracy'])

history = model.fit(X_train, Y_train, batch_size = batch_size_fit, epochs = epoch, shuffle = True,
         verbose = 1, validation_split = .1, validation_data = (X_test, Y_test))
export_model(MODEL_NAME, "FirstLayerConv2D_No1/Relu", "endNode/Softmax")

答案 2 :(得分:0)

python中编写图形时,需要执行以下步骤:

with tf.Session(graph=tf.Graph()) as sess:
    # 1. Load saved model
    saved_model = tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], SAVED_MODEL_PATH)

    # 2. Convert variables to constants
    inference_graph_def = tf.graph_util.convert_variables_to_constants(sess, saved_model.graph_def, OUTPUT_NODE_NAMES)

    # 3. Optimize for inference
    optimized_graph_def = optimize_for_inference_lib.optimize_for_inference(inference_graph_def,
        INPUT_NODE_NAMES,
        OUTPUT_NODE_NAMES,
        tf.float32.as_datatype_enum)

    # 4. Save .pb file
    tf.train.write_graph(optimized_graph_def, MODEL_DIR, 'model_name.pb', as_text=False)

    # 5. Transform graph
    transforms = [
        'strip_unused_nodes(type=float, shape=\"1,128,128,3\")',
        'remove_nodes(op=PlaceholderWithDefault)',
        'remove_device',
        'sort_by_execution_order'
    ]

    transformed_graph_def = TransformGraph(optimized_graph_def,
                                           INPUT_NODE_NAMES,
                                           OUTPUT_NODE_NAMES,
                                           transforms)

   # 6. Remove constant nodes and attributes
   for i in reversed(range(len(transformed_graph_def.node))):
       if transformed_graph_def.node[i].op == "Const":
           del transformed_graph_def.node[i]
       for attr in ['T', 'data_format', 'Tshape', 'N', 'Tidx', 'Tdim',
                    'use_cudnn_on_gpu', 'Index', 'Tperm', 'is_training', 'Tpaddings']:
           if attr in transformed_graph_def.node[i].attr:
               del transformed_graph_def.node[i].attr[attr]

   # 7. Save .pbtxt file
   tf.train.write_graph(transformed_graph_def, MODEL_DIR, 'model_name.pbtxt', as_text=True)

此外,如果您有特殊的节点,例如Flatten,则需要手动删除并重命名一些节点。

更多信息here