我试图在"纯"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_input和StatefulPartitionedCall
这就是找到张量名称的方法。
虽然,但正确的方法是使用SignatureDefs在模型上定义图路径及其输出和输入张量。所以你加载那些SignaturesDefs而不是直接处理张量名称。
这是一个很好的参考,比官方文档更好地解释了这一点,在我看来:
https://sthalles.github.io/serving_tensorflow_models/在Keras中调用model.summary()
查看所有图层。
输入张量通常被称为input_1
、input_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_names
和output_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