History

dnn: add tf.nn.conv2d support for native model

Unlike other tf.*.conv2d layers, tf.nn.conv2d does not create many nodes (within a scope) in the graph, it just acts like other layers. tf.nn.conv2d only creates one node in the graph, and no internal nodes such as 'kernel' are created. The format of native model file is also changed, a flag named has_bias is added, so change the version number.

Guo, Yejun committed 7 years ago

Commit dff39ea1 parent a269fa06 files · +82 −18Browse files

Showing the changes to tools/python (2 of 6 files). Show all

Unified · Split

2 files
  1. tools/python/convert_from_tensorflow.py +49 −5
  2. tools/python/convert_header.py +2 −2
tools/python/convert_from_tensorflow.py+49−5
@@ -118,7 +118,7 @@ class TFConverter: · 117 unmodified lines
118 return knode, bnode, dnode, anode118 return knode, bnode, dnode, anode
119 119
120 120
121 def dump_conv2d_to_file(self, node, f):121 def dump_complex_conv2d_to_file(self, node, f):
122 assert(node.op == 'Conv2D')122 assert(node.op == 'Conv2D')
123 self.layer_number = self.layer_number + 1123 self.layer_number = self.layer_number + 1
124 self.converted_nodes.add(node.name)124 self.converted_nodes.add(node.name)
@@ -153,7 +153,8 @@ class TFConverter: · 28 unmodified lines
153 kernel = kernel.reshape(filter_height, filter_width, in_channels, out_channels)153 kernel = kernel.reshape(filter_height, filter_width, in_channels, out_channels)
154 kernel = np.transpose(kernel, [3, 0, 1, 2])154 kernel = np.transpose(kernel, [3, 0, 1, 2])
155 155
156 np.array([self.op2code[node.op], dilation, padding, self.conv_activations[activation], in_channels, out_channels, filter_height], dtype=np.uint32).tofile(f)156 has_bias = 1
157 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)
157 kernel.tofile(f)158 kernel.tofile(f)
158 159
159 btensor = bnode.attr['value'].tensor160 btensor = bnode.attr['value'].tensor
@@ -173,6 +174,41 @@ class TFConverter: · 13 unmodified lines
173 np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f)174 np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f)
174 175
175 176
177 def dump_simple_conv2d_to_file(self, node, f):
178 assert(node.op == 'Conv2D')
179 self.layer_number = self.layer_number + 1
180 self.converted_nodes.add(node.name)
181
182 node0 = self.name_node_dict[node.input[0]]
183 node1 = self.name_node_dict[node.input[1]]
184 if node0.op == 'Const':
185 knode = node0
186 input_name = node.input[1]
187 else:
188 knode = node1
189 input_name = node.input[0]
190
191 ktensor = knode.attr['value'].tensor
192 filter_height = ktensor.tensor_shape.dim[0].size
193 filter_width = ktensor.tensor_shape.dim[1].size
194 in_channels = ktensor.tensor_shape.dim[2].size
195 out_channels = ktensor.tensor_shape.dim[3].size
196 kernel = np.frombuffer(ktensor.tensor_content, dtype=np.float32)
197 kernel = kernel.reshape(filter_height, filter_width, in_channels, out_channels)
198 kernel = np.transpose(kernel, [3, 0, 1, 2])
199
200 has_bias = 0
201 dilation = 1
202 padding = node.attr['padding'].s.decode("utf-8")
203 np.array([self.op2code[node.op], dilation, self.conv_paddings[padding], self.conv_activations['None'],
204 in_channels, out_channels, filter_height, has_bias], dtype=np.uint32).tofile(f)
205 kernel.tofile(f)
206
207 input_operand_index = self.add_operand(input_name, Operand.IOTYPE_INPUT)
208 output_operand_index = self.add_operand(node.name, Operand.IOTYPE_OUTPUT)
209 np.array([input_operand_index, output_operand_index], dtype=np.uint32).tofile(f)
210
211
176 def dump_depth2space_to_file(self, node, f):212 def dump_depth2space_to_file(self, node, f):
177 assert(node.op == 'DepthToSpace')213 assert(node.op == 'DepthToSpace')
178 self.layer_number = self.layer_number + 1214 self.layer_number = self.layer_number + 1
@@ -222,10 +258,12 @@ class TFConverter: · 43 unmodified lines
222 scope_name = TFConverter.get_scope_name(node.name)258 scope_name = TFConverter.get_scope_name(node.name)
223 if scope_name in self.conv2d_scope_names:259 if scope_name in self.conv2d_scope_names:
224 if node.op == 'Conv2D':260 if node.op == 'Conv2D':
225 self.dump_conv2d_to_file(node, f)261 self.dump_complex_conv2d_to_file(node, f)
226 continue262 continue
227 263
228 if node.op == 'DepthToSpace':264 if node.op == 'Conv2D':
265 self.dump_simple_conv2d_to_file(node, f)
266 elif node.op == 'DepthToSpace':
229 self.dump_depth2space_to_file(node, f)267 self.dump_depth2space_to_file(node, f)
230 elif node.op == 'MirrorPad':268 elif node.op == 'MirrorPad':
231 self.dump_mirrorpad_to_file(node, f)269 self.dump_mirrorpad_to_file(node, f)
@@ -312,10 +350,16 @@ class TFConverter: · 80 unmodified lines
312 350
313 351
314 def generate_conv2d_scope_info(self):352 def generate_conv2d_scope_info(self):
315 # conv2d is a sub block in graph, get the scope name353 # mostly, conv2d is a sub block in graph, get the scope name
316 for node in self.nodes:354 for node in self.nodes:
317 if node.op == 'Conv2D':355 if node.op == 'Conv2D':
318 scope = TFConverter.get_scope_name(node.name)356 scope = TFConverter.get_scope_name(node.name)
357 # for the case tf.nn.conv2d is called directly
358 if scope == '':
359 continue
360 # for the case tf.nn.conv2d is called within a scope
361 if scope + '/kernel' not in self.name_node_dict:
362 continue
319 self.conv2d_scope_names.add(scope)363 self.conv2d_scope_names.add(scope)
320 364
321 # get the input name to the conv2d sub block365 # get the input name to the conv2d sub block
tools/python/convert_header.py+2−2
@@ -20,7 +20,7 @@ · 19 unmodified lines
20str = 'FFMPEGDNNNATIVE'20str = 'FFMPEGDNNNATIVE'
21 21
22# increase major and reset minor when we have to re-convert the model file22# increase major and reset minor when we have to re-convert the model file
23major = 023major = 1
24 24
25# increase minor when we don't have to re-convert the model file25# increase minor when we don't have to re-convert the model file
26minor = 226minor = 0

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t