将Keras模型加载到TensorFlow

时间:2016-10-05 12:44:36

标签: machine-learning tensorflow keras

我正在尝试在“纯粹的”TensorFlow中使用Keras的模型(我想在Android应用中使用它)。我已成功将Keras模型导出到protobuf并将其导入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)

Hovewer,没有形状的张量(3,15,15)。

我见过here我可以添加“my_input_tensor”作为输入,但是我不知道它是哪种类型 - 我尝试了TensorFlow和Keras的占位符,他们给了我这个错误:< / p>

/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'

3 个答案:

答案 0 :(得分:1)

在Keras中呼叫model.summary()以查看所有图层。

输入张量通常称为input_1input_2等。请在摘要中查看正确的名称。

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

通常,对于这些unknonw维度,您使用-1,例如(-1, 3, 15, 15)。但我无法向你保证它会像这样工作。它完美地适用于重塑张量,但是为了创造我从未测试过。

答案 1 :(得分:0)

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

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

以上假设只有1个输入张量和1个输出张量。如果有更多张量,则必须使用适当的索引来获取那些张量。

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

答案 2 :(得分:0)

从TensorFlow 2.0 开始(不幸的是,它们似乎经常更改),您可以使用python-使用

将模型导出为SavedModel格式
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 ,而不必直接处理张量名称。

这是一个很好的参考资料,比官方文档imo更好地解释了这一点:

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