Мы разрабатываем метод для загрузки и запуска файла .pb в нашем коде и столкнулись с нечетной ошибкой сегментации, которую мы не можем выяснить, как отлаживать. Смотрите следующий код:
extern "C" void run_graph_(char* path){
tensorflow::Status s;
tensorflow::GraphDef gdef;
s = tensorflow::ReadBinaryProto(tensorflow::Env::Default(), path, &gdef);
if (!s.ok())
{
std::cout << "error: " << s.ToString() << "\n";
}
else
{
std::cout << "complete: " << s.ToString() << "\n";
}
for (int i = 0; i < gdef.node_size(); i++)
{
if (gdef.node(i).name() == "nn_output" || gdef.node(i).name() == "nn_input")
{
gdef.node(i).PrintDebugString();
}
}
tensorflow::Session* session;
s = tensorflow::NewSession(tensorflow::SessionOptions(), &session);
s = session->Create(gdef);
std::vector<tensorflow::Tensor> outputs;
tensorflow::Input::Initializer a({{8.81474371e-01, 8.90273631e-01, 1.72516504e-01, 5.55829580e-04, 9.59886648e-01, 1.20462446e-02, 1.98175483e-03, 1.38663768e-02}});
std::cout << a.tensor.DebugString() << std::endl;
std::cout << "run" << std::endl;
s = session->Run({{"nn_input", a.tensor}}, {"nn_output"}, {}, &outputs);
std::cout << "ran" << std::endl;
if (!s.ok())
{
std::cout << "error: " << s.ToString() << "\n";
}
if( outputs.size() > 0 )
{
std::cout << "output: " << outputs[0].DebugString() << std::endl; // Tensor<type: float shape: [] values: 30>
}
// Free any resources used by the session
session->Close();
}
Если мы запустим этот код, он будет работать нормально, и мы получим следующий вывод:
complete: OK
name: "nn_input"op: "Placeholder"attr {
key: "dtype"value {
type: DT_DOUBLE
}
}
attr {
key: "shape"value {
shape {
dim {
size: -1
}
dim {
size: 8
}
}
}
}
name: "nn_output"op: "Add"input: "MatMul_4"input: "Variable_4/read"attr {
key: "T"value {
type: DT_DOUBLE
}
}
Tensor<type: double shape: [1,8] values: [0.881474371 0.890273631 0.172516504]...>
run
ran
output: Tensor<type: double shape: [1,2] values: [0.016238948144062765 0.18446201154785777]>
Однако если мы изменим входной тензор на более чем 1 строку, например:
tensorflow::Input::Initializer a({{8.81474371e-01, 8.90273631e-01, 1.72516504e-01, 5.55829580e-04, 9.59886648e-01, 1.20462446e-02, 1.98175483e-03, 1.38663768e-02}, {5.58892306e-01, 8.76436973e-01, 1.78063232e-01, 1.27910966e-01, 2.23700877e-01, 1.81518624e-01, 2.75920096e-01, 1.19812048e-02}, {3.69272573e-01, 6.75944584e-01, 8.35322158e-01, 3.89913301e-02, 4.26433973e-01, 2.94287142e-01, 1.08364415e-01, 3.93754220e-02}, {4.27477538e-01, 6.70533752e-01, 4.24946841e-02, 4.63300582e-02, 1.07105860e-02, 1.92844420e-02, 2.40294042e-02, 2.53449079e-03}, {2.66025541e-01, 9.75372575e-01, 6.53711732e-02, 7.52453239e-02, 2.75028037e-02, 1.23259054e-01, 1.29876045e-01, 1.75538941e-01}});
мы получаем ошибку сегмента, когда он пытается запустить граф со следующим выводом:
complete: OK
name: "nn_input"op: "Placeholder"attr {
key: "dtype"value {
type: DT_DOUBLE
}
}
attr {
key: "shape"value {
shape {
dim {
size: -1
}
dim {
size: 8
}
}
}
}
name: "nn_output"op: "Add"input: "MatMul_4"input: "Variable_4/read"attr {
key: "T"value {
type: DT_DOUBLE
}
}
Tensor<type: double shape: [5,8] values: [0.881474371 0.890273631 0.172516504]...>
run
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7fcd55f2f26f in ???
#1 0x7fcd5488b77a in ???
#2 0x7fcd548bebb3 in ???
#3 0x7fcd549032c3 in ???
#4 0x7fcd549204ef in ???
#5 0x7fcd52beccfc in ???
#6 0x7fcd52bbbcda in ???
#7 0x7fcd52bad633 in ???
#8 0x7fcd52818fc0 in ???
#9 0x7fcd52816d09 in ???
#10 0x7fcd5206706e in execute_native_thread_routine
at ../../../.././libstdc++-v3/src/c++11/thread.cc:83
#11 0x7fcd56d46e24 in ???
#12 0x7fcd55ff234c in ???
#13 0xffffffffffffffff in ???
Segmentation fault
Мы используем C ++ на CentOS 7. Я полагаю, что мы сможем запустить многомерный тензор через этот граф, как он работает в python. Любая помощь приветствуется.
Задача ещё не решена.
Других решений пока нет …