Вывод в C++ Tensorflow: Session->Run зависает при запуске с входными и выходными параметрами

Я обучил FasterRCNN для обнаружения точек, используя TensorFlow и его API Python. Я смог успешно сделать вывод в том же самом без каких-либо проблем. Теперь для производственных требований мне нужно создать отдельное приложение или библиотеку, которая может выполнять вывод на C++.

Для этого мне удалось создать библиотеку TensorFlow с нуля для C++ API и запустить несколько тестовых программ.

Шаги для вывода на моей обученной модели:

  1. Способ №1: заморозить график в файл *.pb, используя модифицированный freeze_graph.py и восстановите его.
  2. Способ № 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 — это частная переменная класса fastRcnn. Область видимости, используемая графом для загрузки изображений в тензоры.

   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);

};

Теперь, когда приходит время для прогнозирования, когда я запускаю Session-›Run с определенным именем входного узла и именем выходного узла, программа зависает:

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();
}

TF_CHECK_OK(fSession-›Run({{fasterrcnn/truncated_base_network/sub,image}},{fasterrcnn/rcnn/rcnn_proposal/GatherV2_1},{},&outTensors));

Он зависает на приведенном выше заявлении.

Вплоть до нескольких соображений по отладке:

  1. Я думал, что QueueRunner может создавать проблему, но, согласно этому ответу, я обработал это, когда создал граф обработчика изображений .
  2. Думал может я не так график заморозил, вот и грузился прямо с чекпойнтов, но все равно зависает.
  3. Входные данные для усеченной сети VGG_16 в графе ожидают четырехмерный тензор с плавающей запятой, который я предоставляю, перепроверил это.

Вопрос:

  1. Есть ли какой-либо шаг, который я пропустил, для успешного вывода на С++.
  2. Как проверить правильность имен моих входных и выходных узлов? Я сослался на код Python, и они кажутся правильными.
  3. Какие-либо шаги для отладки, которые я должен выполнить, чтобы предоставить больше информации об этом?

person amit pandey    schedule 17.09.2019    source источник