From 2bc0a830d3032d68f66369dec2c059e647c3cb6a Mon Sep 17 00:00:00 2001 From: yeliang2258 <30516196+yeliang2258@users.noreply.github.com> Date: Sun, 5 Dec 2021 20:00:02 +0800 Subject: [PATCH] Enhanced conv and pad functions in onnx opset9 (#707) * Enhanced conv and pad functions in onnx opset9 * update code style * code style * fix style --- .../op_mapper/onnx2paddle/opset9/opset.py | 78 +++++++++++++++++-- .../op_mapper/pytorch2paddle/prim2code.py | 0 2 files changed, 72 insertions(+), 6 deletions(-) mode change 100644 => 100755 x2paddle/op_mapper/pytorch2paddle/prim2code.py diff --git a/x2paddle/op_mapper/onnx2paddle/opset9/opset.py b/x2paddle/op_mapper/onnx2paddle/opset9/opset.py index 5aaa81d..55ec32e 100755 --- a/x2paddle/op_mapper/onnx2paddle/opset9/opset.py +++ b/x2paddle/op_mapper/onnx2paddle/opset9/opset.py @@ -60,7 +60,7 @@ def _rename_or_remove_weight(weights, None ''' if origin_name not in weights: - raise KeyError('{} not a key in {}'.format(origin_name, weights)) + raise KeyError('{} not a key in {}'.format(origin_name, weights.keys())) if is_remove: # remove weight data = weights.pop(origin_name) @@ -585,7 +585,21 @@ class OpSet9(): layer_attrs["pad"] = paddings paddle_op = "custom_layer:PadAllDim4WithOneInput" else: - raise Exception("The padding value {} is wrong!".format(pads)) + pad_data = node.get_attr('pads') + pad_data1 = pad_data[0::2] + pad_data_all = [] + for i in range(len(pad_data1)): + pad_data_all.append(pad_data[i]) + pad_data_all.append(pad_data[len(pad_data1) + i]) + + layer_attrs["pad"] = pad_data_all + self.paddle_graph.add_layer( + 'paddle.nn.functional.pad', + inputs={'x': val_x.name}, + outputs=layer_outputs[1:], + **layer_attrs) + return + self.paddle_graph.add_layer( paddle_op, inputs={'x': val_x.name}, @@ -1982,11 +1996,17 @@ class OpSet9(): @print_mapping_info def Conv(self, node): - op_name = name_generator("conv", self.nn_name2id) output_name = node.name - layer_outputs = [op_name, output_name] val_x = self.graph.get_input_node(node, idx=0, copy=True) val_w = self.graph.get_input_node(node, idx=1, copy=True) + + if val_w.name in self.weights.keys(): + op_name = name_generator("conv", self.nn_name2id) + else: + op_name = output_name + + layer_outputs = [op_name, output_name] + has_bias = len(node.layer.input) == 3 if has_bias: val_b = self.graph.get_input_node(node, idx=2, copy=True) @@ -2015,6 +2035,25 @@ class OpSet9(): paddings = pad_h + pad_w layer_inputs = {'x': val_x if isinstance(val_x, str) else val_x.name} + if val_w.name not in self.weights.keys(): + layer_attrs = { + "stride": strides, + "padding": paddings, + "dilation": dilations, + "groups": num_groups, + } + layer_inputs['weight'] = val_w.name + if has_bias: + layer_inputs['bias'] = val_b.name + + paddle_op = 'paddle.nn.functional.conv{}d'.format(convnd) + self.paddle_graph.add_layer( + paddle_op, + inputs=layer_inputs, + outputs=[node.name], + **layer_attrs) + return + layer_attrs = { "in_channels": num_in_channels * num_groups, "out_channels": num_out_channels, @@ -2055,11 +2094,17 @@ class OpSet9(): @print_mapping_info def ConvTranspose(self, node): - op_name = name_generator("conv_trans", self.nn_name2id) output_name = node.name - layer_outputs = [op_name, output_name] val_x = self.graph.get_input_node(node, idx=0, copy=True) val_w = self.graph.get_input_node(node, idx=1, copy=True) + + if val_w.name in self.weights.keys(): + op_name = name_generator("conv_trans", self.nn_name2id) + else: + op_name = output_name + + layer_outputs = [op_name, output_name] + val_b = None if len(node.layer.input) > 2: val_b = self.graph.get_input_node(node, idx=2, copy=True) @@ -2092,6 +2137,27 @@ class OpSet9(): # Conv2DTranspose缺少output_size,只能在forward里头传进output_size inputs_dict = {'x': val_x if isinstance(val_x, str) else val_x.name} + if val_w.name not in self.weights.keys(): + layer_attrs = { + "stride": strides, + "dilation": dilations, + "padding": paddings, + "groups": num_groups, + "output_padding": out_padding + } + paddle_op = 'paddle.nn.functional.conv{}d_transpose'.format(convnd) + + inputs_dict['weight'] = val_w.name + if len(node.layer.input) > 2: + inputs_dict['bias'] = val_b.name + + self.paddle_graph.add_layer( + paddle_op, + inputs=inputs_dict, + outputs=[node.name], + **layer_attrs) + return + layer_attrs = { "in_channels": num_in_channels, "out_channels": num_out_channels * num_groups, diff --git a/x2paddle/op_mapper/pytorch2paddle/prim2code.py b/x2paddle/op_mapper/pytorch2paddle/prim2code.py old mode 100644 new mode 100755 -- GitLab