Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
X2Paddle
提交
e161a582
X
X2Paddle
项目概览
PaddlePaddle
/
X2Paddle
大约 1 年 前同步成功
通知
328
Star
698
Fork
167
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
26
列表
看板
标记
里程碑
合并请求
4
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
X2Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
26
Issue
26
列表
看板
标记
里程碑
合并请求
4
合并请求
4
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
e161a582
编写于
7月 01, 2020
作者:
C
Channingss
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
optimize code structure
上级
4bb2953c
变更
11
显示空白变更内容
内联
并排
Showing
11 changed file
with
150 addition
and
151 deletion
+150
-151
x2paddle/convert.py
x2paddle/convert.py
+2
-3
x2paddle/core/fluid_code.py
x2paddle/core/fluid_code.py
+5
-0
x2paddle/op_mapper/onnx_directly_map.py
x2paddle/op_mapper/onnx_directly_map.py
+0
-82
x2paddle/op_mapper/onnx_op_mapper.py
x2paddle/op_mapper/onnx_op_mapper.py
+92
-0
x2paddle/op_mapper/onnx_opsets/__init__.py
x2paddle/op_mapper/onnx_opsets/__init__.py
+0
-0
x2paddle/op_mapper/onnx_opsets/custom_layer/InstanceNormalization.py
..._mapper/onnx_opsets/custom_layer/InstanceNormalization.py
+0
-0
x2paddle/op_mapper/onnx_opsets/custom_layer/__init__.py
x2paddle/op_mapper/onnx_opsets/custom_layer/__init__.py
+0
-0
x2paddle/op_mapper/onnx_opsets/custom_layer/register.py
x2paddle/op_mapper/onnx_opsets/custom_layer/register.py
+0
-0
x2paddle/op_mapper/onnx_opsets/opset9.py
x2paddle/op_mapper/onnx_opsets/opset9.py
+4
-50
x2paddle/op_mapper/paddle_custom_layer/yolo_box.py
x2paddle/op_mapper/paddle_custom_layer/yolo_box.py
+35
-16
x2paddle/op_mapper/paddle_op_mapper.py
x2paddle/op_mapper/paddle_op_mapper.py
+12
-0
未找到文件。
x2paddle/convert.py
浏览文件 @
e161a582
...
...
@@ -172,12 +172,11 @@ def onnx2paddle(model_path, save_dir, params_merge=False):
return
print
(
"Now translating model from onnx to paddle."
)
from
x2paddle.op_mapper.onnx
.onnx_helper
import
ONNXOpMapperFactory
from
x2paddle.op_mapper.onnx
_op_mapper
import
ONNXOpMapper
from
x2paddle.decoder.onnx_decoder
import
ONNXDecoder
from
x2paddle.optimizer.onnx_optimizer
import
ONNXOptimizer
model
=
ONNXDecoder
(
model_path
)
factory
=
ONNXOpMapperFactory
()
mapper
=
factory
.
create_onnx_op_mapper
(
model
)
mapper
=
ONNXOpMapper
(
model
)
print
(
"Model optimizing ..."
)
optimizer
=
ONNXOptimizer
(
mapper
)
print
(
"Model optimized."
)
...
...
x2paddle/core/fluid_code.py
浏览文件 @
e161a582
...
...
@@ -25,6 +25,7 @@ class Layer(object):
self
.
inputs
=
dict
()
self
.
output
=
None
self
.
is_custom_layer
=
False
self
.
use_fluid
=
False
def
get_code
(
self
):
layer_code
=
""
...
...
@@ -38,6 +39,8 @@ class Layer(object):
layer_code
=
layer_code
+
self
.
op
+
"("
elif
self
.
op
==
"="
:
layer_code
=
layer_code
elif
self
.
use_fluid
:
layer_code
=
layer_code
+
"fluid."
+
self
.
op
+
"("
else
:
layer_code
=
layer_code
+
"fluid.layers."
+
self
.
op
+
"("
...
...
@@ -108,9 +111,11 @@ class FluidCode(object):
inputs
,
output
,
param_attr
=
None
,
use_fluid
=
False
,
is_custom_layer
=
False
):
layer
=
Layer
()
layer
.
op
=
op
layer
.
use_fluid
=
use_fluid
layer
.
is_custom_layer
=
is_custom_layer
if
inputs
is
not
None
:
layer
.
inputs
=
inputs
...
...
x2paddle/op_mapper/onnx_directly_map.py
已删除
100644 → 0
浏览文件 @
4bb2953c
# Copyright (c) 2019 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.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from
collections
import
OrderedDict
as
_dict
import
numpy
as
_np
default_op_mapping_field_values
=
_dict
()
default_op_mapping_field_values
[
'FLUID_OP'
]
=
''
default_op_mapping_field_values
[
'FLUID_INPUT_ARGS'
]
=
None
default_op_mapping_field_values
[
'FLUID_OUTPUT_ARGS'
]
=
None
default_op_mapping_field_values
[
'ATTR_MAPPING'
]
=
dict
()
default_op_mapping_field_values
[
'DEFAULTS'
]
=
dict
()
default_op_mapping_field_values
[
'INPUT_PERM'
]
=
None
default_op_mapping_field_values
[
'OUTPUT_PERM'
]
=
None
default_op_mapping_field_values
[
'FILL_NAME_FIELD'
]
=
True
default_op_mapping
=
{
'Shape'
:
[
'shape'
,
[
'X'
],
[
'Out'
]],
'Clip'
:
[
'clip'
,
[
'X'
],
[
'Out'
],
dict
(),
dict
(
min
=
(
_np
.
asarray
(
[
255
,
255
,
127
,
255
],
dtype
=
_np
.
uint8
).
view
(
_np
.
float32
)[
0
]),
max
=
(
_np
.
asarray
(
[
255
,
255
,
127
,
127
],
dtype
=
_np
.
uint8
).
view
(
_np
.
float32
)[
0
]),
)
],
'Erf'
:
[
'erf'
,
[
'X'
],
[
'Out'
]],
'Ceil'
:
[
'ceil'
,
[
'X'
],
[
'Out'
]],
'ReduceMean'
:
[
'reduce_mean'
,
[
'X'
],
[
'Out'
],
dict
(
axes
=
'dim'
,
keepdims
=
'keep_dim'
),
dict
(
keep_dim
=
1
)
],
'ReduceSum'
:
[
'reduce_sum'
,
[
'X'
],
[
'Out'
],
dict
(
axes
=
'dim'
,
keepdims
=
'keep_dim'
),
dict
(
keep_dim
=
1
)
],
'ReduceMin'
:
[
'reduce_min'
,
[
'X'
],
[
'Out'
],
dict
(
axes
=
'dim'
,
keepdims
=
'keep_dim'
),
dict
(
keep_dim
=
1
)
],
'ReduceMax'
:
[
'reduce_max'
,
[
'X'
],
[
'Out'
],
dict
(
axes
=
'dim'
,
keepdims
=
'keep_dim'
),
dict
(
keep_dim
=
1
)
],
#active function
'Relu'
:
[
'relu'
,
[
'X'
],
[
'Out'
]],
'LeakyRelu'
:
[
'leaky_relu'
,
[
'X'
],
[
'Out'
],
dict
(),
dict
(
alpha
=
.
01
)],
'Elu'
:
[
'elu'
,
[
'X'
],
[
'Out'
],
dict
(),
dict
(
alpha
=
1.
)],
'ThresholdedRelu'
:
[
'thresholded_relu'
,
[
'X'
],
[
'Out'
],
dict
(
alpha
=
'threshold'
),
dict
(
alpha
=
1.
)
],
'Tanh'
:
[
'tanh'
,
[
'X'
],
[
'Out'
]],
'Sigmoid'
:
[
'sigmoid'
,
[
'X'
],
[
'Out'
]],
'HardSigmoid'
:
[
'hard_sigmoid'
,
[
'X'
],
[
'Out'
],
dict
(
alpha
=
'slope'
,
beta
=
'offset'
),
dict
(
slope
=
.
2
,
offset
=
.
5
)
],
'Softsign'
:
[
'softsign'
,
[
'X'
],
[
'Out'
]],
'Softplus'
:
[
'softplus'
,
[
'X'
],
[
'Out'
]],
'Exp'
:
[
'exp'
,
[
'X'
],
[
'Out'
]],
'Softmax'
:
[
'softmax'
,
[
'X'
],
[
'Out'
],
dict
(),
dict
(
axis
=
1
)],
'Sqrt'
:
[
'sqrt'
,
[
'X'
],
[
'Out'
]],
'Floor'
:
[
'floor'
,
[
'X'
],
[
'Out'
]],
'Abs'
:
[
'abs'
,
[
'X'
],
[
'Out'
]],
}
default_ioa_constraint
=
{
'Gather'
:
[(
lambda
i
,
o
,
a
:
a
.
get
(
'axis'
,
0
)
==
0
,
'only axis = 0 is supported'
)],
}
x2paddle/op_mapper/onnx
/onnx_hel
per.py
→
x2paddle/op_mapper/onnx
_op_map
per.py
浏览文件 @
e161a582
...
...
@@ -12,30 +12,81 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from
x2paddle.op_mapper.onnx.opset9
import
ONNXOpMapperOpSet9
from
x2paddle.op_mapper.onnx_opsets.opset9
import
OpSet9
from
x2paddle.core.op_mapper
import
OpMapper
from
x2paddle.op_mapper.onnx_opsets.custom_layer
import
*
from
x2paddle.decoder.onnx_decoder
import
ONNXGraph
,
ONNXGraphNode
,
ONNXGraphDataNode
class
ONNXOpMapperFactory
:
def
__init__
(
self
):
class
ONNXOpMapper
(
OpMapper
):
def
__init__
(
self
,
decoder
):
super
(
ONNXOpMapper
,
self
).
__init__
()
self
.
support_op_sets
=
[
9
,
]
self
.
default_op_set
=
9
self
.
graph
=
decoder
.
graph
self
.
opset
=
self
.
create_opset
(
decoder
)
if
not
self
.
op_checker
():
raise
Exception
(
"Model are not supported yet."
)
#mapping op
print
(
"Total nodes: {}"
.
format
(
sum
([
isinstance
(
node
,
ONNXGraphNode
)
for
name
,
node
in
self
.
graph
.
node_map
.
items
()
])))
def
create_onnx_op_mapper
(
self
,
decoder
):
print
(
"Nodes converting ..."
)
for
node_name
in
self
.
graph
.
topo_sort
:
node
=
self
.
graph
.
get_node
(
node_name
)
op
=
node
.
layer_type
if
hasattr
(
self
.
opset
,
op
):
func
=
getattr
(
self
.
opset
,
op
)
func
(
node
)
elif
op
in
self
.
opset
.
default_op_mapping
:
self
.
opset
.
directly_map
(
node
)
elif
op
in
custom_layers
:
self
.
opser
.
deal_custom_layer
(
node
)
elif
op
in
self
.
opset
.
elementwise_ops
:
self
.
opset
.
elementwise_map
(
node
)
print
(
"Nodes converted."
)
self
.
weights
=
self
.
opset
.
weights
self
.
omit_nodes
=
self
.
opset
.
omit_nodes
self
.
used_custom_layers
=
self
.
opset
.
used_custom_layers
def
op_checker
(
self
):
unsupported_ops
=
set
()
for
node_name
in
self
.
graph
.
topo_sort
:
node
=
self
.
graph
.
get_node
(
node_name
)
op
=
node
.
layer_type
if
not
hasattr
(
self
.
opset
,
op
)
and
\
op
not
in
self
.
opset
.
default_op_mapping
and
\
op
not
in
custom_layers
and
\
op
not
in
self
.
opset
.
elementwise_ops
:
unsupported_ops
.
add
(
op
)
if
len
(
unsupported_ops
)
==
0
:
return
True
else
:
print
(
"There are {} ops not supported yet, list as below"
.
format
(
len
(
unsupported_ops
)))
for
op
in
unsupported_ops
:
print
(
op
)
return
False
def
create_opset
(
self
,
decoder
):
run_op_set
=
self
.
default_op_set
OpMapper
=
''
opset
=
''
if
decoder
.
op_set
in
self
.
support_op_sets
:
OpMapper
=
'ONNXOpMapper
OpSet'
+
str
(
decoder
.
op_set
)
opset
=
'
OpSet'
+
str
(
decoder
.
op_set
)
elif
decoder
.
op_set
<
self
.
default_op_set
:
OpMapper
=
'ONNXOpMapper
OpSet'
+
str
(
self
.
default_op_set
)
opset
=
'
OpSet'
+
str
(
self
.
default_op_set
)
else
:
for
op_set
in
self
.
support_op_sets
:
if
decoder
.
op_set
>
op_set
:
run_op_set
=
op_set
else
:
break
OpMapper
=
'ONNXOpMapper
OpSet'
+
str
(
run_op_set
)
opset
=
'
OpSet'
+
str
(
run_op_set
)
print
(
'Now, onnx2paddle support convert onnx model opset_verison {},'
'opset_verison of your onnx model is {}, automatically treated as op_set: {}.'
.
format
(
self
.
support_op_sets
,
decoder
.
op_set
,
run_op_set
))
return
eval
(
OpMapper
)(
decoder
)
return
eval
(
opset
)(
decoder
)
x2paddle/op_mapper/onnx/__init__.py
→
x2paddle/op_mapper/onnx
_opsets
/__init__.py
浏览文件 @
e161a582
文件已移动
x2paddle/op_mapper/onnx/custom_layer/InstanceNormalization.py
→
x2paddle/op_mapper/onnx
_opsets
/custom_layer/InstanceNormalization.py
浏览文件 @
e161a582
文件已移动
x2paddle/op_mapper/onnx/custom_layer/__init__.py
→
x2paddle/op_mapper/onnx
_opsets
/custom_layer/__init__.py
浏览文件 @
e161a582
文件已移动
x2paddle/op_mapper/onnx/custom_layer/register.py
→
x2paddle/op_mapper/onnx
_opsets
/custom_layer/register.py
浏览文件 @
e161a582
文件已移动
x2paddle/op_mapper/onnx/opset9.py
→
x2paddle/op_mapper/onnx
_opsets
/opset9.py
浏览文件 @
e161a582
...
...
@@ -12,13 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from
x2paddle.decoder.onnx_decoder
import
ONNXGraph
,
ONNXGraphNode
,
ONNXGraphDataNode
from
x2paddle.core.graph
import
GraphNode
from
x2paddle.core.op_mapper
import
OpMapper
from
x2paddle.core.fluid_code
import
Layer
from
x2paddle.core.fluid_code
import
FluidCode
from
x2paddle.decoder.onnx_decoder
import
ONNXGraph
,
ONNXGraphNode
,
ONNXGraphDataNode
from
x2paddle.op_mapper.onnx.custom_layer
import
*
from
x2paddle.core.util
import
string
from
functools
import
reduce
import
numpy
as
np
import
onnx
import
onnx.numpy_helper
as
numpy_helper
...
...
@@ -28,7 +27,6 @@ from collections import OrderedDict
import
math
import
os
import
shutil
from
functools
import
reduce
_logger
=
_logging
.
getLogger
(
__name__
)
...
...
@@ -66,7 +64,7 @@ def print_mapping_info(func):
return
run_mapping
class
O
NNXOpMapperOpSet9
(
OpMapper
):
class
O
pSet9
(
):
elementwise_ops
=
{
'Add'
:
'elementwise_add'
,
'Div'
:
'elementwise_div'
,
...
...
@@ -139,57 +137,13 @@ class ONNXOpMapperOpSet9(OpMapper):
}
def
__init__
(
self
,
decoder
):
super
(
O
NNXOpMapperO
pSet9
,
self
).
__init__
()
super
(
OpSet9
,
self
).
__init__
()
self
.
graph
=
decoder
.
graph
self
.
input_shapes
=
[]
self
.
weights
=
dict
()
self
.
omit_nodes
=
list
()
self
.
used_custom_layers
=
dict
()
if
not
self
.
op_checker
():
raise
Exception
(
"Model are not supported yet."
)
#mapping op
print
(
"Total nodes: {}"
.
format
(
sum
([
isinstance
(
node
,
ONNXGraphNode
)
for
name
,
node
in
self
.
graph
.
node_map
.
items
()
])))
print
(
"Nodes converting ..."
)
for
node_name
in
self
.
graph
.
topo_sort
:
node
=
self
.
graph
.
get_node
(
node_name
)
op
=
node
.
layer_type
if
hasattr
(
self
,
op
):
func
=
getattr
(
self
,
op
)
func
(
node
)
elif
op
in
self
.
default_op_mapping
:
self
.
directly_map
(
node
)
elif
op
in
custom_layers
:
self
.
deal_custom_layer
(
node
)
elif
op
in
self
.
elementwise_ops
:
self
.
elementwise_map
(
node
)
print
(
"Nodes converted."
)
def
op_checker
(
self
):
unsupported_ops
=
set
()
for
node_name
in
self
.
graph
.
topo_sort
:
node
=
self
.
graph
.
get_node
(
node_name
)
op
=
node
.
layer_type
if
not
hasattr
(
self
,
op
)
and
\
op
not
in
self
.
default_op_mapping
and
\
op
not
in
custom_layers
and
\
op
not
in
self
.
elementwise_ops
:
unsupported_ops
.
add
(
op
)
if
len
(
unsupported_ops
)
==
0
:
return
True
else
:
print
(
"There are {} ops not supported yet, list as below"
.
format
(
len
(
unsupported_ops
)))
for
op
in
unsupported_ops
:
print
(
op
)
return
False
@
print_mapping_info
def
directly_map
(
self
,
node
,
name
=
''
,
*
args
,
**
kwargs
):
inputs
=
node
.
layer
.
input
...
...
x2paddle/op_mapper/paddle_custom_layer/yolo_box.py
浏览文件 @
e161a582
...
...
@@ -2,6 +2,8 @@ import onnx
import
numpy
as
np
from
onnx
import
onnx_pb
,
helper
MAX_FLOAT
=
np
.
asarray
([
255
,
255
,
127
,
127
],
dtype
=
np
.
uint8
).
view
(
np
.
float32
)[
0
]
def
get_old_name
(
arg
,
name_prefix
=
''
):
prefix_index
=
arg
.
find
(
name_prefix
)
...
...
@@ -747,36 +749,53 @@ def yolo_box(op, block):
outputs_pred_box_x2_clip
=
[
model_name
+
"@pred_box_x2_clip"
]
outputs_pred_box_y2_clip
=
[
model_name
+
"@pred_box_y2_clip"
]
min_const_name
=
model_name
+
"@pred_box_min_const"
max_const_name
=
model_name
+
"@pred_box_max_const"
min_const
=
onnx
.
helper
.
make_node
(
'Constant'
,
inputs
=
[],
outputs
=
[
min_const_name
],
value
=
onnx
.
helper
.
make_tensor
(
name
=
min_const_name
,
data_type
=
onnx
.
TensorProto
.
FLOAT
,
dims
=
(),
vals
=
[
0.0
]))
node_list
.
append
(
min_const
)
max_const
=
onnx
.
helper
.
make_node
(
'Constant'
,
inputs
=
[],
outputs
=
[
max_const_name
],
value
=
onnx
.
helper
.
make_tensor
(
name
=
max_const_name
,
data_type
=
onnx
.
TensorProto
.
FLOAT
,
dims
=
(),
vals
=
[
MAX_FLOAT
]))
node_list
.
append
(
max_const
)
node_pred_box_x1_clip
=
onnx
.
helper
.
make_node
(
'Clip'
,
inputs
=
outputs_pred_box_x1_decode
,
outputs
=
outputs_pred_box_x1_clip
,
min
=
0.0
,
max
=
float
(
np
.
inf
))
inputs
=
outputs_pred_box_x1_decode
+
[
min_const_name
,
max_const_name
],
outputs
=
outputs_pred_box_x1_clip
)
node_list
.
append
(
node_pred_box_x1_clip
)
node_pred_box_y1_clip
=
onnx
.
helper
.
make_node
(
'Clip'
,
inputs
=
outputs_pred_box_y1_decode
,
outputs
=
outputs_pred_box_y1_clip
,
min
=
0.0
,
max
=
float
(
np
.
inf
))
inputs
=
outputs_pred_box_y1_decode
+
[
min_const_name
,
max_const_name
],
outputs
=
outputs_pred_box_y1_clip
)
node_list
.
append
(
node_pred_box_y1_clip
)
node_pred_box_x2_clip
=
onnx
.
helper
.
make_node
(
'Clip'
,
inputs
=
outputs_pred_box_x2_sub_w
,
outputs
=
outputs_pred_box_x2_clip
,
min
=
0.0
,
max
=
float
(
np
.
inf
))
inputs
=
outputs_pred_box_x2_sub_w
+
[
min_const_name
,
max_const_name
],
outputs
=
outputs_pred_box_x2_clip
)
node_list
.
append
(
node_pred_box_x2_clip
)
node_pred_box_y2_clip
=
onnx
.
helper
.
make_node
(
'Clip'
,
inputs
=
outputs_pred_box_y2_sub_h
,
outputs
=
outputs_pred_box_y2_clip
,
min
=
0.0
,
max
=
float
(
np
.
inf
))
inputs
=
outputs_pred_box_y2_sub_h
+
[
min_const_name
,
max_const_name
],
outputs
=
outputs_pred_box_y2_clip
)
node_list
.
append
(
node_pred_box_y2_clip
)
outputs_pred_box_x2_res
=
[
model_name
+
"@box_x2_res"
]
...
...
x2paddle/op_mapper/paddle_op_mapper.py
浏览文件 @
e161a582
...
...
@@ -99,6 +99,18 @@ class PaddleOpMapper(object):
self
.
name_counter
[
name
]
+=
1
return
name
+
'.{}'
.
format
(
self
.
name_counter
[
name
])
def
im2sequence
(
self
,
op
,
block
):
from
.paddle_custom_layer.im2sequence
import
im2sequence
return
im2sequence
(
op
,
block
)
def
yolo_box
(
self
,
op
,
block
):
from
.paddle_custom_layer.yolo_box
import
yolo_box
return
yolo_box
(
op
,
block
)
def
multiclass_nms
(
self
,
op
,
block
):
from
.paddle_custom_layer.multiclass_nms
import
multiclass_nms
return
multiclass_nms
(
op
,
block
)
def
convert_weights
(
self
,
program
):
var_names
=
program
.
global_block
().
vars
nodes
=
list
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录