当将Keras模型加载到TensorFlow时,输入和输出张量的名称



我试图在"纯"TensorFlow中使用Keras模型(我想在Android应用程序中使用它)。我已经成功地将Keras模型导出到protobuf并将其导入到Tensorflow中。然而,运行tensorflow模型需要提供输入和输出张量的名称,我不知道如何找到它们。我的模型是这样的:

seq = Sequential()
seq.add(Convolution2D(32, 3, 3, input_shape=(3, 15, 15), name="Conv1"))
....
seq.add(Activation('softmax', name="Act4"))
seq.compile()

当我在TensorFlow打印张量时,我可以找到:

Tensor("Conv1_W/initial_value:0", shape=(32, 3, 3, 3), dtype=float32)
Tensor("Conv1_W:0", dtype=float32_ref)
Tensor("Conv1_W/Assign:0", shape=(32, 3, 3, 3), dtype=float32_ref)
Tensor("Conv1_W/read:0", dtype=float32)
Tensor("Act4_sample_weights:0", dtype=float32)
Tensor("Act4_target:0", dtype=float32)

然而,不存在形状为(3,15,15)的张量。

我在这里看到我可以添加"my_input_tensor"作为输入,但是我不知道它是哪种类型-我已经尝试过TensorFlow和Keras的占位符,他们给了我这个错误:

/XXXXXXXXX/lib/python2.7/site-packages/keras/engine/topology.pyc in __init__(self, input, output, name)
   1599             # check that x is an input tensor
   1600             layer, node_index, tensor_index = x._keras_history
-> 1601             if len(layer.inbound_nodes) > 1 or (layer.inbound_nodes and layer.inbound_nodes[0].inbound_layers):
   1602                 cls_name = self.__class__.__name__
   1603                 warnings.warn(cls_name + ' inputs must come from '
AttributeError: 'NoneType' object has no attribute 'inbound_nodes'

作为TensorFlow 2.0 (不幸的是他们似乎经常改变这一点)您可以将模型导出为SavedModel格式-在python中-使用

model.save('MODEL-FOLDER')

,然后使用saved_model_cli工具检查模型(至少在anaconda的python文件夹<yourenv>/bin/saved_model_cli -中找到)

saved_model_cli show --dir /path/to/model/MODEL-FOLDER/ --tag_set serve --signature_def serving_default

输出将类似于

The given SavedModel SignatureDef contains the following input(s):
  inputs['graph_input'] tensor_info:
      dtype: DT_DOUBLE
      shape: (-1, 28, 28)
      name: serving_default_graph_input:0
The given SavedModel SignatureDef contains the following output(s):
  outputs['graph_output'] tensor_info:
      dtype: DT_FLOAT
      shape: (-1, 10)
      name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict

通过检查输出,您可以看到本例中输入和输出张量的名称分别为:serving_default_graph_inputStatefulPartitionedCall

这就是找到张量名称的方法。

虽然,但正确的方法是使用SignatureDefs在模型上定义图路径及其输出和输入张量。所以你加载那些SignaturesDefs而不是直接处理张量名称。

这是一个很好的参考,比官方文档更好地解释了这一点,在我看来:

https://sthalles.github.io/serving_tensorflow_models/

在Keras中调用model.summary()查看所有图层。

输入张量通常被称为input_1input_2等。请参阅摘要中的正确名称。


当你在Keras中使用input_shape=(3,15,15)时,你实际上使用了形状为(None, 3, 15, 15)的张量。其中None将被训练或预测中的批大小取代。

通常,对于这些未知的维度,您使用-1,例如(-1, 3, 15, 15)。但我不能向你保证它会像这样起作用。它对于重塑张量非常有效,但对于创造,我从未测试过。

要获得Keras模型的输入和输出张量,请执行以下操作:

input_tensor = seq.inputs[0]
output_tensor = seq.outputs[0]
print("Inputs: "+str(input_tensor))
print("Outputs: "+str(output_tensor))

上面假设只有一个输入张量和一个输出张量。如果你有更多的张量,那么你就必须使用合适的指标来得到这些张量。

请注意,层输出形状和张量输出形状之间存在差异。两者通常是相同的,但并非总是如此。

您可以尝试在加载的模型对象上调用summary(),正如其中一个答案所建议的那样。但是,如果您无法在模型摘要中找到输入和输出名称,请尝试在模型对象上调用input_namesoutput_names,如下所示:

from tensorflow.keras.models import load_model
model = load_model("./model/00001")
print(model.input_names)
print(model.output_names)

试用TensorFlow版本:2.3.1

相关内容

  • 没有找到相关文章

最新更新