C++ C+中的推理+;Tensorflow:会话->;在提供输入和输出参数的情况下运行时,运行挂起

C++ C+中的推理+;Tensorflow:会话->;在提供输入和输出参数的情况下运行时,运行挂起,c++,linux,tensorflow,deep-learning,inference,C++,Linux,Tensorflow,Deep Learning,Inference,我使用TensorFlow及其python API培训了一个FasterRCNN进行点检测。我能够在同样的情况下成功地进行推理,没有任何问题。 现在对于生产要求,我需要构建一个独立的应用程序或库,可以在C++中执行推理。 为了实现这一目标,我成功地为C++ API建立了零开销流库,并运行了几个测试程序。 在我训练过的模型上进行推理所遵循的步骤: 方法#1:使用修改后的将图形冻结到*.pb文件,并将其还原 方法2:使用MetaGraphDef和ReadBinaryProto直接从检查点恢复 我尝试

我使用TensorFlow及其python API培训了一个FasterRCNN进行点检测。我能够在同样的情况下成功地进行推理,没有任何问题。 现在对于生产要求,我需要构建一个独立的应用程序或库,可以在C++中执行推理。 为了实现这一目标,我成功地为C++ API建立了零开销流库,并运行了几个测试程序。 在我训练过的模型上进行推理所遵循的步骤:

  • 方法#1:使用修改后的将图形冻结到*.pb文件,并将其还原
  • 方法2:使用MetaGraphDef和ReadBinaryProto直接从检查点恢复
  • 我尝试了这两种方法,加载模型似乎没有任何错误。我还打印了节点名称

    加载图形后,我为图像输入创建了一个处理程序,之前培训期间的输入由QueueRunner处理,但因为这只是一个推断,所以我自己创建了处理程序,并对其进行了适当的修改,如下所示

        Status fasterRcnn::CreateGraphForImage(bool unstack)
    {
        fileNameVar=Placeholder(iRoot.WithOpName("input"),DT_STRING);
        auto fileReader=ReadFile(iRoot.WithOpName("fileReader"),fileNameVar);
        auto imageReader=DecodeJpeg(iRoot.WithOpName("jpegReader"),fileReader,DecodeJpeg::Channels(imageChannels));
        auto floatCaster=Cast(iRoot.WithOpName("floatCaster"),imageReader,DT_FLOAT);
        auto dimsExpander=ExpandDims(iRoot.WithOpName("dim"),floatCaster,0);
        //auto resized=ResizeBilinear(iRoot.WithOpName("size"),dimsExpander,Const(iRoot,{imageSide,imageSide}));
        //auto div=Div(iRoot.WithOpName("normalized"),resized,{255.f});
        imageTensorVar=dimsExpander;//div;
        return iRoot.status();
    
    }
    
    注意:iRoot是fasterRcnn class->Scope的私有变量,图形用于将图像加载到张量中

       class fasterRcnn
    {
    private:
        Scope iRoot;//graph for loading images into tensors
        const int imageSide;
        const int imageChannels;//rgb
        //load image vars
        Output fileNameVar;
        Output imageTensorVar;
        //
        std::unique_ptr<Session> fSession;//file session
        std::unique_ptr<GraphDef> graphDef;
    public:
        fasterRcnn(int side,int channels):iRoot(Scope::NewRootScope()),imageSide(side),imageChannels(channels){}
        Status CreateGraphForImage(bool unstack);
        Status LoadSavedModel(string &fileName);//via frozen graph
        Status LoadSavedModel(std::string graph_fn,std::string checkpoint_fn);//via checkpoints
        Status PredictFromFrozen(Tensor &image,int&results);//
        Status ReadTensorFromImageFile(string& file_name, Tensor& outTensor);
        Status ReadFileTensors(string& folder_name,vector<Tensor>& file_tensors);
    
    };
    
    class-fasterRcnn
    {
    私人:
    Scope iRoot;//用于将图像加载到张量中的图形
    常量int imageSide;
    常量int imageChannels;//rgb
    //加载图像变量
    输出fileNameVar;
    输出图像张量;
    //
    std::unique_ptr fSession;//文件会话
    std::唯一的ptr图dEF;
    公众:
    fasterRcnn(int-side,int-channels):iRoot(Scope::NewRootScope()),imageSide(side),imageChannels(channels){}
    状态CreateGraphForImage(布尔取消堆栈);
    状态LoadSavedModel(字符串和文件名);//通过冻结图
    Status LoadSavedModel(std::string graph_fn,std::string checkpoint_fn);//通过检查点
    状态(张量和图像、整数和结果)//
    状态ReadTensorFromImageFile(字符串和文件名、张量和输出张量);
    状态ReadFileTensors(字符串和文件夹\u名称、向量和文件\u张量);
    };
    
    现在,当我运行会话->使用特定的输入节点名和输出节点名运行时,预测时间到了,程序挂起:

    Status fasterRcnn::PredictFromFrozen(Tensor& image, int& result)
    {
        vector<Tensor> outTensors;
        cout<<"Prediction about to start"<<endl;
        TF_CHECK_OK(fSession->Run({{"fasterrcnn/truncated_base_network/sub",image}},{"fasterrcnn/rcnn/rcnn_proposal/GatherV2_1"},{},&outTensors));
        cout<<"Prediction done"<<endl;
        auto output_c = outTensors[0].scalar<float>();
        for (int i=0;i<outTensors.size();i++)
        {
            cout << "Output dimension of the image" << outTensors[i].DebugString()<<"\n";
        }
        cout << "Output dimension of the image" << outTensors[0].DebugString()<<"\n";
        return Status::OK();
    }
    
    Status fasterRcnn::PredictFromFromFroFreeze(张量和图像、整数和结果)
    {
    向量外张量;
    库特