diff --git a/mace/dsp/ops.h b/mace/dsp/ops.h index c686482c92e7f25489a5034963b8eb0fe064d19a..f8e5e7f60da5ee7d965de33ace1083801e6884b5 100644 --- a/mace/dsp/ops.h +++ b/mace/dsp/ops.h @@ -150,7 +150,6 @@ DEF_OP_WREF(QuantizedSigmoid_8) DEF_OP_WREF(QuantizedTanh_8) DEF_OP_WREF(QuantizedSoftmax_8) DEF_OP_WREF(QuantizedLRN_8) -DEF_OP_WREF(Quantizedpad2d_frame_8p) DEF_OP_WREF(QuantizedSub_8p8to32) DEF_OP_WREF(QuantizedMaximum_8) DEF_OP_WREF(QuantizedMinimum_8) diff --git a/mace/python/tools/BUILD b/mace/python/tools/BUILD index b2c7ae9e285303ff1c8dbebfa60d3d988b15739f..5a048c378e9937728d334545c2b444abc57fc3f9 100644 --- a/mace/python/tools/BUILD +++ b/mace/python/tools/BUILD @@ -1,6 +1,9 @@ py_library( name = "tf_converter_lib", - srcs = ["tf_converter_lib.py", "tf_dsp_converter_lib.py"], + srcs = [ + "tf_converter_lib.py", + "tf_dsp_converter_lib.py", + "tf_graph_util.py"], srcs_version = "PY2AND3", deps = [ "//mace/proto:mace_py", diff --git a/mace/python/tools/dsp_ops.py b/mace/python/tools/dsp_ops.py index dec73b6b55a4d5c24d7d2e7da01271ba60529070..8874b0b33a3a42fa01a07bed0fb2b601dfad2b69 100644 --- a/mace/python/tools/dsp_ops.py +++ b/mace/python/tools/dsp_ops.py @@ -47,13 +47,14 @@ class DspOps(object): 'Split': 'Split_f', 'Transpose': 'Transpose_f', 'Concat': 'Concat_f', + 'AddN': 'AddN_f', } def has_op(self, tf_op): return tf_op in self.dsp_ops def map_nn_op(self, tf_op): if tf_op not in self.dsp_ops: - raise Exception('Could not map nn op') + raise Exception('Could not map nn op for: ', tf_op) return self.dsp_ops[tf_op] diff --git a/mace/python/tools/tf_dsp_converter_lib.py b/mace/python/tools/tf_dsp_converter_lib.py index e2639123b559a9b7aec1ce6f39cd14219ea8ef23..28cb19991e9a8ccc22ae0d39ad8777e58dd1aab3 100644 --- a/mace/python/tools/tf_dsp_converter_lib.py +++ b/mace/python/tools/tf_dsp_converter_lib.py @@ -4,6 +4,7 @@ import tensorflow as tf import numpy as np from operator import mul from dsp_ops import DspOps +from mace.python.tools import tf_graph_util padding_mode = { 'NA': 0, @@ -162,6 +163,12 @@ def add_output_node(net_def, output_node): node_input.output_port = 0 def convert_to_mace_pb(input_graph_def, input_dim, output_node): + """ + nnlib does not have batch norm, so use tensorflow optimizer to fold + batch norm with convolution. The fold optimization reorders ops, so + we sort ops first by topology. + """ + input_graph_def = tf_graph_util.sort_graph(input_graph_def) inputs = input_dim.split(';') input_shape = {} for input in inputs: diff --git a/mace/python/tools/tf_graph_util.py b/mace/python/tools/tf_graph_util.py new file mode 100644 index 0000000000000000000000000000000000000000..3b899c49907901b6ce11c322ee8aa9aeeae10ce7 --- /dev/null +++ b/mace/python/tools/tf_graph_util.py @@ -0,0 +1,26 @@ +import tensorflow as tf +from collections import OrderedDict + +def sort_graph_node(node, nodes_map, ordered_nodes_map): + if node.name not in ordered_nodes_map: + for input_tensor_name in node.input: + input_node_name = input_tensor_name.split(':')[ + 0] if ':' in input_tensor_name else input_tensor_name + if input_node_name not in nodes_map or input_node_name in ordered_nodes_map: + continue + + input_node = nodes_map[input_node_name] + sort_graph_node(input_node, nodes_map, ordered_nodes_map) + ordered_nodes_map[input_node_name] = input_node + ordered_nodes_map[node.name] = node + +def sort_graph(graph_def): + nodes_map = {} + ordered_nodes_map = OrderedDict() + for node in graph_def.node: + nodes_map[node.name] = node + for node in graph_def.node: + sort_graph_node(node, nodes_map, ordered_nodes_map) + sorted_graph = tf.GraphDef() + sorted_graph.node.extend([node for _, node in ordered_nodes_map.iteritems()]) + return sorted_graph \ No newline at end of file