20 import tensorflow 
as tf
 
   23 import convert_header 
as header
 
   25 __all__ = [
'convert_from_tensorflow']
 
   30     IOTYPE_INTERMEDIATE = IOTYPE_INPUT | IOTYPE_OUTPUT
 
   41         Operand.index = Operand.index + 1
 
   42         self.
iotype2str = {Operand.IOTYPE_INPUT: 
'in', Operand.IOTYPE_OUTPUT: 
'out', Operand.IOTYPE_INTERMEDIATE: 
'inout'}
 
   43         self.
dtype2str = {Operand.DTYPE_FLOAT: 
'DT_FLOAT', Operand.DTYPE_UINT8: 
'DT_UINT8'}
 
   47         if iotype == Operand.IOTYPE_INPUT:
 
   51         return "{}: (name: {}, iotype: {}, dtype: {}, dims: ({},{},{},{}) used_count: {})".
format(self.
index,
 
   56         return self.
index < other.index
 
   59     def __init__(self, graph_def, nodes, outfile, dump4tb):
 
   73         self.
op2code = {
'Conv2D':1, 
'DepthToSpace':2, 
'MirrorPad':3, 
'Maximum':4, 
'MathBinary':5, 
'MathUnary':6}
 
   74         self.
mathbin2code = {
'Sub':0, 
'Add':1, 
'Mul':2, 
'RealDiv':3, 
'Minimum':4}
 
   83             dtype = node.attr[
'dtype'].type
 
   85                 dtype = node.attr[
'T'].type
 
   87             if 'shape' in node.attr:
 
   88                 dims[0] = node.attr[
'shape'].shape.dim[0].size
 
   89                 dims[1] = node.attr[
'shape'].shape.dim[1].size
 
   90                 dims[2] = node.attr[
'shape'].shape.dim[2].size
 
   91                 dims[3] = node.attr[
'shape'].shape.dim[3].size
 
   92             operand = 
Operand(name, dtype, dims)
 
   99         graph = tf.get_default_graph()
 
  100         tf.import_graph_def(self.
graph_def, name=
"")
 
  101         tf.summary.FileWriter(
'/tmp/graph', graph)
 
  102         print(
'graph saved, run "tensorboard --logdir=/tmp/graph" to see it')
 
  116         if conv2d_scope_name + 
'/BiasAdd' in self.
edges:
 
  117             anode = self.
edges[conv2d_scope_name + 
'/BiasAdd'][0]
 
  122         return knode, bnode, dnode, anode
 
  126         assert(node.op == 
'Conv2D')
 
  130         scope_name = TFConverter.get_scope_name(node.name)
 
  134         if dnode 
is not None:
 
  135             dilation = struct.unpack(
'i', dnode.attr[
'value'].tensor.tensor_content[0:4])[0]
 
  139         if anode 
is not None:
 
  140             activation = anode.op
 
  144         padding = node.attr[
'padding'].s.decode(
"utf-8")
 
  151         ktensor = knode.attr[
'value'].tensor
 
  152         filter_height = ktensor.tensor_shape.dim[0].size
 
  153         filter_width = ktensor.tensor_shape.dim[1].size
 
  154         in_channels = ktensor.tensor_shape.dim[2].size
 
  155         out_channels = ktensor.tensor_shape.dim[3].size
 
  156         kernel = np.frombuffer(ktensor.tensor_content, dtype=np.float32)
 
  157         kernel = kernel.reshape(filter_height, filter_width, in_channels, out_channels)
 
  158         kernel = np.transpose(kernel, [3, 0, 1, 2])
 
  161         np.array([self.
op2code[node.op], dilation, padding, self.
conv_activations[activation], in_channels, out_channels, filter_height, has_bias], dtype=np.uint32).tofile(f)
 
  164         btensor = bnode.attr[
'value'].tensor
 
  165         if btensor.tensor_shape.dim[0].size == 1:
 
  166             bias = struct.pack(
"f", btensor.float_val[0])
 
  168             bias = btensor.tensor_content
 
  172         input_operand_index = self.
add_operand(input_name, Operand.IOTYPE_INPUT)
 
  174         if anode 
is not None:
 
  175             output_operand_index = self.
add_operand(anode.name, Operand.IOTYPE_OUTPUT)
 
  177             output_operand_index = self.
add_operand(self.
edges[bnode.name][0].name, Operand.IOTYPE_OUTPUT)
 
  178         np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f)
 
  182         assert(node.op == 
'Conv2D')
 
  188         if node0.op == 
'Const':
 
  190             input_name = node.input[1]
 
  193             input_name = node.input[0]
 
  195         ktensor = knode.attr[
'value'].tensor
 
  196         filter_height = ktensor.tensor_shape.dim[0].size
 
  197         filter_width = ktensor.tensor_shape.dim[1].size
 
  198         in_channels = ktensor.tensor_shape.dim[2].size
 
  199         out_channels = ktensor.tensor_shape.dim[3].size
 
  200         if filter_height * filter_width * in_channels * out_channels == 1:
 
  201             kernel = np.float32(ktensor.float_val[0])
 
  203             kernel = np.frombuffer(ktensor.tensor_content, dtype=np.float32)
 
  204         kernel = kernel.reshape(filter_height, filter_width, in_channels, out_channels)
 
  205         kernel = np.transpose(kernel, [3, 0, 1, 2])
 
  209         padding = node.attr[
'padding'].s.decode(
"utf-8")
 
  211                   in_channels, out_channels, filter_height, has_bias], dtype=np.uint32).tofile(f)
 
  214         input_operand_index = self.
add_operand(input_name, Operand.IOTYPE_INPUT)
 
  215         output_operand_index = self.
add_operand(node.name, Operand.IOTYPE_OUTPUT)
 
  216         np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f)
 
  220         assert(node.op == 
'DepthToSpace')
 
  222         block_size = node.attr[
'block_size'].i
 
  223         np.array([self.
op2code[node.op], block_size], dtype=np.uint32).tofile(f)
 
  225         input_operand_index = self.
add_operand(node.input[0], Operand.IOTYPE_INPUT)
 
  226         output_operand_index = self.
add_operand(node.name, Operand.IOTYPE_OUTPUT)
 
  227         np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f)
 
  231         assert(node.op == 
'MirrorPad')
 
  233         mode = node.attr[
'mode'].s
 
  235         np.array([self.
op2code[node.op], mode], dtype=np.uint32).tofile(f)
 
  238         paddings = pnode.attr[
'value'].tensor.tensor_content
 
  241         input_operand_index = self.
add_operand(node.input[0], Operand.IOTYPE_INPUT)
 
  242         output_operand_index = self.
add_operand(node.name, Operand.IOTYPE_OUTPUT)
 
  243         np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f)
 
  247         assert(node.op == 
'Maximum')
 
  250         y = ynode.attr[
'value'].tensor.float_val[0]
 
  251         np.array([self.
op2code[node.op]], dtype=np.uint32).tofile(f)
 
  252         np.array([y], dtype=np.float32).tofile(f)
 
  254         input_operand_index = self.
add_operand(node.input[0], Operand.IOTYPE_INPUT)
 
  255         output_operand_index = self.
add_operand(node.name, Operand.IOTYPE_OUTPUT)
 
  256         np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f)
 
  264         np.array([self.
op2code[
'MathBinary'], self.
mathbin2code[node.op]], dtype=np.uint32).tofile(f)
 
  265         if i0_node.op == 
'Const':
 
  266             scalar = i0_node.attr[
'value'].tensor.float_val[0]
 
  267             np.array([1], dtype=np.uint32).tofile(f)            
 
  268             np.array([scalar], dtype=np.float32).tofile(f)
 
  269             np.array([0], dtype=np.uint32).tofile(f)            
 
  270             input_operand_index = self.
add_operand(i1_node.name, Operand.IOTYPE_INPUT)
 
  271             np.array([input_operand_index], dtype=np.uint32).tofile(f)
 
  272         elif i1_node.op == 
'Const':
 
  273             scalar = i1_node.attr[
'value'].tensor.float_val[0]
 
  274             np.array([0], dtype=np.uint32).tofile(f)
 
  275             input_operand_index = self.
add_operand(i0_node.name, Operand.IOTYPE_INPUT)
 
  276             np.array([input_operand_index], dtype=np.uint32).tofile(f)
 
  277             np.array([1], dtype=np.uint32).tofile(f)
 
  278             np.array([scalar], dtype=np.float32).tofile(f)
 
  280             np.array([0], dtype=np.uint32).tofile(f)
 
  281             input_operand_index = self.
add_operand(i0_node.name, Operand.IOTYPE_INPUT)
 
  282             np.array([input_operand_index], dtype=np.uint32).tofile(f)
 
  283             np.array([0], dtype=np.uint32).tofile(f)
 
  284             input_operand_index = self.
add_operand(i1_node.name, Operand.IOTYPE_INPUT)
 
  285             np.array([input_operand_index], dtype=np.uint32).tofile(f)
 
  286         output_operand_index = self.
add_operand(node.name, Operand.IOTYPE_OUTPUT)
 
  287         np.array([output_operand_index], dtype=np.uint32).tofile(f)
 
  294         np.array([self.
op2code[
'MathUnary'], self.
mathun2code[node.op]], dtype=np.uint32).tofile(f)
 
  295         input_operand_index = self.
add_operand(i0_node.name, Operand.IOTYPE_INPUT)
 
  296         np.array([input_operand_index], dtype=np.uint32).tofile(f)
 
  297         output_operand_index = self.
add_operand(node.name, Operand.IOTYPE_OUTPUT)
 
  298         np.array([output_operand_index],dtype=np.uint32).tofile(f)
 
  302         for node 
in self.
nodes:
 
  308                 if node.op == 
'Conv2D':
 
  312             if node.op == 
'Conv2D':
 
  314             elif node.op == 
'DepthToSpace':
 
  316             elif node.op == 
'MirrorPad':
 
  318             elif node.op == 
'Maximum':
 
  328             for operand 
in operands:
 
  330                 np.array([operand.index, 
len(operand.name)], dtype=np.uint32).tofile(f)
 
  331                 f.write(operand.name.encode(
'utf-8'))
 
  332                 np.array([operand.iotype, operand.dtype], dtype=np.uint32).tofile(f)
 
  333                 np.array([operand.dims[0], operand.dims[1], operand.dims[2], operand.dims[3]], dtype=np.uint32).tofile(f)
 
  337         with open(self.
outfile, 
'wb') 
as f:
 
  338             f.write(header.str.encode(
'utf-8'))
 
  339             np.array([header.major, header.minor], dtype=np.uint32).tofile(f)
 
  346         for node 
in self.
nodes:
 
  352         for node 
in self.
nodes:
 
  353             for input 
in node.input:
 
  354                 used_names.append(input)
 
  356         for node 
in self.
nodes:
 
  357             if node.name 
not in used_names:
 
  364         for node 
in self.
nodes:
 
  365             if node.op == 
'Identity':
 
  367                 input = node.input[0]
 
  368                 id_nodes.append(node)
 
  375                     id_dict[name] = input
 
  377         for idnode 
in id_nodes:
 
  378             self.
nodes.remove(idnode)
 
  380         for node 
in self.
nodes:
 
  381             for i 
in range(
len(node.input)):
 
  382                 input = node.input[i]
 
  384                     node.input[i] = id_dict[input]
 
  388         for node 
in self.
nodes:
 
  389             for input 
in node.input:
 
  390                 if input 
in self.
edges:
 
  393                     self.
edges[input] = [node]
 
  398         index = name.rfind(
'/')
 
  405         inner_scope = TFConverter.get_scope_name(name)
 
  406         if inner_scope == 
"":
 
  409             index = inner_scope.find(scope)
 
  417         for node 
in self.
nodes:
 
  418             if node.op == 
'Conv2D':
 
  419                 scope = TFConverter.get_scope_name(node.name)
 
  429         for node 
in self.
nodes:
 
  430             scope = TFConverter.get_scope_name(node.name)
 
  432                 if node.op == 
'Conv2D' or node.op == 
'Shape':
 
  433                     for inp 
in node.input:
 
  434                         if TFConverter.get_scope_name(inp) != scope:
 
  452     with open(infile, 
'rb') 
as f:
 
  454         graph_def = tf.GraphDef()
 
  455         graph_def.ParseFromString(f.read())
 
  456         nodes = graph_def.node
 
  458     converter = 
TFConverter(graph_def, nodes, outfile, dump4tb)