多个输入是 Const Op

4
我正在尝试在opencv中提供以下gitrepo:https://github.com/una-dinosauria/3d-pose-baseline,检查点数据可以在以下链接找到:https://drive.google.com/file/d/0BxWzojlLp259MF9qSFpiVjl0cU0/view 我已经构建了一个冻结的图表,可以在python中使用,并使用以下脚本生成:
meta_path = 'checkpoint-4874200.meta' # Your .meta file
output_node_names = ['linear_model/add_1']    # Output nodes
export_dir=os.path.join('export_dir')
graph=tf.Graph()

with tf.Session(graph=graph) as sess:
# Restore the graph
    loader=tf.train.import_meta_graph(meta_path)
    loader.restore(sess,'checkpoint-4874200')

    builder=tf.saved_model.builder.SavedModelBuilder(export_dir)
    builder.add_meta_graph_and_variables(sess,
                                     [tf.saved_model.SERVING],
                                     strip_default_attrs=True)


# Freeze the graph
frozen_graph_def = tf.graph_util.convert_variables_to_constants(
    sess,
    sess.graph_def,
    output_node_names)

# Save the frozen graph
with open('C:\\Users\\FrozenGraph.pb', 'wb') as f:
  f.write(frozen_graph_def.SerializeToString())

然后我通过运行以下命令来优化图形:
optimized_graph_def=optimize_for_inference_lib.optimize_for_inference(
    frozen_graph_def,
    ['inputs/enc_in'],
    ['linear_model/add_1'],
    tf.float32.as_datatype_enum)
g=tf.gfile.FastGFile('optimized_inference_graph.pb','wb')
g.write(optimized_graph_def.SerializeToString())

优化后的冻结图可以在以下链接中找到: https://github.com/alecda573/frozen_graph/blob/master/optimized_inference_graph.pb

当我尝试在OpenCV中运行以下内容时,会出现运行时错误:

OpenCV(4.3.0) Error: Unspecified error (More than one input is Const op) in cv::dnn::dnn4_v20200310::`anonymous-namespace'::TFImporter::getConstBlob, file C:\build\master_winpack-build-win64-vc15\opencv\modules\dnn\src\tensorflow\tf_importer.cpp, line 570

重现步骤

要重现问题,您只需要从上面的链接下载冻结图或从检查点数据创建自己的冻结图,然后使用下面的头文件在opencv中调用以下内容:

 #include <iostream>
 #include <vector>
 #include <cmath>
 #include <opencv2/core/core.hpp>
 #include <opencv2/highgui/highgui.hpp>
 #include <opencv2/imgproc.hpp>
 #include "opencv2/dnn.hpp"


string pbFilePath = "C:/Users/optimized_inferene_graph.pb";
//Create 3d-pose-baseline model
cv::dnn::Net inputNet;
inputNet = cv::dnn::readNetFromTensorflow(pbFilePath);

我希望知道是否有人对如何解决这个错误有任何想法。

您可以从附加的照片中看到我使用tensorboard生成的冻结图和优化图。

frozen_graph optimized

我有一种感觉,错误是由训练标志输入引起的,但我不确定,如果那不是问题,我不想去尝试编辑图形。
我附上了在OpenCV中导致该问题的函数:
const tensorflow::TensorProto& TFImporter::getConstBlob(const tensorflow::NodeDef &layer, std::map<String, int> const_layers,
                                              int input_blob_index, int* actual_inp_blob_idx) {
    if (input_blob_index == -1) {
        for(int i = 0; i < layer.input_size(); i++) {
            Pin input = parsePin(layer.input(i));
            if (const_layers.find(input.name) != const_layers.end()) {
                if (input_blob_index != -1)
                    CV_Error(Error::StsError, "More than one input is Const op");

                input_blob_index = i;
            }
        }
    }

    if (input_blob_index == -1)
        CV_Error(Error::StsError, "Const input blob for weights not found");

    Pin kernel_inp = parsePin(layer.input(input_blob_index));
    if (const_layers.find(kernel_inp.name) == const_layers.end())
        CV_Error(Error::StsError, "Input [" + layer.input(input_blob_index) +
                                  "] for node [" + layer.name() + "] not found");
    if (kernel_inp.blobIndex != 0)
        CV_Error(Error::StsError, "Unsupported kernel input");

    if(actual_inp_blob_idx) {
        *actual_inp_blob_idx = input_blob_index;
    }

    int nodeIdx = const_layers.at(kernel_inp.name);
    if (nodeIdx < netBin.node_size() && netBin.node(nodeIdx).name() == kernel_inp.name)
    {
        return netBin.node(nodeIdx).attr().at("value").tensor();
    }
    else
    {
        CV_Assert_N(nodeIdx < netTxt.node_size(),
                    netTxt.node(nodeIdx).name() == kernel_inp.name);
        return netTxt.node(nodeIdx).attr().at("value").tensor();
    }
}
1个回答

0

正如您所指出的,错误源于getConstBlobhttps://github.com/opencv/opencv/blob/master/modules/dnn/src/tensorflow/tf_importer.cpp#L570)。getConstBlobpopulateNet中被多次调用(https://github.com/opencv/opencv/blob/master/modules/dnn/src/tensorflow/tf_importer.cpp#L706),而populateNet又在所有重载的readNetFromTensor定义中被调用(https://github.com/opencv/opencv/blob/master/modules/dnn/src/tensorflow/tf_importer.cpp#L2278)。如果您想使用调试器逐步执行代码,这些可能是放置断点的起点。

我注意到的另一件事是,我相信你正在使用的populateNet的定义(提供一个std::stringhttps://docs.opencv.org/master/d6/d0f/group__dnn.html#gad820b280978d06773234ba6841e77e8d)需要两个参数 - 模型路径(model)和一个可选的配置(config),默认为空字符串。在单元测试中,看起来有提供配置和不提供配置的情况(https://github.com/opencv/opencv/blob/master/modules/dnn/test/test_tf_importer.cpp)。我不确定这是否会产生影响。
最后,在您提供的脚本中,我认为模型文件名拼写错误 - 它说optimized_inferene_graph.pb,但您在github存储库中指向的文件拼写为optimized_inference_graph.pb。

只是一些建议,希望这可以帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接