我目前正在使用C-API导入一个经过训练的(python3.8,TF==2.3(LSTM模型(TF==1.13.2(。我必须坚持使用这个软件版本。我试着用一个假例子来展示我到目前为止的步骤。
我的模型描述(用于伪导入目的(使用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, 2, 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,
NULL, 0, NULL ,
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中,我将CCD_ 3设置为零,因为在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++中成功导入该模型。
根据tensorflow/tensorflow/core/framework/function.cc,控制输入必须以"^"开头。您可以通过在输入[1]中加上"^"来修改所有出现的"TensorArrayV2Stack/TensorListStack"中的node_def