Я обучил FasterRCNN для обнаружения точек, используя TensorFlow и его API Python. Я смог успешно сделать вывод в том же самом без каких-либо проблем. Теперь для производственных требований мне нужно создать отдельное приложение или библиотеку, которая может выполнять вывод на C++.
Для этого мне удалось создать библиотеку TensorFlow с нуля для C++ API и запустить несколько тестовых программ.
Шаги для вывода на моей обученной модели:
- Способ №1: заморозить график в файл *.pb, используя модифицированный freeze_graph.py и восстановите его.
- Способ № 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));
Он зависает на приведенном выше заявлении.
Вплоть до нескольких соображений по отладке:
- Я думал, что QueueRunner может создавать проблему, но, согласно этому ответу, я обработал это, когда создал граф обработчика изображений .
- Думал может я не так график заморозил, вот и грузился прямо с чекпойнтов, но все равно зависает.
- Входные данные для усеченной сети VGG_16 в графе ожидают четырехмерный тензор с плавающей запятой, который я предоставляю, перепроверил это.
Вопрос:
- Есть ли какой-либо шаг, который я пропустил, для успешного вывода на С++.
- Как проверить правильность имен моих входных и выходных узлов? Я сослался на код Python, и они кажутся правильными.
- Какие-либо шаги для отладки, которые я должен выполнить, чтобы предоставить больше информации об этом?