Tensorflow c_api1.13.2-导入LSTM .pb:预期输入[1]为控制输入

问题描述

我目前正在通过使用C-API(TF == 1.13.2)导入经过训练的(python3.8,TF == 2.3)LSTM模型。我必须坚持使用该软件版本。我尝试使用一个虚拟示例来展示到目前为止的步骤。

使用tensorflow-cli使用我的模型描述(用于虚拟导入)

python3.8 ~/path/to/tensorflow/python/tools/saved_model_cli.py show --dir ~/path/to/model/folder --tag_set serve --signature_def serving_default是:

    The given SavedModel SignatureDef contains the following input(s):
      inputs['input_1'] tensor_info:
          dtype: DT_FLOAT
          shape: (-1,2,1)
          name: serving_default_input_1:0
    The given SavedModel SignatureDef contains the following output(s):
      outputs['dense'] tensor_info:
          dtype: DT_FLOAT
          shape: (-1,1)
          name: StatefulPartitionedCall:0
    Method name is: tensorflow/serving/predict

我尝试使用以下方式导入图形结构:

uint8_t m_NumInputs = 1;
TF_Output* m_Input_ = static_cast<TF_Output*>(malloc(sizeof(TF_Output) * m_NumInputs));
TF_Output t0 = {TF_GraphOperationByName(m_Graph_,"serving_default_input_1"),0};
m_Input_[0] = t0;

//********* Get Output tensor
uint8_t m_NumOutputs = 1;
TF_Output* m_Output_ = static_cast<TF_Output*>(malloc(sizeof(TF_Output) * m_NumOutputs));
TF_Output t2 = {TF_GraphOperationByName(m_Graph_,"StatefulPartitionedCall"),0};

在声明输入值后,我使用以下命令运行会话:

TF_Tensor** InputValues = static_cast<TF_Tensor**>(malloc(sizeof(TF_Tensor*) * m_NumInputs));
TF_Tensor** OutputValues = static_cast<TF_Tensor**>(malloc(sizeof(TF_Tensor*) * m_NumOutputs));

const std::vector<std::int64_t> dims = {1,1};
const auto data_size = std::accumulate(dims.begin(),dims.end(),sizeof(float),std::multiplies<std::int64_t>{});

auto data = static_cast<float*>(std::malloc(data_size));
std::vector<float> vals = {1.0,1.0};
std::copy(vals.begin(),vals.end(),data); // init input_vals.

auto tensor = TF_NewTensor(
        TF_FLOAT,dims.data(),static_cast<int>(dims.size()),data,data_size,&NoOpDeallocator,nullptr
);

InputValues[0] = tensor;

TF_SessionRun(
        m_Session_,NULL,m_Input_,InputValues,m_NumInputs,m_Output_,OutputValues,m_NumOutputs,m_Status_
);

void* buff = TF_TensorData(OutputValues[0]);
float* offsets = static_cast<float*>(buff);

TF_SessionRun(),我收到以下错误消息:

Expected input[1] == 'TensorArrayV2_1/element_shape:output:0' to be a control input.
    In {{node TensorArrayV2Stack/TensorListStack}}
     [[{{node sequential/lstm/PartitionedCall}}]]
     [[{{node StatefulPartitionedCall}}]]
     [[{{node StatefulPartitionedCall}}]]

在这种情况下,我只是不知道控制输入的含义。在软件模块2中,我将input[1]设置为零,因为在cli输出中,在显示名称”时建议使用此设置。

我尝试了几个不同的层,并且仅在将层用于时间序列(LSTM,GRU)时才收到此错误。有人知道我可能在这里错过了什么吗?感谢您的每一个建议!

解决方法

我在python 3.6.8,Tensorflow python 2.3.0版和Tensorflow Java 1.13.1版中遇到了相同的问题。将Java版本更新为1.15.0后,它已修复,我能够通过Java的LSTM层进行预测。

,

万一其他人迷惑了这个问题,我要做的是确认该问题与所使用的Tensorflow版本有关:

我包括了TF2.3.1共享库,在Python中导出了TF2.3.1模型,并在c ++中成功导入了该模型。

之后,我将Python模型降级到1.13.1版本,并使用TF1.13.1共享库成功地在c ++中导入了模型。