From b616b2f6c94a0dcbc28973d20a7c5f5a087ce2c1 Mon Sep 17 00:00:00 2001 From: jiangjiajun Date: Wed, 17 Jun 2020 04:02:34 +0000 Subject: [PATCH] add ocr support --- x2paddle/convert.py | 2 +- .../op_mapper/paddle_custom_layer/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 172 bytes .../__pycache__/multiclass_nms.cpython-37.pyc | Bin 0 -> 7053 bytes .../__pycache__/yolo_box.cpython-37.pyc | Bin 0 -> 13426 bytes .../paddle_custom_layer/multiclass_nms.py | 415 +++++++++ .../op_mapper/paddle_custom_layer/yolo_box.py | 824 ++++++++++++++++++ x2paddle/op_mapper/paddle_op_mapper.py | 157 +++- 8 files changed, 1384 insertions(+), 14 deletions(-) create mode 100644 x2paddle/op_mapper/paddle_custom_layer/__init__.py create mode 100644 x2paddle/op_mapper/paddle_custom_layer/__pycache__/__init__.cpython-37.pyc create mode 100644 x2paddle/op_mapper/paddle_custom_layer/__pycache__/multiclass_nms.cpython-37.pyc create mode 100644 x2paddle/op_mapper/paddle_custom_layer/__pycache__/yolo_box.cpython-37.pyc create mode 100644 x2paddle/op_mapper/paddle_custom_layer/multiclass_nms.py create mode 100644 x2paddle/op_mapper/paddle_custom_layer/yolo_box.py diff --git a/x2paddle/convert.py b/x2paddle/convert.py index 92ec1cf..efd6657 100644 --- a/x2paddle/convert.py +++ b/x2paddle/convert.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. +# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License" # you may not use this file except in compliance with the License. diff --git a/x2paddle/op_mapper/paddle_custom_layer/__init__.py b/x2paddle/op_mapper/paddle_custom_layer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/x2paddle/op_mapper/paddle_custom_layer/__pycache__/__init__.cpython-37.pyc b/x2paddle/op_mapper/paddle_custom_layer/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b86f3a42a7a72082d54f17434f5860f02e6c3109 GIT binary patch literal 172 zcmZ?b<>g`kf`_dy;z0Cc5CH>>K!yVl7qb9~6oz01O-8?!3`HPe1o10WKP5joJGDqZ zD>E@K9Y|!A=ILi87U$>bM;HYprljPg>Q@*QKp6Q2@wtfw1whphf%xRo;*$K__?*N_ hpjdo-W?p7Ve7s&kDE^7b) literal 0 HcmV?d00001 diff --git a/x2paddle/op_mapper/paddle_custom_layer/__pycache__/multiclass_nms.cpython-37.pyc b/x2paddle/op_mapper/paddle_custom_layer/__pycache__/multiclass_nms.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..404e41db99321e1947e1c4a45e5bd28cfa4ebf7c GIT binary patch literal 7053 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 a_VD$1emqsO&XnIK*W`0;+NEQudH)YcOwk 0: + if ('OutSize' in input_names and len(op.input('OutSize')) > 0) or ( + 'SizeTensor' in input_names + and len(op.input('SizeTensor')) > 0): + node_list = list() roi_node = self.make_constant_node( self.get_name(op.type, 'roi'), onnx_pb.TensorProto.FLOAT, [1, 1, 1, 1, 1, 1, 1, 1]) @@ -444,16 +503,42 @@ class PaddleOpMapper(object): 'Slice', inputs=[shape_name0, starts_name, ends_name], outputs=[shape_name1]) - shape_name2 = self.get_name(op.type, "shape.cast") - shape_node2 = helper.make_node( - 'Cast', - inputs=op.input('OutSize'), - outputs=[shape_name2], - to=onnx_pb.TensorProto.INT64) + node_list.extend([ + roi_node, empty_node, shape_node0, starts_node, ends_node, + shape_node1 + ]) + # shape_name2 = self.get_name(op.type, "shape.cast") + # shape_node2 = helper.make_node( + # 'Cast', + # inputs=op.input('OutSize'), + # outputs=[shape_name2], + # to=onnx_pb.TensorProto.INT64) + if 'OutSize' in input_names and len(op.input('OutSize')) > 0: + cast_shape_name = self.get_name(op.type, "shape.cast") + cast_shape_node = helper.make_node( + 'Cast', + inputs=op.input('OutSize'), + outputs=[cast_shape_name], + to=onnx_pb.TensorProto.INT64) + node_list.append(cast_shape_node) + else: + concat_shape_name = self.get_name(op.type, "shape.concat") + concat_shape_node = helper.make_node( + "Concat", + inputs=op.input('SizeTensor'), + outputs=[concat_shape_name], + axis=0) + cast_shape_name = self.get_name(op.type, "shape.cast") + cast_shape_node = helper.make_node( + 'Cast', + inputs=[concat_shape_name], + outputs=[cast_shape_name], + to=onnx_pb.TensorProto.INT64) + node_list.extend([concat_shape_node, cast_shape_node]) shape_name3 = self.get_name(op.type, "shape.concat") shape_node3 = helper.make_node( 'Concat', - inputs=[shape_name1, shape_name2], + inputs=[shape_name1, cast_shape_name], outputs=[shape_name3], axis=0) result_node = helper.make_node( @@ -462,10 +547,8 @@ class PaddleOpMapper(object): outputs=op.output('Out'), mode='linear', coordinate_transformation_mode=coordinate_transformation_mode) - return [ - roi_node, empty_node, shape_node0, starts_node, ends_node, - shape_node1, shape_node2, shape_node3, result_node - ] + node_list.extend([shape_node3, result_node]) + return node_list elif 'Scale' in input_names and len(op.input('Scale')) > 0: node = helper.make_node( 'Resize', @@ -552,6 +635,41 @@ class PaddleOpMapper(object): beta=offset) return node + def hard_swish(self, op, block): + min_name = self.get_name(op.type, 'min') + max_name = self.get_name(op.type, 'max') + scale_name = self.get_name(op.type, 'scale') + offset_name = self.get_name(op.type, 'offset') + min_node = self.make_constant_node(min_name, onnx_pb.TensorProto.FLOAT, + 0) + max_node = self.make_constant_node(max_name, onnx_pb.TensorProto.FLOAT, + op.attr('threshold')) + scale_node = self.make_constant_node(scale_name, + onnx_pb.TensorProto.FLOAT, + op.attr('scale')) + offset_node = self.make_constant_node(offset_name, + onnx_pb.TensorProto.FLOAT, + op.attr('offset')) + + name0 = self.get_name(op.type, 'add') + node0 = helper.make_node( + 'Add', inputs=[op.input('X')[0], offset_name], outputs=[name0]) + name1 = self.get_name(op.type, 'relu') + node1 = helper.make_node( + 'Clip', + inputs=[name0, min_name, max_name], + outputs=[name1], + ) + name2 = self.get_name(op.type, 'mul') + node2 = helper.make_node( + 'Mul', inputs=[op.input('X')[0], name1], outputs=[name2]) + node3 = helper.make_node( + 'Div', inputs=[name2, scale_name], outputs=op.output('Out')) + return [ + min_node, max_node, scale_node, offset_node, node0, node1, node2, + node3 + ] + def elementwise_mul(self, op, block): axis = op.attr('axis') x_shape = block.var(op.input('X')[0]).shape @@ -617,6 +735,18 @@ class PaddleOpMapper(object): keepdims=0) return node + def yolo_box(self, op, block): + return yolo_box(op, block) + + def multiclass_nms(self, op, block): + return multiclass_nms(op, block) + + def reciprocal(self, op, block): + inputs = op.input(op.input_names[0]) + outputs = op.output(op.output_names[0]) + node = helper.make_node('Reciprocal', inputs=inputs, outputs=outputs) + return node + def convert_weights(self, program): var_names = program.global_block().vars nodes = list() @@ -651,6 +781,7 @@ class PaddleOpMapper(object): sys.stdout.write( "\rTotal:{}, Current:{} : {} ".format( len(block.ops), i + 1, op.type)) + sys.stdout.flush() if not hasattr(self, op.type): unsupported_ops.add(op.type) continue -- GitLab