Android 给定张量流模型图,如何查找输入节点和输出节点名称
我在Tensor flow Camera演示中使用自定义模型进行分类。 我生成了一个.pb文件(序列化protobuf文件),可以显示其中包含的巨大图形。 要将此图转换为优化图,如[,可使用以下步骤:Android 给定张量流模型图,如何查找输入节点和输出节点名称,android,tensorflow,bazel,Android,Tensorflow,Bazel,我在Tensor flow Camera演示中使用自定义模型进行分类。 我生成了一个.pb文件(序列化protobuf文件),可以显示其中包含的巨大图形。 要将此图转换为优化图,如[,可使用以下步骤: $ bazel-bin/tensorflow/python/tools/optimize_for_inference \ --input=tf_files/retrained_graph.pb \ --output=tensorflow/examples/android/assets/retra
$ bazel-bin/tensorflow/python/tools/optimize_for_inference \
--input=tf_files/retrained_graph.pb \
--output=tensorflow/examples/android/assets/retrained_graph.pb
--input_names=Mul \
--output_names=final_result
这里介绍如何从图形显示中查找输入和输出名称。
当我不使用专有名称时,我会导致设备崩溃:
E/TensorFlowInferenceInterface(16821): Failed to run TensorFlow inference
with inputs:[AvgPool], outputs:[predictions]
E/AndroidRuntime(16821): FATAL EXCEPTION: inference
E/AndroidRuntime(16821): java.lang.IllegalArgumentException: Incompatible
shapes: [1,224,224,3] vs. [32,1,1,2048]
E/AndroidRuntime(16821): [[Node: dropout/dropout/mul = Mul[T=DT_FLOAT,
_device="/job:localhost/replica:0/task:0/cpu:0"](dropout/dropout/div,
dropout/dropout/Floor)]]
试试这个:
运行python
>>> import tensorflow as tf
>>> gf = tf.GraphDef()
>>> gf.ParseFromString(open('/your/path/to/graphname.pb','rb').read())
然后
>>> [n.name + '=>' + n.op for n in gf.node if n.op in ( 'Softmax','Placeholder')]
然后,您可以得到与此类似的结果:
['Mul=>Placeholder', 'final_result=>Softmax']
但我不确定这是否是关于错误消息的节点名称的问题。
我猜您在加载图形文件时提供了错误的论点,或者您生成的图形文件出错了
检查此部分:
E/AndroidRuntime(16821): java.lang.IllegalArgumentException: Incompatible
shapes: [1,224,224,3] vs. [32,1,1,2048]
更新:
很抱歉
如果使用(重新)训练的图形,请尝试以下操作:
[n.name + '=>' + n.op for n in gf.node if n.op in ( 'Softmax','Mul')]
似乎(重新)训练的图形将输入/输出op名称保存为“Mul”和“Softmax”,而优化和/或量化的图形将其保存为“占位符”和“Softmax”
顺便说一句,根据Peter Warden的帖子,不建议在移动环境中使用重新训练的图形:。由于性能和文件大小问题,最好使用量化或memmapped图形,但我无法找到如何在android中加载memmapped图形…:(
(在android中加载优化/量化图形没有问题)最近我直接从tensorflow中找到了这个选项:
bazel build tensorflow/tools/graph_transforms:summarize_graph
bazel-bin/tensorflow/tools/graph_transforms/summarize_graph
--in_graph=custom_graph_name.pb
我写了一个简单的脚本来分析计算图(通常是DAG,直接非循环图)中的依赖关系。很明显,输入是缺少输入的节点。但是,输出可以定义为图形中的任何节点,因为在最奇怪但仍然有效的情况下,输出可以是输入,而其他节点都是虚拟的。我仍然将输出操作定义为代码中没有输出的节点。您可以随意忽略它
import tensorflow as tf
def load_graph(frozen_graph_filename):
with tf.io.gfile.GFile(frozen_graph_filename, "rb") as f:
graph_def = tf.compat.v1.GraphDef()
graph_def.ParseFromString(f.read())
with tf.Graph().as_default() as graph:
tf.import_graph_def(graph_def)
return graph
def analyze_inputs_outputs(graph):
ops = graph.get_operations()
outputs_set = set(ops)
inputs = []
for op in ops:
if len(op.inputs) == 0 and op.type != 'Const':
inputs.append(op)
else:
for input_tensor in op.inputs:
if input_tensor.op in outputs_set:
outputs_set.remove(input_tensor.op)
outputs = list(outputs_set)
return (inputs, outputs)
当我为我的自定义模型执行注释时:[n.name+'=>'+n.op for n in input_graph_def.node如果n.op in('Softmax','Placeholder')],我得到[u'tower_0/logits/predictions=>Softmax'],当输入层名称不存在时,显示输出层名称。我无法理解哪里出了问题。@Dr.SantleCamilus,我认为加载图形文件时出错的原因是您试图加载一个未针对移动设备优化的图形。您不应该从重新训练的输出中使用pb文件。它在移动设备上有Djpeg问题。因此,只需使用优化的_用于_推理和/或量化图进行转换。两者都很好,但量化图更好。优化的_用于_推理或量化图或转换图操作后,[n.name+'=>'+n.op对于gf.node中的n.op in('Softmax','Placeholder')的输出为[u'tower_0/logits/predictions=>Softmax'][n.name+'=>'+n.op表示gf.node中的n,如果n.op表示('Softmax','Mul')],则在优化\u表示\u推断或量化\u图之后[u'tower\u 0/conv0/BatchNorm/moments/normalize/shift\u mean=>Mul',u'tower\u 0/conv0/BatchNorm/moments/normalize/Mul=>Mul',……u'tower\u 0/mixed\u 8x8x2048b/branch\u pool/Conv/BatchNorm/BatchNorm/Mul 1=>Mul',u'tower\u 0/logits/drop/drop/BatchNorm/Mul=>Mul','r_0/logits/dropout/dropout/mul=>mul',u'tower_0/logits/predictions=>Softmax']历史是这样的:tensorflow模型是使用inception V3 arch创建的。这些模型以检查点(ckpt)格式(.meta、.index和.data)保存的。该模型被转换为.pb文件,以端口连接到tensor flow摄像机演示()您好@Dr.SantleCamilus,您找到解决方案了吗?是的,提及正确的输入和输出节点名称对于android TF演示的工作是至关重要的。一些较旧的TF培训代码可能不包括这些名称到模型中。JP Kim的以下回答可以找到节点名称。如果没有名称,则需要迁移到新的TF培训包含正确节点名的代码。我得到的输出如下*[u'image\u tensor=>Placeholder']*[u'image\u tensor=>Placeholder']表示您的输入节点名为“image\u tensor”(/您可以在为\u接口定义optimize\u时使用--input\u names=image\u tensor)请使用以下JP Kim的回答检查您的模型中是否存在softmax节点。如果返回任何,请使用相同的名称作为输出名称。输出名称是生成CNN网络输出的特定节点。