问题描述
我目前正在通过使用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 ++中导入了模型。