【问题标题】:Name of input and output tensors when loading Keras model to TensorFlow将 Keras 模型加载到 TensorFlow 时输入和输出张量的名称
【发布时间】:2016-10-05 12:44:35
【问题描述】:

我正在尝试在“纯”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) 的张量。

我已经看到 here 我可以添加“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'

【问题讨论】:

标签: machine-learning tensorflow keras


【解决方案1】:

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

model.save('MODEL-FOLDER')

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

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 而不必直接处理张量名称。

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

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

【讨论】:

    【解决方案2】:

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

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


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

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

    【讨论】:

      【解决方案3】:

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

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

      以上假设只有 1 个输入张量和 1 个输出张量。如果你有更多,那么你将不得不使用适当的索引来获取这些张量。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-23
        • 2017-12-16
        • 1970-01-01
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        • 2016-11-29
        相关资源
        最近更新 更多