Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
X2Paddle
提交
98d1fd96
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看板
未验证
提交
98d1fd96
编写于
8月 03, 2020
作者:
S
SunAhong1993
提交者:
GitHub
8月 03, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #4 from PaddlePaddle/develop
00
上级
b0b27b85
14d2bc24
变更
33
隐藏空白更改
内联
并排
Showing
33 changed file
with
903 addition
and
191 deletion
+903
-191
.github/ISSUE_TEMPLATE/caffe2paddle.md
.github/ISSUE_TEMPLATE/caffe2paddle.md
+8
-0
.github/ISSUE_TEMPLATE/onnx2paddle.md
.github/ISSUE_TEMPLATE/onnx2paddle.md
+7
-0
.github/ISSUE_TEMPLATE/other.md
.github/ISSUE_TEMPLATE/other.md
+4
-0
.github/ISSUE_TEMPLATE/paddle2onnx.md
.github/ISSUE_TEMPLATE/paddle2onnx.md
+7
-0
.github/ISSUE_TEMPLATE/tensorflow2paddle.md
.github/ISSUE_TEMPLATE/tensorflow2paddle.md
+8
-0
FAQ.md
FAQ.md
+9
-0
caffe_custom_layer.md
caffe_custom_layer.md
+3
-1
op_list.md
op_list.md
+1
-0
x2paddle/__init__.py
x2paddle/__init__.py
+1
-1
x2paddle/convert.py
x2paddle/convert.py
+7
-2
x2paddle/decoder/caffe_decoder.py
x2paddle/decoder/caffe_decoder.py
+13
-0
x2paddle/decoder/onnx_shape_inference.py
x2paddle/decoder/onnx_shape_inference.py
+0
-8
x2paddle/op_mapper/caffe_custom_layer/__init__.py
x2paddle/op_mapper/caffe_custom_layer/__init__.py
+2
-0
x2paddle/op_mapper/caffe_custom_layer/axpy.py
x2paddle/op_mapper/caffe_custom_layer/axpy.py
+2
-2
x2paddle/op_mapper/caffe_custom_layer/relu6.py
x2paddle/op_mapper/caffe_custom_layer/relu6.py
+21
-0
x2paddle/op_mapper/caffe_custom_layer/upsample.py
x2paddle/op_mapper/caffe_custom_layer/upsample.py
+66
-0
x2paddle/op_mapper/caffe_op_mapper.py
x2paddle/op_mapper/caffe_op_mapper.py
+20
-1
x2paddle/op_mapper/onnx2paddle/opset9/opset.py
x2paddle/op_mapper/onnx2paddle/opset9/opset.py
+43
-18
x2paddle/op_mapper/paddle2onnx/opset10/opset.py
x2paddle/op_mapper/paddle2onnx/opset10/opset.py
+0
-12
x2paddle/op_mapper/paddle2onnx/opset10/paddle_custom_layer/im2sequence.py
...er/paddle2onnx/opset10/paddle_custom_layer/im2sequence.py
+0
-22
x2paddle/op_mapper/paddle2onnx/opset10/paddle_custom_layer/multiclass_nms.py
...paddle2onnx/opset10/paddle_custom_layer/multiclass_nms.py
+0
-32
x2paddle/op_mapper/paddle2onnx/opset10/paddle_custom_layer/yolo_box.py
...apper/paddle2onnx/opset10/paddle_custom_layer/yolo_box.py
+0
-22
x2paddle/op_mapper/paddle2onnx/opset11/opset.py
x2paddle/op_mapper/paddle2onnx/opset11/opset.py
+13
-4
x2paddle/op_mapper/paddle2onnx/opset11/paddle_custom_layer/im2sequence.py
...er/paddle2onnx/opset11/paddle_custom_layer/im2sequence.py
+0
-22
x2paddle/op_mapper/paddle2onnx/opset11/paddle_custom_layer/multiclass_nms.py
...paddle2onnx/opset11/paddle_custom_layer/multiclass_nms.py
+4
-4
x2paddle/op_mapper/paddle2onnx/opset11/paddle_custom_layer/yolo_box.py
...apper/paddle2onnx/opset11/paddle_custom_layer/yolo_box.py
+5
-16
x2paddle/op_mapper/paddle2onnx/opset9/opset.py
x2paddle/op_mapper/paddle2onnx/opset9/opset.py
+52
-5
x2paddle/op_mapper/paddle2onnx/opset9/paddle_custom_layer/box_coder.py
...apper/paddle2onnx/opset9/paddle_custom_layer/box_coder.py
+401
-0
x2paddle/op_mapper/paddle2onnx/opset9/paddle_custom_layer/multiclass_nms.py
.../paddle2onnx/opset9/paddle_custom_layer/multiclass_nms.py
+4
-4
x2paddle/op_mapper/paddle2onnx/opset9/paddle_custom_layer/prior_box.py
...apper/paddle2onnx/opset9/paddle_custom_layer/prior_box.py
+174
-0
x2paddle/op_mapper/paddle2onnx/opset9/paddle_custom_layer/yolo_box.py
...mapper/paddle2onnx/opset9/paddle_custom_layer/yolo_box.py
+15
-4
x2paddle/op_mapper/paddle2onnx/paddle_op_mapper.py
x2paddle/op_mapper/paddle2onnx/paddle_op_mapper.py
+11
-11
x2paddle_model_zoo.md
x2paddle_model_zoo.md
+2
-0
未找到文件。
.github/ISSUE_TEMPLATE/caffe2paddle.md
0 → 100644
浏览文件 @
98d1fd96
---
name
:
caffe2paddle
about
:
Caffe模型转换至PaddlePaddle,请说明Caffe模型的来源,模型类型(例如图像分类、目标检测等)
---
Caffe模型转换至PaddlePaddle,请说明Caffe模型的来源,模型类型(例如图像分类、目标检测等)
如有原模型文件或github链接,如方便可一并附上,方便开发人员分析。
.github/ISSUE_TEMPLATE/onnx2paddle.md
0 → 100644
浏览文件 @
98d1fd96
---
name
:
onnx2paddle
about
:
ONNX模型转换至PaddlePaddle,请说明ONNX模型的来源,模型类型(例如图像分类、目标检测等)
---
ONNX模型转换至PaddlePaddle,请说明ONNX模型的来源,模型类型(例如图像分类、目标检测等)
如有原模型文件或github链接,如方便可一并附上,方便开发人员分析。
.github/ISSUE_TEMPLATE/other.md
0 → 100644
浏览文件 @
98d1fd96
---
name
:
其它类型
about
:
例如Bug类,需求建议类
---
.github/ISSUE_TEMPLATE/paddle2onnx.md
0 → 100644
浏览文件 @
98d1fd96
---
name
:
paddle2onnx
about
:
Paddle模型转换至ONNX,请说明Paddle模型的来源,模型类型(例如图像分类、目标检测等)
---
Paddle模型转换至ONNX,请说明Paddle模型的来源,模型类型(例如图像分类、目标检测等)
如有原模型文件或github链接,如方便可一并附上,方便开发人员分析,同时建议说明模型转换的使用场景:)
.github/ISSUE_TEMPLATE/tensorflow2paddle.md
0 → 100644
浏览文件 @
98d1fd96
---
name
:
tensorflow2paddle
about
:
TensorFlow模型转换至PaddlePaddle,请说明TensorFlow模型的来源,模型类型(例如图像分类、目标检测等)
---
TensorFlow模型转换至PaddlePaddle,请说明TensorFlow模型的来源,模型类型(例如图像分类、目标检测等)
如有原模型文件或github链接,可以一并附上,方便开发人员分析。
FAQ.md
浏览文件 @
98d1fd96
...
...
@@ -14,3 +14,12 @@ x2paddle -f tensorflow -m tf.pb -s pd-model --without_data_format_optimization -
**Q3. ONNX模型转换过程中,提示『Unknown shape for input tensor[tensor name: "input"] -> shape: ['batch', 'sequence'], Please define shape of input here』**
A:该提示信息表示从ONNX的模型中获取到输入tensor(tensor名为"input:)的shape是语义象征性的['batch', 'sequence'],而不是dim为int类型的shape,从而可能会因为部分node的shape无法推理,导致转换失败。所以用户可以尝试手动在提示后输入详细的shape信息,如:-1,3,224,224 其中-1表示Batch
**Q4. Paddle模型转至ONNX模型过程中,提示『The parameter normalized of multiclass_nms OP of Paddle is False, which has diff with ONNX』**
A: 此提示为警告信息,模型仍然会正常进行转换。Paddle中
`fluid.layers.multiclass_nms`
算子中提供了
`normalized`
参数,用于表示输入box是否进行了归一化。而ONNX中的NMS算子只支持
`normalized`
参数为True的情况,当你转换的模型(一般是YOLOv3模型)中该参数为
`False`
的情况下,转换后的模型可能会与原模型存在diff。
**Q5. Paddle模型转至ONNX模型过程中,提示『Converting this model to ONNX need with static input shape, please fix input shape of this model』**
A: 此提示为错误信息,表示该模型的转换需要固定的输入大小:
> 1. 模型来源于PaddleX导出,可以在导出的命令中,指定--fixed_input_shape=[Height,Width],详情可见:[PaddleX模型导出文档](https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/deploy/export_model.md)。
> 2. 模型来源于PaddleDetection导出,可以在导出模型的时候,指定 TestReader.inputs_def.image_shape=[Channel,Height,Width], 详情可见:[PaddleDetection模型导出文档](https://github.com/PaddlePaddle/PaddleDetection/blob/master/docs/advanced_tutorials/deploy/EXPORT_MODEL.md#设置导出模型的输入大小)。
> 3. 模型来源于自己构建,可在网络构建的`fluid.data(shape=[])`中,指定shape参数来固定模型的输入大小。
caffe_custom_layer.md
浏览文件 @
98d1fd96
目前,代码中已经提供了
8
个非官方op(不在
[
官网
](
http://caffe.berkeleyvision.org/tutorial/layers
)
上的op)的转换,这些op对应的Caffe实现源码如下:
目前,代码中已经提供了
10
个非官方op(不在
[
官网
](
http://caffe.berkeleyvision.org/tutorial/layers
)
上的op)的转换,这些op对应的Caffe实现源码如下:
| op | 该版本实现源码 |
|-------|--------|
...
...
@@ -10,3 +10,5 @@
| Normalize |
[
code
](
https://github.com/weiliu89/caffe/blob/ssd/src/caffe/layers/normalize_layer.cpp
)
|
| ROIPooling |
[
code
](
https://github.com/rbgirshick/caffe-fast-rcnn/blob/0dcd397b29507b8314e252e850518c5695efbb83/src/caffe/layers/roi_pooling_layer.cpp
)
|
| Axpy |
[
code
](
https://github.com/hujie-frank/SENet/blob/master/src/caffe/layers/axpy_layer.cpp
)
|
| ReLU6 |
[
code
](
https://github.com/chuanqi305/ssd/blob/ssd/src/caffe/layers/relu6_layer.cpp
)
|
| Upsample |
[
code
](
https://github.com/eric612/MobileNet-YOLO/blob/master/src/caffe/layers/upsample_layer.cpp
)
|
op_list.md
浏览文件 @
98d1fd96
...
...
@@ -34,6 +34,7 @@
| 21 | Axpy | 22 | ROIPolling | 23 | Permute | 24 | DetectionOutput |
| 25 | Normalize | 26 | Select | 27 | ShuffleChannel | 28 | ConvolutionDepthwise |
| 29 | ReLU | 30 | AbsVal | 31 | Sigmoid | 32 | TanH |
| 33 | ReLU6 | 34 | Upsample |
## ONNX
...
...
x2paddle/__init__.py
浏览文件 @
98d1fd96
__version__
=
"0.
7.4
"
__version__
=
"0.
8.1
"
from
.core.program
import
PaddleProgram
...
...
x2paddle/convert.py
浏览文件 @
98d1fd96
...
...
@@ -195,9 +195,14 @@ def onnx2paddle(model_path, save_dir, params_merge=False):
def
paddle2onnx
(
model_path
,
save_dir
,
opset_version
=
10
):
from
x2paddle.decoder.paddle_decoder
import
PaddleDecoder
from
x2paddle.op_mapper.paddle2onnx.paddle_op_mapper
import
PaddleOpMapper
import
paddle.fluid
as
fluid
model
=
PaddleDecoder
(
model_path
,
'__model__'
,
'__params__'
)
mapper
=
PaddleOpMapper
()
mapper
.
convert
(
model
.
program
,
save_dir
,
opset_number
=
opset_version
)
mapper
.
convert
(
model
.
program
,
save_dir
,
scope
=
fluid
.
global_scope
(),
opset_version
=
opset_version
)
def
main
():
...
...
@@ -264,7 +269,7 @@ def main():
elif
args
.
framework
==
"paddle2onnx"
:
assert
args
.
model
is
not
None
,
"--model should be defined while translating paddle model to onnx"
paddle2onnx
(
args
.
model
,
args
.
save_dir
,
args
.
onnx_opset
)
paddle2onnx
(
args
.
model
,
args
.
save_dir
,
opset_version
=
args
.
onnx_opset
)
else
:
raise
Exception
(
...
...
x2paddle/decoder/caffe_decoder.py
浏览文件 @
98d1fd96
...
...
@@ -88,6 +88,19 @@ class CaffeGraph(Graph):
# filter them out here.
if
(
not
exclude
)
and
(
phase
==
'test'
):
exclude
=
(
type_str
==
'Dropout'
)
if
layer
.
type
==
'Dropout'
:
drop_layer_top
=
layer
.
top
[
0
]
drop_layer_bottom
=
layer
.
bottom
[
0
]
if
drop_layer_top
!=
drop_layer_bottom
:
for
next_layer
in
layers
:
for
next_layer_bottom_idx
,
next_layer_bottom
in
enumerate
(
next_layer
.
bottom
):
if
drop_layer_top
==
next_layer_bottom
:
next_layer
.
bottom
.
remove
(
drop_layer_top
)
next_layer
.
bottom
.
insert
(
next_layer_bottom_idx
,
drop_layer_bottom
)
if
not
exclude
:
filtered_layers
.
append
(
layer
)
# Guard against dupes.
...
...
x2paddle/decoder/onnx_shape_inference.py
浏览文件 @
98d1fd96
...
...
@@ -545,9 +545,6 @@ class SymbolicShapeInference:
self
.
sympy_data_
[
node
.
output
[
0
]]
=
data
new_shape
=
np
.
array
(
data
).
shape
vi
=
self
.
known_vi_
[
node
.
output
[
0
]]
#print(node.output[0])
#print(new_shape)
#vi.CopyFrom(helper.make_tensor_value_info(node.output[0], self.known_vi_[node.input[0]].type.tensor_type.elem_type, list(new_shape)))
def
_pass_on_sympy_data
(
self
,
node
):
assert
len
(
node
.
input
)
==
1
or
node
.
op_type
==
'Reshape'
...
...
@@ -854,12 +851,7 @@ class SymbolicShapeInference:
axis
=
handle_negative_axis
(
get_attribute
(
node
,
'axis'
,
0
),
len
(
data_shape
))
indices_shape
=
self
.
_get_shape
(
node
,
1
)
#if indices_shape == []:
# value = self._get_initializer_value(node, 1)
# if isinstance(value.tolist(), int):
# indices_shape = [1]
new_shape
=
data_shape
[:
axis
]
+
indices_shape
+
data_shape
[
axis
+
1
:]
#print(new_shape)
vi
=
self
.
known_vi_
[
node
.
output
[
0
]]
vi
.
CopyFrom
(
helper
.
make_tensor_value_info
(
node
.
output
[
...
...
x2paddle/op_mapper/caffe_custom_layer/__init__.py
浏览文件 @
98d1fd96
...
...
@@ -10,6 +10,8 @@ from . import select
from
.
import
shufflechannel
from
.
import
convolutiondepthwise
from
.
import
axpy
from
.
import
upsample
from
.
import
relu6
#custom layer import ends
custom_layers
=
get_registered_layers
()
...
...
x2paddle/op_mapper/caffe_custom_layer/axpy.py
浏览文件 @
98d1fd96
...
...
@@ -2,7 +2,7 @@ from .register import register
from
x2paddle.core.util
import
*
def
axpy_shape
(
input_shape
):
def
axpy_shape
(
input_shape
s
):
assert
len
(
input_shapes
)
==
3
,
"not valid input shape for axpy layer"
assert
len
(
input_shapes
[
0
])
==
len
(
input_shapes
[
1
]),
'should have same dims'
output_shape
=
input_shapes
[
1
]
...
...
@@ -18,7 +18,7 @@ def axpy_layer(inputs, input_shape=None, name=None):
y
=
inputs
[
2
]
out
=
fluid
.
layers
.
elementwise_mul
(
x
,
alpha
,
axis
=
0
)
out
=
fluid
.
layers
.
elementwise_add
(
out
,
y
,
name
=
name
)
print
(
out
)
return
out
def
axpy_weights
(
name
,
data
=
None
):
...
...
x2paddle/op_mapper/caffe_custom_layer/relu6.py
0 → 100644
浏览文件 @
98d1fd96
from
.register
import
register
from
x2paddle.core.util
import
*
def
relu6_shape
(
input_shape
):
return
input_shape
def
relu6_layer
(
inputs
,
input_shape
=
None
,
name
=
None
):
input
=
inputs
[
0
]
out
=
fluid
.
layers
.
relu6
(
x
=
input
)
return
out
def
relu6_weights
(
name
,
data
=
None
):
weights_name
=
[]
return
weights_name
register
(
kind
=
'ReLU6'
,
shape
=
relu6_shape
,
layer
=
relu6_layer
,
weights
=
relu6_weights
)
x2paddle/op_mapper/caffe_custom_layer/upsample.py
0 → 100644
浏览文件 @
98d1fd96
# -*- coding: utf-8 -*-
################################################################################
#
# Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved
#
################################################################################
"""
Author: Drift
Email: wutuobang@baidu.com
Date: 2020/04/22 18:45
"""
from
.register
import
register
from
x2paddle.core.util
import
*
def
upsample_shape
(
input_shapes
,
scale
):
"""
:param input_shapes:
:param scale:
:return:
"""
assert
len
(
input_shapes
)
==
1
,
"not valid input shape for upsample layer"
assert
type
(
scale
)
is
int
input_shape
=
input_shapes
[
0
]
new_h
=
scale
*
input_shape
[
2
]
new_w
=
scale
*
input_shape
[
3
]
output_shape
=
[
input_shape
[
0
],
input_shape
[
1
],
new_h
,
new_w
]
return
[
output_shape
]
def
upsample_layer
(
inputs
,
scale
,
input_shape
=
None
,
name
=
None
):
"""
:param inputs:
:param scale:
:param input_shape:
:param name:
:return:
"""
x
=
inputs
[
0
]
out
=
fluid
.
layers
.
resize_nearest
(
x
,
align_corners
=
False
,
scale
=
scale
,
name
=
name
)
return
out
def
upsample_weights
(
name
,
data
=
None
):
"""
:param name:
:param data:
:return:
"""
weights_name
=
[]
return
weights_name
register
(
kind
=
'Upsample'
,
shape
=
upsample_shape
,
layer
=
upsample_layer
,
weights
=
upsample_weights
)
x2paddle/op_mapper/caffe_op_mapper.py
浏览文件 @
98d1fd96
...
...
@@ -23,7 +23,6 @@ from x2paddle.op_mapper.caffe_custom_layer import *
class
CaffeOpMapper
(
OpMapper
):
directly_map_ops
=
{
'ReLU'
:
'relu'
,
'AbsVal'
:
'abs'
,
'Sigmoid'
:
'sigmoid'
,
'TanH'
:
'tanh'
,
...
...
@@ -435,6 +434,26 @@ class CaffeOpMapper(OpMapper):
node
.
fluid_code
.
add_layer
(
"concat"
,
inputs
=
inputs
,
output
=
node
,
param_attr
=
attr
)
def
ReLU
(
self
,
node
):
"""
:param node:
:return:
"""
assert
len
(
node
.
inputs
)
==
1
,
'The count of ReLU node
\'
s input is not 1.'
input
=
self
.
graph
.
get_bottom_node
(
node
,
idx
=
0
,
copy
=
True
)
params
=
node
.
layer
.
relu_param
if
params
.
HasField
(
'negative_slope'
)
and
params
.
negative_slope
!=
0
:
negative_slope
=
float
(
params
.
negative_slope
)
attr
=
{
'alpha'
:
negative_slope
}
node
.
fluid_code
.
add_layer
(
'leaky_relu'
,
inputs
=
input
,
output
=
node
,
param_attr
=
attr
)
else
:
node
.
fluid_code
.
add_layer
(
'relu'
,
inputs
=
input
,
output
=
node
)
def
PReLU
(
self
,
node
):
assert
len
(
node
.
inputs
)
==
1
,
'The count of PReLU node
\'
s input is not 1.'
...
...
x2paddle/op_mapper/onnx2paddle/opset9/opset.py
浏览文件 @
98d1fd96
...
...
@@ -332,10 +332,37 @@ class OpSet9():
def
_interpolate
(
self
,
node
):
val_x
=
self
.
graph
.
get_input_node
(
node
,
idx
=
0
,
copy
=
True
)
inputs
=
{
'input'
:
val_x
}
if
node
.
layer_type
==
'Resize'
:
val_scales
=
self
.
graph
.
get_input_node
(
node
,
idx
=
2
,
copy
=
True
)
if
len
(
node
.
layer
.
input
)
==
2
:
# opset 10
val_scales
=
self
.
graph
.
get_input_node
(
node
,
idx
=
1
,
copy
=
True
)
inputs
[
'scale'
]
=
val_scales
elif
len
(
node
.
layer
.
input
)
==
3
:
# opset 11
val_scales
=
self
.
graph
.
get_input_node
(
node
,
idx
=
2
,
copy
=
True
)
inputs
[
'scale'
]
=
val_scales
elif
len
(
node
.
layer
.
input
)
==
4
:
# opset 11
val_sizes
=
self
.
graph
.
get_input_node
(
node
,
idx
=
3
,
copy
=
True
)
var_nc
,
var_hw
=
val_sizes
.
layer_name
+
'_nc'
,
val_sizes
.
layer_name
+
'_hw'
node
.
fluid_code
.
add_layer
(
'split'
,
inputs
=
val_sizes
,
output
=
var_nc
+
','
+
var_hw
,
param_attr
=
{
'dim'
:
0
,
'num_or_sections'
:
[
2
,
2
],
})
node
.
fluid_code
.
add_layer
(
"cast"
,
inputs
=
var_hw
,
output
=
var_hw
,
param_attr
=
{
'dtype'
:
string
(
'int32'
)})
inputs
[
'out_shape'
]
=
var_hw
elif
node
.
layer_type
==
'Upsample'
:
val_scales
=
self
.
graph
.
get_input_node
(
node
,
idx
=
1
,
copy
=
True
)
inputs
[
'scale'
]
=
val_scales
attr
=
{
'name'
:
string
(
node
.
layer_name
)}
mode
=
node
.
get_attr
(
'mode'
,
'nearest'
)
...
...
@@ -345,13 +372,8 @@ class OpSet9():
'Warnning: paddle not support op:resize wiht mode: linear, we use bilinear replace linear'
)
fluid_op
=
'resize_bilinear'
node
.
fluid_code
.
add_layer
(
fluid_op
,
inputs
=
{
'input'
:
val_x
,
'scale'
:
val_scales
},
output
=
node
,
param_attr
=
attr
)
fluid_op
,
inputs
=
inputs
,
output
=
node
,
param_attr
=
attr
)
@
print_mapping_info
def
RoiAlign
(
self
,
node
):
...
...
@@ -497,7 +519,6 @@ class OpSet9():
'attribute "shape" of %s not inferred, '
'using value as 1-D tensor may lead to fails'
,
val_output
.
layer_name
,
val_output
.
layer_name
)
if
len
(
value
)
==
1
:
value
=
value
.
tolist
()
shape
=
[
1
]
...
...
@@ -814,11 +835,13 @@ class OpSet9():
inputs
=
val_shape
,
output
=
val_shape_cast
,
param_attr
=
{
'dtype'
:
string
(
'int32'
)})
node
.
fluid_code
.
add_layer
(
'reshape'
,
inputs
=
val_shape_cast
,
output
=
val_shape_cast
,
param_attr
=
{
'shape'
:
val_shape
.
out_shapes
[
0
]})
# shape may be [], come form Gather by scalar indices
if
len
(
val_shape
.
out_shapes
[
0
])
>
0
:
node
.
fluid_code
.
add_layer
(
'reshape'
,
inputs
=
val_shape_cast
,
output
=
val_shape_cast
,
param_attr
=
{
'shape'
:
val_shape
.
out_shapes
[
0
]})
node
.
fluid_code
.
add_layer
(
'reshape'
,
inputs
=
{
'x'
:
val_x
,
...
...
@@ -826,11 +849,13 @@ class OpSet9():
output
=
node
,
param_attr
=
attr
)
else
:
node
.
fluid_code
.
add_layer
(
'reshape'
,
inputs
=
val_shape
,
output
=
val_shape
,
param_attr
=
{
'shape'
:
val_shape
.
out_shapes
[
0
]})
# shape may be [], come form Gather by scalar indices
if
len
(
val_shape
.
out_shapes
[
0
])
>
0
:
node
.
fluid_code
.
add_layer
(
'reshape'
,
inputs
=
val_shape
,
output
=
val_shape
,
param_attr
=
{
'shape'
:
val_shape
.
out_shapes
[
0
]})
node
.
fluid_code
.
add_layer
(
'reshape'
,
inputs
=
{
'x'
:
val_x
,
...
...
x2paddle/op_mapper/paddle2onnx/opset10/opset.py
浏览文件 @
98d1fd96
...
...
@@ -47,15 +47,3 @@ class OpSet10(OpSet9):
inputs
=
[
op
.
input
(
'Input'
)[
0
],
starts_name
,
ends_name
,
axes_name
],
outputs
=
op
.
output
(
'Out'
),
)
return
[
starts_node
,
ends_node
,
axes_node
,
node
]
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
)
x2paddle/op_mapper/paddle2onnx/opset10/paddle_custom_layer/im2sequence.py
已删除
100644 → 0
浏览文件 @
b0b27b85
# 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.
# 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.
import
onnx
import
numpy
as
np
from
onnx
import
onnx_pb
,
helper
from
x2paddle.op_mapper.paddle2onnx.opset9.paddle_custom_layer.im2sequence
import
im2sequence
as
im2sequence9
def
im2sequence
(
op
,
block
):
return
im2sequence9
(
op
,
block
)
x2paddle/op_mapper/paddle2onnx/opset10/paddle_custom_layer/multiclass_nms.py
已删除
100644 → 0
浏览文件 @
b0b27b85
# 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.
import
math
import
sys
import
os
import
numpy
as
np
import
paddle.fluid.core
as
core
import
paddle.fluid
as
fluid
import
onnx
import
warnings
from
onnx
import
helper
,
onnx_pb
from
x2paddle.op_mapper.paddle2onnx.opset9.paddle_custom_layer.multiclass_nms
import
multiclass_nms
as
multiclass_nms9
def
multiclass_nms
(
op
,
block
):
"""
Convert the paddle multiclass_nms to onnx op.
This op is get the select boxes from origin boxes.
"""
return
multiclass_nms9
(
op
,
block
)
x2paddle/op_mapper/paddle2onnx/opset10/paddle_custom_layer/yolo_box.py
已删除
100644 → 0
浏览文件 @
b0b27b85
# 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.
# 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.
import
onnx
import
numpy
as
np
from
onnx
import
onnx_pb
,
helper
from
x2paddle.op_mapper.paddle2onnx.opset9.paddle_custom_layer.yolo_box
import
yolo_box
as
yolo_box9
def
yolo_box
(
op
,
block
):
return
yolo_box9
(
op
,
block
)
x2paddle/op_mapper/paddle2onnx/opset11/opset.py
浏览文件 @
98d1fd96
...
...
@@ -68,6 +68,19 @@ class OpSet11(OpSet10):
mode
=
op
.
attr
(
'mode'
))
return
[
pads_node
,
constant_value_node
,
node
]
def
clip
(
self
,
op
,
block
):
min_name
=
self
.
get_name
(
op
.
type
,
'min'
)
max_name
=
self
.
get_name
(
op
.
type
,
'max'
)
min_node
=
self
.
make_constant_node
(
min_name
,
onnx_pb
.
TensorProto
.
FLOAT
,
op
.
attr
(
'min'
))
max_node
=
self
.
make_constant_node
(
max_name
,
onnx_pb
.
TensorProto
.
FLOAT
,
op
.
attr
(
'max'
))
node
=
helper
.
make_node
(
'Clip'
,
inputs
=
[
op
.
input
(
'X'
)[
0
],
min_name
,
max_name
],
outputs
=
op
.
output
(
'Out'
))
return
[
min_node
,
max_node
,
node
]
def
bilinear_interp
(
self
,
op
,
block
):
input_names
=
op
.
input_names
coordinate_transformation_mode
=
''
...
...
@@ -263,10 +276,6 @@ class OpSet11(OpSet10):
node3
]
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
)
...
...
x2paddle/op_mapper/paddle2onnx/opset11/paddle_custom_layer/im2sequence.py
已删除
100644 → 0
浏览文件 @
b0b27b85
# 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.
# 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.
import
onnx
import
numpy
as
np
from
onnx
import
onnx_pb
,
helper
from
x2paddle.op_mapper.paddle2onnx.opset10.paddle_custom_layer.im2sequence
import
im2sequence
as
im2sequence10
def
im2sequence
(
op
,
block
):
return
im2sequence10
(
op
,
block
)
x2paddle/op_mapper/paddle2onnx/opset11/paddle_custom_layer/multiclass_nms.py
浏览文件 @
98d1fd96
...
...
@@ -19,7 +19,7 @@ import numpy as np
import
paddle.fluid.core
as
core
import
paddle.fluid
as
fluid
import
onnx
import
warnings
import
logging
from
onnx
import
helper
,
onnx_pb
...
...
@@ -42,9 +42,9 @@ def multiclass_nms(op, block):
background
=
attrs
[
'background_label'
]
normalized
=
attrs
[
'normalized'
]
if
normalized
==
False
:
warnings
.
warn
(
'The parameter normalized of multiclass_nms OP of Paddle is False, which has diff with ONNX.
\
Please set normalized=True in multiclass_nms of Paddle'
)
logging
.
warn
(
"The parameter normalized of multiclass_nms OP of Paddle is False, which has diff with ONNX."
\
" Please set normalized=True in multiclass_nms of Paddle, see doc Q4 in https://github.com/PaddlePaddle/X2Paddle/blob/develop/FAQ.md"
)
#convert the paddle attribute to onnx tensor
name_score_threshold
=
[
outputs
[
'Out'
][
0
]
+
"@score_threshold"
]
...
...
x2paddle/op_mapper/paddle2onnx/opset11/paddle_custom_layer/yolo_box.py
浏览文件 @
98d1fd96
...
...
@@ -15,21 +15,9 @@
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
)
if
prefix_index
!=
-
1
:
last_prefix
=
arg
[
len
(
name_prefix
):]
else
:
last_prefix
=
arg
idx
=
last_prefix
.
find
(
'@'
)
if
idx
!=
-
1
:
last_prefix
=
last_prefix
[:
idx
]
return
name_prefix
+
last_prefix
from
x2paddle.op_mapper.paddle2onnx.opset9.paddle_custom_layer.yolo_box
import
is_static_shape
from
x2paddle.op_mapper.paddle2onnx.opset9.paddle_custom_layer.yolo_box
import
get_old_name
from
x2paddle.op_mapper.paddle2onnx.opset9.paddle_custom_layer.yolo_box
import
MAX_FLOAT32
def
yolo_box
(
op
,
block
):
...
...
@@ -44,6 +32,7 @@ def yolo_box(op, block):
attrs
[
name
]
=
op
.
attr
(
name
)
model_name
=
outputs
[
'Boxes'
][
0
]
input_shape
=
block
.
vars
[
get_old_name
(
inputs
[
'X'
][
0
])].
shape
is_static_shape
(
input_shape
)
image_size
=
inputs
[
'ImgSize'
]
input_height
=
input_shape
[
2
]
input_width
=
input_shape
[
3
]
...
...
@@ -785,7 +774,7 @@ def yolo_box(op, block):
name
=
max_const_name
,
data_type
=
onnx
.
TensorProto
.
FLOAT
,
dims
=
(),
vals
=
[
MAX_FLOAT
]))
vals
=
[
MAX_FLOAT
32
]))
node_list
.
append
(
max_const
)
node_pred_box_x1_clip
=
onnx
.
helper
.
make_node
(
...
...
x2paddle/op_mapper/paddle2onnx/opset9/opset.py
浏览文件 @
98d1fd96
...
...
@@ -59,7 +59,7 @@ class OpSet9(object):
'Constant'
,
inputs
=
[],
outputs
=
[
name
],
value
=
tensor
)
return
node
def
convert_weights
(
self
,
program
):
def
convert_weights
(
self
,
program
,
scope
=
None
):
var_names
=
program
.
global_block
().
vars
nodes
=
list
()
for
name
in
var_names
:
...
...
@@ -68,7 +68,7 @@ class OpSet9(object):
continue
if
not
var
.
persistable
:
continue
weight
=
np
.
array
(
fluid
.
global_scope
()
.
find_var
(
name
).
get_tensor
())
weight
=
np
.
array
(
scope
.
find_var
(
name
).
get_tensor
())
tensor
=
helper
.
make_tensor
(
name
=
name
,
dims
=
var
.
shape
,
...
...
@@ -110,11 +110,32 @@ class OpSet9(object):
'Relu'
,
inputs
=
op
.
input
(
'X'
),
outputs
=
op
.
output
(
'Out'
))
return
node
def
tanh
(
self
,
op
,
block
):
node
=
helper
.
make_node
(
'Tanh'
,
inputs
=
op
.
input
(
'X'
),
outputs
=
op
.
output
(
'Out'
))
return
node
def
log
(
self
,
op
,
block
):
node
=
helper
.
make_node
(
'Log'
,
inputs
=
op
.
input
(
'X'
),
outputs
=
op
.
output
(
'Out'
))
return
node
def
sigmoid
(
self
,
op
,
block
):
node
=
helper
.
make_node
(
'Sigmoid'
,
inputs
=
op
.
input
(
'X'
),
outputs
=
op
.
output
(
'Out'
))
return
node
def
clip
(
self
,
op
,
block
):
min_value
=
op
.
attr
(
'min'
)
max_value
=
op
.
attr
(
'max'
)
node
=
helper
.
make_node
(
'Clip'
,
inputs
=
[
op
.
input
(
'X'
)[
0
]],
outputs
=
op
.
output
(
'Out'
),
max
=
max_value
,
min
=
min_value
)
return
node
def
exp
(
self
,
op
,
block
):
node
=
helper
.
make_node
(
'Exp'
,
inputs
=
op
.
input
(
'X'
),
outputs
=
op
.
output
(
'Out'
))
...
...
@@ -436,6 +457,14 @@ class OpSet9(object):
perm
=
op
.
attr
(
'axis'
))
return
node
def
flatten2
(
self
,
op
,
block
):
node
=
helper
.
make_node
(
'Flatten'
,
inputs
=
op
.
input
(
'X'
),
outputs
=
op
.
output
(
'Out'
),
axis
=
op
.
attr
(
'axis'
))
return
node
def
reshape2
(
self
,
op
,
block
):
input_names
=
op
.
input_names
if
len
(
op
.
input
(
'ShapeTensor'
))
>
1
:
...
...
@@ -460,7 +489,7 @@ class OpSet9(object):
inputs
=
[
op
.
input
(
'X'
)[
0
],
temp_name
],
outputs
=
op
.
output
(
'Out'
))
return
cast_shape_nodes
+
[
shape_node
,
node
]
el
se
:
el
if
len
(
op
.
input
(
'ShapeTensor'
))
==
1
:
temp_name
=
self
.
get_name
(
op
.
type
,
'shape.cast'
)
cast_shape_node
=
helper
.
make_node
(
'Cast'
,
...
...
@@ -472,6 +501,16 @@ class OpSet9(object):
inputs
=
[
op
.
input
(
'X'
)[
0
],
temp_name
],
outputs
=
op
.
output
(
'Out'
))
return
[
cast_shape_node
,
node
]
elif
op
.
attr
(
'shape'
)
is
not
None
and
len
(
op
.
attr
(
'shape'
))
>
0
:
shape_name
=
self
.
get_name
(
op
.
type
,
'shape'
)
shape_node
=
self
.
make_constant_node
(
shape_name
,
onnx_pb
.
TensorProto
.
INT64
,
op
.
attr
(
'shape'
))
reshape_node
=
helper
.
make_node
(
'Reshape'
,
inputs
=
[
op
.
input
(
'X'
)[
0
],
shape_name
],
outputs
=
op
.
output
(
'Out'
))
return
[
shape_node
,
reshape_node
]
def
dropout
(
self
,
op
,
block
):
dropout_mode
=
op
.
attr
(
'dropout_implementation'
)
...
...
@@ -506,7 +545,7 @@ class OpSet9(object):
input_shape
=
block
.
vars
[
op
.
input
(
'X'
)[
0
]].
shape
if
op
.
attr
(
'align_corners'
)
or
op
.
attr
(
'align_mode'
)
==
0
:
raise
Exception
(
"Resize in onnx(opset<=10) only support coordinate_transformation_mode: 'asymmetric'
.
"
"Resize in onnx(opset<=10) only support coordinate_transformation_mode: 'asymmetric'
, Try converting with --onnx_opest 11
"
)
if
(
'OutSize'
in
input_names
and
len
(
op
.
input
(
'OutSize'
))
>
0
)
or
(
'SizeTensor'
in
input_names
and
...
...
@@ -612,7 +651,7 @@ class OpSet9(object):
input_names
=
op
.
input_names
if
op
.
attr
(
'align_corners'
):
raise
Exception
(
"Resize in onnx(opset<=10) only support coordinate_transformation_mode: 'asymmetric'
.
"
"Resize in onnx(opset<=10) only support coordinate_transformation_mode: 'asymmetric'
, Try converting with --onnx_opest 11
"
)
if
'OutSize'
in
input_names
and
len
(
op
.
input
(
'OutSize'
))
>
0
:
node
=
helper
.
make_node
(
...
...
@@ -766,3 +805,11 @@ class OpSet9(object):
def
multiclass_nms
(
self
,
op
,
block
):
from
.paddle_custom_layer.multiclass_nms
import
multiclass_nms
return
multiclass_nms
(
op
,
block
)
def
box_coder
(
self
,
op
,
block
):
from
.paddle_custom_layer.box_coder
import
box_coder
return
box_coder
(
op
,
block
)
def
prior_box
(
self
,
op
,
block
):
from
.paddle_custom_layer.prior_box
import
prior_box
return
prior_box
(
op
,
block
)
x2paddle/op_mapper/paddle2onnx/opset9/paddle_custom_layer/box_coder.py
0 → 100644
浏览文件 @
98d1fd96
# 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.
import
sys
import
math
import
onnx
import
warnings
import
numpy
as
np
from
functools
import
partial
from
onnx
import
TensorProto
from
onnx.helper
import
make_node
,
make_tensor
from
onnx
import
onnx_pb
from
paddle.fluid.executor
import
_fetch_var
as
fetch_var
from
onnx
import
helper
import
paddle.fluid
as
fluid
import
paddle.fluid.core
as
core
def
box_coder
(
op
,
block
):
"""
In this function, we will use the decode the prior box to target box,
we just use the decode mode to transform this op.
"""
node_list
=
[]
input_names
=
op
.
input_names
prior_var
=
block
.
var
(
op
.
input
(
'PriorBox'
)[
0
])
t_size
=
block
.
var
(
op
.
input
(
'TargetBox'
)[
0
]).
shape
p_size
=
prior_var
.
shape
# get the outout_name
result_name
=
op
.
output
(
'OutputBox'
)[
0
]
# n is size of batch, m is boxes num of targe_boxes
n
=
t_size
[
0
]
m
=
t_size
[
0
]
axis
=
int
(
op
.
attr
(
'axis'
))
#norm
norm
=
bool
(
op
.
attr
(
'box_normalized'
))
name_slice_x1
=
op
.
output
(
'OutputBox'
)[
0
]
+
"@x1"
name_slice_y1
=
op
.
output
(
'OutputBox'
)[
0
]
+
"@y1"
name_slice_x2
=
op
.
output
(
'OutputBox'
)[
0
]
+
"@x2"
name_slice_y2
=
op
.
output
(
'OutputBox'
)[
0
]
+
"@y2"
#make onnx tensor to save the intermeidate reslut
name_slice_indices
=
[[
op
.
output
(
'OutputBox'
)[
0
]
+
"@slice_"
+
str
(
i
)]
for
i
in
range
(
1
,
3
)]
node_slice_indices
=
[
None
for
i
in
range
(
1
,
3
)]
# create the range(0, 4) const data to slice
for
i
in
range
(
1
,
3
):
node
=
onnx
.
helper
.
make_node
(
'Constant'
,
inputs
=
[],
outputs
=
name_slice_indices
[
i
-
1
],
value
=
onnx
.
helper
.
make_tensor
(
name
=
name_slice_indices
[
i
-
1
][
0
]
+
"@const"
,
data_type
=
onnx
.
TensorProto
.
FLOAT
,
dims
=
(),
vals
=
[
i
]))
node_list
.
append
(
node
)
# make node split data
name_box_split
=
[
name_slice_x1
,
name_slice_y1
,
name_slice_x2
,
name_slice_y2
]
split_shape
=
list
(
p_size
)
split_shape
[
-
1
]
=
1
node_split_prior_node
=
onnx
.
helper
.
make_node
(
'Split'
,
inputs
=
op
.
input
(
'PriorBox'
),
outputs
=
name_box_split
,
axis
=
1
)
node_list
.
append
(
node_split_prior_node
)
# make node get centor node for decode
final_outputs_vars
=
[]
if
not
norm
:
name_centor_w_tmp
=
[
op
.
output
(
'OutputBox'
)[
0
]
+
"@centor_w_tmp"
]
name_centor_h_tmp
=
[
op
.
output
(
'OutputBox'
)[
0
]
+
"@centor_h_tmp"
]
node_centor_w_tmp
=
None
node_centor_h_tmp
=
None
name_centor_tmp_list
=
[
name_centor_w_tmp
,
name_centor_h_tmp
]
node_centor_tmp_list
=
[
node_centor_w_tmp
,
node_centor_h_tmp
]
count
=
2
for
(
name
,
node
)
in
zip
(
name_centor_tmp_list
,
node_centor_tmp_list
):
node
=
onnx
.
helper
.
make_node
(
'Add'
,
inputs
=
[
op
.
output
(
'OutputBox'
)[
0
]
+
"@slice_"
+
str
(
1
)]
\
+
[
name_box_split
[
count
]],
outputs
=
name
)
node_list
.
append
(
node
)
count
=
count
+
1
if
not
norm
:
inputs_sub
=
[[
name_centor_w_tmp
[
0
],
name_box_split
[
0
]],
[
name_centor_h_tmp
[
0
],
name_box_split
[
1
]]]
else
:
inputs_sub
=
[[
name_box_split
[
2
],
name_box_split
[
0
]],
[
name_box_split
[
3
],
name_box_split
[
1
]]]
outputs_sub
=
[
result_name
+
"@pb_w"
,
result_name
+
"@pb_h"
]
for
i
in
range
(
0
,
2
):
node
=
onnx
.
helper
.
make_node
(
'Sub'
,
inputs
=
inputs_sub
[
i
],
outputs
=
[
outputs_sub
[
i
]])
node_list
.
append
(
node
)
# according to prior_box height and weight to get centor x, y
name_half_value
=
[
result_name
+
"@half_value"
]
node_half_value
=
onnx
.
helper
.
make_node
(
'Constant'
,
inputs
=
[],
outputs
=
name_half_value
,
value
=
onnx
.
helper
.
make_tensor
(
name
=
name_slice_indices
[
i
][
0
]
+
"@const"
,
data_type
=
onnx
.
TensorProto
.
FLOAT
,
dims
=
(),
vals
=
[
0.5
]))
node_list
.
append
(
node_half_value
)
outputs_half_wh
=
[[
result_name
+
"@pb_w_half"
],
[
result_name
+
"@pb_h_half"
]]
inputs_half_wh
=
[[
result_name
+
"@pb_w"
,
name_half_value
[
0
]],
[
result_name
+
"@pb_h"
,
name_half_value
[
0
]]]
for
i
in
range
(
0
,
2
):
node
=
onnx
.
helper
.
make_node
(
'Mul'
,
inputs
=
inputs_half_wh
[
i
],
outputs
=
outputs_half_wh
[
i
])
node_list
.
append
(
node
)
inputs_centor_xy
=
[[
outputs_half_wh
[
0
][
0
],
name_slice_x1
],
[
outputs_half_wh
[
1
][
0
],
name_slice_y1
]]
outputs_centor_xy
=
[[
result_name
+
"@pb_x"
],
[
result_name
+
"@pb_y"
]]
# final calc the centor x ,y
for
i
in
range
(
0
,
2
):
node
=
onnx
.
helper
.
make_node
(
'Add'
,
inputs
=
inputs_centor_xy
[
i
],
outputs
=
outputs_centor_xy
[
i
])
node_list
.
append
(
node
)
# reshape the data
shape
=
(
1
,
split_shape
[
0
])
if
axis
==
0
else
(
split_shape
[
0
],
1
)
# need to reshape the data
inputs_transpose_pb
=
[
[
result_name
+
"@pb_w"
],
[
result_name
+
"@pb_h"
],
[
result_name
+
"@pb_x"
],
[
result_name
+
"@pb_y"
],
]
outputs_transpose_pb
=
[
[
result_name
+
"@pb_w_transpose"
],
[
result_name
+
"@pb_h_transpose"
],
[
result_name
+
"@pb_x_transpose"
],
[
result_name
+
"@pb_y_transpose"
],
]
if
axis
==
0
:
name_reshape_pb
=
[
result_name
+
"@pb_transpose"
]
# reshape the data
for
i
in
range
(
0
,
4
):
node
=
onnx
.
helper
.
make_node
(
'Transpose'
,
inputs
=
inputs_transpose_pb
[
i
],
outputs
=
outputs_transpose_pb
[
i
])
node_list
.
append
(
node
)
# decoder the box according to the target_box and variacne
name_variance_raw
=
[
result_name
+
"@variance_raw"
]
name_variance_unsqueeze
=
[
result_name
+
"@variance_unsqueeze"
]
shape
=
[]
# make node to extend the data
var_split_axis
=
0
var_split_inputs_name
=
[]
if
'PriorBoxVar'
in
input_names
and
len
(
op
.
input
(
'PriorBoxVar'
))
>
0
:
if
axis
==
1
:
raise
Exception
(
"The op box_coder has variable do not support aixs broadcast"
)
prior_variance_var
=
block
.
var
(
op
.
input
(
'PriorBoxVar'
)[
0
])
axes
=
[]
var_split_inputs_name
=
[
result_name
+
"@variance_split"
]
node
=
onnx
.
helper
.
make_node
(
'Transpose'
,
inputs
=
op
.
input
(
'PriorBoxVar'
),
outputs
=
var_split_inputs_name
)
node_list
.
append
(
node
)
var_split_axis
=
0
else
:
variances
=
[
1.0
,
1.0
,
1.0
,
1.0
]
if
'variance'
in
op
.
attr
and
len
(
op
.
attr
(
'variance'
))
>
0
:
variances
=
[
float
(
var
)
for
var
in
op
.
attr
(
'variance'
)]
node_variance_create
=
onnx
.
helper
.
make_node
(
'Constant'
,
inputs
=
[],
outputs
=
name_variance_raw
,
value
=
onnx
.
helper
.
make_tensor
(
name
=
name_variance_raw
[
0
]
+
"@const"
,
data_type
=
onnx
.
TensorProto
.
FLOAT
,
dims
=
[
len
(
variances
)],
vals
=
variances
))
node_list
.
append
(
node_variance_create
)
var_split_axis
=
0
var_split_inputs_name
=
name_variance_raw
# decode the result
outputs_split_variance
=
[
result_name
+
"@variance_split"
+
str
(
i
)
for
i
in
range
(
0
,
4
)
]
outputs_split_targebox
=
[
result_name
+
"@targebox_split"
+
str
(
i
)
for
i
in
range
(
0
,
4
)
]
node_split_var
=
onnx
.
helper
.
make_node
(
'Split'
,
inputs
=
var_split_inputs_name
,
outputs
=
outputs_split_variance
,
axis
=
var_split_axis
)
node_split_target
=
onnx
.
helper
.
make_node
(
'Split'
,
inputs
=
op
.
input
(
'TargetBox'
),
outputs
=
outputs_split_targebox
,
axis
=
2
)
node_list
.
extend
([
node_split_var
,
node_split_target
])
outputs_squeeze_targebox
=
[
result_name
+
"@targebox_squeeze"
+
str
(
i
)
for
i
in
range
(
0
,
4
)
]
for
(
input_name
,
output_name
)
in
zip
(
outputs_split_targebox
,
outputs_squeeze_targebox
):
node
=
onnx
.
helper
.
make_node
(
'Squeeze'
,
inputs
=
[
input_name
],
outputs
=
[
output_name
],
axes
=
[
2
])
node_list
.
append
(
node
)
output_shape_step1
=
list
(
t_size
)[:
-
1
]
inputs_tb_step1
=
[
[
outputs_squeeze_targebox
[
0
],
outputs_split_variance
[
0
]],
[
outputs_squeeze_targebox
[
1
],
outputs_split_variance
[
1
]],
[
outputs_squeeze_targebox
[
2
],
outputs_split_variance
[
2
]],
[
outputs_squeeze_targebox
[
3
],
outputs_split_variance
[
3
]]
]
outputs_tb_step1
=
[[
result_name
+
"@decode_x_step1"
],
[
result_name
+
"@decode_y_step1"
],
[
result_name
+
"@decode_w_step1"
],
[
result_name
+
"@decode_h_step1"
]]
for
input_step1
,
output_step_1
in
zip
(
inputs_tb_step1
,
outputs_tb_step1
):
node
=
onnx
.
helper
.
make_node
(
'Mul'
,
inputs
=
input_step1
,
outputs
=
output_step_1
)
node_list
.
append
(
node
)
if
axis
==
0
:
inputs_tbxy_step2
=
[
[
outputs_tb_step1
[
0
][
0
],
outputs_transpose_pb
[
0
][
0
]],
[
outputs_tb_step1
[
1
][
0
],
outputs_transpose_pb
[
1
][
0
]]
]
else
:
inputs_tbxy_step2
=
[
[
outputs_tb_step1
[
0
][
0
],
inputs_transpose_pb
[
0
][
0
]],
[
outputs_tb_step1
[
1
][
0
],
inputs_transpose_pb
[
1
][
0
]]
]
outputs_tbxy_step2
=
[[
result_name
+
"@decode_x_step2"
],
[
result_name
+
"@decode_y_step2"
]]
for
input_step2
,
output_step_2
in
zip
(
inputs_tbxy_step2
,
outputs_tbxy_step2
):
node
=
onnx
.
helper
.
make_node
(
'Mul'
,
inputs
=
input_step2
,
outputs
=
output_step_2
)
node_list
.
append
(
node
)
if
axis
==
0
:
inputs_tbxy_step3
=
[
[
outputs_tbxy_step2
[
0
][
0
],
outputs_transpose_pb
[
2
][
0
]],
[
outputs_tbxy_step2
[
1
][
0
],
outputs_transpose_pb
[
3
][
0
]]
]
else
:
inputs_tbxy_step3
=
[
[
outputs_tbxy_step2
[
0
][
0
],
inputs_transpose_pb
[
2
][
0
]],
[
outputs_tbxy_step2
[
1
][
0
],
inputs_transpose_pb
[
3
][
0
]]
]
outputs_tbxy_step3
=
[[
result_name
+
"@decode_x_step3"
],
[
result_name
+
"@decode_y_step3"
]]
for
input_step3
,
output_step_3
in
zip
(
inputs_tbxy_step3
,
outputs_tbxy_step3
):
node
=
onnx
.
helper
.
make_node
(
'Add'
,
inputs
=
input_step3
,
outputs
=
output_step_3
)
node_list
.
append
(
node
)
# deal with width & height
inputs_tbwh_step2
=
[
outputs_tb_step1
[
2
],
outputs_tb_step1
[
3
]]
outputs_tbwh_step2
=
[[
result_name
+
"@decode_w_step2"
],
[
result_name
+
"@decode_h_step2"
]]
for
input_name
,
output_name
in
zip
(
inputs_tbwh_step2
,
outputs_tbwh_step2
):
node
=
onnx
.
helper
.
make_node
(
'Exp'
,
inputs
=
input_name
,
outputs
=
output_name
)
node_list
.
append
(
node
)
if
axis
==
0
:
inputs_tbwh_step3
=
[
[
outputs_tbwh_step2
[
0
][
0
],
outputs_transpose_pb
[
0
][
0
]],
[
outputs_tbwh_step2
[
1
][
0
],
outputs_transpose_pb
[
1
][
0
]]
]
else
:
inputs_tbwh_step3
=
[
[
outputs_tbwh_step2
[
0
][
0
],
inputs_transpose_pb
[
0
][
0
]],
[
outputs_tbwh_step2
[
1
][
0
],
inputs_transpose_pb
[
1
][
0
]]
]
outputs_tbwh_step3
=
[[
result_name
+
"@decode_w_step3"
],
[
result_name
+
"@decode_h_step3"
]]
for
input_name
,
output_name
in
zip
(
inputs_tbwh_step3
,
outputs_tbwh_step3
):
node
=
onnx
.
helper
.
make_node
(
'Mul'
,
inputs
=
input_name
,
outputs
=
output_name
)
node_list
.
append
(
node
)
# final step to calc the result, and concat the result to output
# return the output box, [(x1, y1), (x2, y2)]
inputs_half_tbwh_step4
=
[
[
outputs_tbwh_step3
[
0
][
0
],
result_name
+
"@slice_2"
],
[
outputs_tbwh_step3
[
1
][
0
],
result_name
+
"@slice_2"
]
]
outputs_half_tbwh_step4
=
[[
result_name
+
"@decode_half_w_step4"
],
[
result_name
+
"@decode_half_h_step4"
]]
for
inputs_name
,
outputs_name
in
zip
(
inputs_half_tbwh_step4
,
outputs_half_tbwh_step4
):
node
=
onnx
.
helper
.
make_node
(
'Div'
,
inputs
=
inputs_name
,
outputs
=
outputs_name
)
node_list
.
append
(
node
)
inputs_output_point1
=
[
[
outputs_tbxy_step3
[
0
][
0
],
outputs_half_tbwh_step4
[
0
][
0
]],
[
outputs_tbxy_step3
[
1
][
0
],
outputs_half_tbwh_step4
[
1
][
0
]]
]
outputs_output_point1
=
[[
result_name
+
"@ouput_x1"
],
[
result_name
+
"@output_y1"
]]
for
input_name
,
output_name
in
zip
(
inputs_output_point1
,
outputs_output_point1
):
node
=
onnx
.
helper
.
make_node
(
'Sub'
,
inputs
=
input_name
,
outputs
=
output_name
)
node_list
.
append
(
node
)
inputs_output_point2
=
[
[
outputs_tbxy_step3
[
0
][
0
],
outputs_half_tbwh_step4
[
0
][
0
]],
[
outputs_tbxy_step3
[
1
][
0
],
outputs_half_tbwh_step4
[
1
][
0
]]
]
outputs_output_point2
=
[[
result_name
+
"@ouput_x2"
],
[
result_name
+
"@output_y2"
]]
for
input_name
,
output_name
in
zip
(
inputs_output_point2
,
outputs_output_point2
):
node
=
onnx
.
helper
.
make_node
(
'Add'
,
inputs
=
input_name
,
outputs
=
output_name
)
node_list
.
append
(
node
)
if
not
norm
:
inputs_unnorm_point2
=
[
[
outputs_output_point2
[
0
][
0
],
result_name
+
"@slice_1"
],
[
outputs_output_point2
[
1
][
0
],
result_name
+
"@slice_1"
]
]
outputs_unnorm_point2
=
[[
result_name
+
"@ouput_unnorm_x2"
],
[
result_name
+
"@ouput_unnorm_y2"
]]
for
input_name
,
output_name
in
zip
(
inputs_unnorm_point2
,
outputs_unnorm_point2
):
node
=
onnx
.
helper
.
make_node
(
'Sub'
,
inputs
=
input_name
,
outputs
=
output_name
)
node_list
.
append
(
node
)
outputs_output_point2
=
outputs_unnorm_point2
outputs_output_point1
.
extend
(
outputs_output_point2
)
ouputs_points_unsqueeze
=
[[
result_name
+
"@points_unsqueeze_x1"
],
[
result_name
+
"points_unsqueeze_y1"
],
[
result_name
+
"points_unsqueeze_x2"
],
[
result_name
+
"points_unsqueeze_y2"
]]
for
input_name
,
output_name
in
zip
(
outputs_output_point1
,
ouputs_points_unsqueeze
):
node
=
onnx
.
helper
.
make_node
(
'Unsqueeze'
,
inputs
=
input_name
,
outputs
=
output_name
,
axes
=
[
len
(
output_shape_step1
)])
node_list
.
append
(
node
)
outputs_points_unsqueeze_list
=
[
output
[
0
]
for
output
in
ouputs_points_unsqueeze
]
node_point_final
=
onnx
.
helper
.
make_node
(
'Concat'
,
inputs
=
outputs_points_unsqueeze_list
,
outputs
=
op
.
output
(
'OutputBox'
),
axis
=
len
(
output_shape_step1
))
node_list
.
append
(
node_point_final
)
return
node_list
x2paddle/op_mapper/paddle2onnx/opset9/paddle_custom_layer/multiclass_nms.py
浏览文件 @
98d1fd96
...
...
@@ -19,7 +19,7 @@ import numpy as np
import
paddle.fluid.core
as
core
import
paddle.fluid
as
fluid
import
onnx
import
warnings
import
logging
from
onnx
import
helper
,
onnx_pb
...
...
@@ -42,9 +42,9 @@ def multiclass_nms(op, block):
background
=
attrs
[
'background_label'
]
normalized
=
attrs
[
'normalized'
]
if
normalized
==
False
:
warnings
.
warn
(
'The parameter normalized of multiclass_nms OP of Paddle is False, which has diff with ONNX.
\
Please set normalized=True in multiclass_nms of Paddle'
)
logging
.
warn
(
"The parameter normalized of multiclass_nms OP of Paddle is False, which has diff with ONNX."
\
" Please set normalized=True in multiclass_nms of Paddle, see doc Q4 in https://github.com/PaddlePaddle/X2Paddle/blob/develop/FAQ.md"
)
#convert the paddle attribute to onnx tensor
name_score_threshold
=
[
outputs
[
'Out'
][
0
]
+
"@score_threshold"
]
...
...
x2paddle/op_mapper/paddle2onnx/opset9/paddle_custom_layer/prior_box.py
0 → 100644
浏览文件 @
98d1fd96
# 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.
import
sys
import
math
import
onnx
import
warnings
import
numpy
as
np
from
functools
import
partial
from
onnx
import
TensorProto
from
onnx.helper
import
make_node
,
make_tensor
from
onnx
import
onnx_pb
from
paddle.fluid.executor
import
_fetch_var
as
fetch_var
from
onnx
import
helper
import
paddle.fluid
as
fluid
import
paddle.fluid.core
as
core
def
ExpandAspectRations
(
input_aspect_ratior
,
flip
):
expsilon
=
1e-6
output_ratios
=
[
1.0
]
for
input_ratio
in
input_aspect_ratior
:
already_exis
=
False
for
output_ratio
in
output_ratios
:
if
abs
(
input_ratio
-
output_ratio
)
<
expsilon
:
already_exis
=
True
break
if
already_exis
==
False
:
output_ratios
.
append
(
input_ratio
)
if
flip
:
output_ratios
.
append
(
1.0
/
input_ratio
)
return
output_ratios
def
prior_box
(
op
,
block
):
"""
In this function, use the attribute to get the prior box, because we do not use
the image data and feature map, wo could the python code to create the varaible,
and to create the onnx tensor as output.
"""
flip
=
bool
(
op
.
attr
(
'flip'
))
clip
=
bool
(
op
.
attr
(
'clip'
))
min_max_aspect_ratios_order
=
bool
(
op
.
attr
(
'min_max_aspect_ratios_order'
))
min_sizes
=
[
float
(
size
)
for
size
in
op
.
attr
(
'min_sizes'
)]
max_sizes
=
[
float
(
size
)
for
size
in
op
.
attr
(
'max_sizes'
)]
if
isinstance
(
op
.
attr
(
'aspect_ratios'
),
list
):
aspect_ratios
=
[
float
(
ratio
)
for
ratio
in
op
.
attr
(
'aspect_ratios'
)]
else
:
aspect_ratios
=
[
float
(
op
.
attr
(
'aspect_ratios'
))]
variances
=
[
float
(
var
)
for
var
in
op
.
attr
(
'variances'
)]
# set min_max_aspect_ratios_order = false
output_ratios
=
ExpandAspectRations
(
aspect_ratios
,
flip
)
step_w
=
float
(
op
.
attr
(
'step_w'
))
step_h
=
float
(
op
.
attr
(
'step_h'
))
offset
=
float
(
op
.
attr
(
'offset'
))
input_shape
=
block
.
var
(
op
.
input
(
'Input'
)[
0
]).
shape
image_shape
=
block
.
var
(
op
.
input
(
'Image'
)[
0
]).
shape
img_width
=
image_shape
[
3
]
img_height
=
image_shape
[
2
]
feature_width
=
input_shape
[
3
]
feature_height
=
input_shape
[
2
]
step_width
=
1.0
step_height
=
1.0
if
step_w
==
0.0
or
step_h
==
0.0
:
step_w
=
float
(
img_width
/
feature_width
)
step_h
=
float
(
img_height
/
feature_height
)
num_priors
=
len
(
output_ratios
)
*
len
(
min_sizes
)
if
len
(
max_sizes
)
>
0
:
num_priors
+=
len
(
max_sizes
)
out_dim
=
(
feature_height
,
feature_width
,
num_priors
,
4
)
out_boxes
=
np
.
zeros
(
out_dim
).
astype
(
'float32'
)
out_var
=
np
.
zeros
(
out_dim
).
astype
(
'float32'
)
idx
=
0
for
h
in
range
(
feature_height
):
for
w
in
range
(
feature_width
):
c_x
=
(
w
+
offset
)
*
step_w
c_y
=
(
h
+
offset
)
*
step_h
idx
=
0
for
s
in
range
(
len
(
min_sizes
)):
min_size
=
min_sizes
[
s
]
if
not
min_max_aspect_ratios_order
:
# rest of priors
for
r
in
range
(
len
(
output_ratios
)):
ar
=
output_ratios
[
r
]
c_w
=
min_size
*
math
.
sqrt
(
ar
)
/
2
c_h
=
(
min_size
/
math
.
sqrt
(
ar
))
/
2
out_boxes
[
h
,
w
,
idx
,
:]
=
[
(
c_x
-
c_w
)
/
img_width
,
(
c_y
-
c_h
)
/
img_height
,
(
c_x
+
c_w
)
/
img_width
,
(
c_y
+
c_h
)
/
img_height
]
idx
+=
1
if
len
(
max_sizes
)
>
0
:
max_size
=
max_sizes
[
s
]
# second prior: aspect_ratio = 1,
c_w
=
c_h
=
math
.
sqrt
(
min_size
*
max_size
)
/
2
out_boxes
[
h
,
w
,
idx
,
:]
=
[
(
c_x
-
c_w
)
/
img_width
,
(
c_y
-
c_h
)
/
img_height
,
(
c_x
+
c_w
)
/
img_width
,
(
c_y
+
c_h
)
/
img_height
]
idx
+=
1
else
:
c_w
=
c_h
=
min_size
/
2.
out_boxes
[
h
,
w
,
idx
,
:]
=
[
(
c_x
-
c_w
)
/
img_width
,
(
c_y
-
c_h
)
/
img_height
,
(
c_x
+
c_w
)
/
img_width
,
(
c_y
+
c_h
)
/
img_height
]
idx
+=
1
if
len
(
max_sizes
)
>
0
:
max_size
=
max_sizes
[
s
]
# second prior: aspect_ratio = 1,
c_w
=
c_h
=
math
.
sqrt
(
min_size
*
max_size
)
/
2
out_boxes
[
h
,
w
,
idx
,
:]
=
[
(
c_x
-
c_w
)
/
img_width
,
(
c_y
-
c_h
)
/
img_height
,
(
c_x
+
c_w
)
/
img_width
,
(
c_y
+
c_h
)
/
img_height
]
idx
+=
1
# rest of priors
for
r
in
range
(
len
(
output_ratios
)):
ar
=
output_ratios
[
r
]
if
abs
(
ar
-
1.
)
<
1e-6
:
continue
c_w
=
min_size
*
math
.
sqrt
(
ar
)
/
2
c_h
=
(
min_size
/
math
.
sqrt
(
ar
))
/
2
out_boxes
[
h
,
w
,
idx
,
:]
=
[
(
c_x
-
c_w
)
/
img_width
,
(
c_y
-
c_h
)
/
img_height
,
(
c_x
+
c_w
)
/
img_width
,
(
c_y
+
c_h
)
/
img_height
]
idx
+=
1
if
clip
:
out_boxes
=
np
.
clip
(
out_boxes
,
0.0
,
1.0
)
# set the variance.
out_var
=
np
.
tile
(
variances
,
(
feature_height
,
feature_width
,
num_priors
,
1
))
#make node that
node_boxes
=
onnx
.
helper
.
make_node
(
'Constant'
,
inputs
=
[],
outputs
=
op
.
output
(
'Boxes'
),
value
=
onnx
.
helper
.
make_tensor
(
name
=
op
.
output
(
'Boxes'
)[
0
]
+
"@const"
,
data_type
=
onnx
.
TensorProto
.
FLOAT
,
dims
=
out_boxes
.
shape
,
vals
=
out_boxes
.
flatten
()))
node_vars
=
onnx
.
helper
.
make_node
(
'Constant'
,
inputs
=
[],
outputs
=
op
.
output
(
'Variances'
),
value
=
onnx
.
helper
.
make_tensor
(
name
=
op
.
output
(
'Variances'
)[
0
]
+
"@const"
,
data_type
=
onnx
.
TensorProto
.
FLOAT
,
dims
=
out_var
.
shape
,
vals
=
out_var
.
flatten
()))
return
[
node_boxes
,
node_vars
]
x2paddle/op_mapper/paddle2onnx/opset9/paddle_custom_layer/yolo_box.py
浏览文件 @
98d1fd96
...
...
@@ -16,6 +16,9 @@ import onnx
import
numpy
as
np
from
onnx
import
onnx_pb
,
helper
MAX_FLOAT32
=
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
)
...
...
@@ -30,6 +33,13 @@ def get_old_name(arg, name_prefix=''):
return
name_prefix
+
last_prefix
def
is_static_shape
(
shape
):
if
len
(
shape
)
>
1
and
shape
.
count
(
-
1
)
>
1
:
raise
Exception
(
"Converting this model to ONNX need with static input shape, please fix input shape of this model, see doc Q5 in https://github.com/PaddlePaddle/X2Paddle/blob/develop/FAQ.md."
)
def
yolo_box
(
op
,
block
):
inputs
=
dict
()
outputs
=
dict
()
...
...
@@ -42,6 +52,7 @@ def yolo_box(op, block):
attrs
[
name
]
=
op
.
attr
(
name
)
model_name
=
outputs
[
'Boxes'
][
0
]
input_shape
=
block
.
vars
[
get_old_name
(
inputs
[
'X'
][
0
])].
shape
is_static_shape
(
input_shape
)
image_size
=
inputs
[
'ImgSize'
]
input_height
=
input_shape
[
2
]
input_width
=
input_shape
[
3
]
...
...
@@ -766,7 +777,7 @@ def yolo_box(op, block):
inputs
=
outputs_pred_box_x1_decode
,
outputs
=
outputs_pred_box_x1_clip
,
min
=
0.0
,
max
=
float
(
np
.
inf
))
max
=
float
(
MAX_FLOAT32
))
node_list
.
append
(
node_pred_box_x1_clip
)
node_pred_box_y1_clip
=
onnx
.
helper
.
make_node
(
...
...
@@ -774,7 +785,7 @@ def yolo_box(op, block):
inputs
=
outputs_pred_box_y1_decode
,
outputs
=
outputs_pred_box_y1_clip
,
min
=
0.0
,
max
=
float
(
np
.
inf
))
max
=
float
(
MAX_FLOAT32
))
node_list
.
append
(
node_pred_box_y1_clip
)
node_pred_box_x2_clip
=
onnx
.
helper
.
make_node
(
...
...
@@ -782,7 +793,7 @@ def yolo_box(op, block):
inputs
=
outputs_pred_box_x2_sub_w
,
outputs
=
outputs_pred_box_x2_clip
,
min
=
0.0
,
max
=
float
(
np
.
inf
))
max
=
float
(
MAX_FLOAT32
))
node_list
.
append
(
node_pred_box_x2_clip
)
node_pred_box_y2_clip
=
onnx
.
helper
.
make_node
(
...
...
@@ -790,7 +801,7 @@ def yolo_box(op, block):
inputs
=
outputs_pred_box_y2_sub_h
,
outputs
=
outputs_pred_box_y2_clip
,
min
=
0.0
,
max
=
float
(
np
.
inf
))
max
=
float
(
MAX_FLOAT32
))
node_list
.
append
(
node_pred_box_y2_clip
)
outputs_pred_box_x2_res
=
[
model_name
+
"@box_x2_res"
]
...
...
x2paddle/op_mapper/paddle2onnx/paddle_op_mapper.py
浏览文件 @
98d1fd96
...
...
@@ -33,9 +33,9 @@ class PaddleOpMapper(object):
self
.
name_counter
=
dict
()
self
.
op_set
=
None
def
convert
(
self
,
program
,
save_dir
,
opset_number
=
10
):
self
.
op_set
=
self
.
create_opset
(
opset_
number
)
weight_nodes
=
self
.
op_set
.
convert_weights
(
program
)
def
convert
(
self
,
program
,
save_dir
,
scope
=
None
,
opset_version
=
10
):
self
.
op_set
=
self
.
create_opset
(
opset_
version
)
weight_nodes
=
self
.
op_set
.
convert_weights
(
program
,
scope
=
scope
)
op_nodes
=
list
()
input_nodes
=
list
()
output_nodes
=
list
()
...
...
@@ -77,7 +77,7 @@ class PaddleOpMapper(object):
initializer
=
[],
inputs
=
input_nodes
,
outputs
=
output_nodes
)
opset_imports
=
[
helper
.
make_opsetid
(
""
,
opset_
number
)]
opset_imports
=
[
helper
.
make_opsetid
(
""
,
opset_
version
)]
model
=
helper
.
make_model
(
graph
,
producer_name
=
'X2Paddle'
,
opset_imports
=
opset_imports
)
onnx
.
checker
.
check_model
(
model
)
...
...
@@ -89,20 +89,20 @@ class PaddleOpMapper(object):
print
(
"
\n
Translated model saved in {}"
.
format
(
os
.
path
.
join
(
save_dir
,
'x2paddle_model.onnx'
)))
def
create_opset
(
self
,
opset_
number
):
def
create_opset
(
self
,
opset_
version
=
10
):
run_opset
=
self
.
default_opset
opset
=
''
if
opset_
number
in
self
.
support_opsets
:
run_opset
=
opset_
number
if
opset_
version
in
self
.
support_opsets
:
run_opset
=
opset_
version
else
:
for
support_opset_
number
in
self
.
support_opsets
:
if
support_opset_
number
<
opset_number
:
run_opset
=
support_opset_
number
for
support_opset_
version
in
self
.
support_opsets
:
if
support_opset_
version
<
opset_version
:
run_opset
=
support_opset_
version
else
:
break
print
(
'Now, onnx2paddle support convert onnx model opset_verison {},'
'opset_verison of your onnx model is {}, automatically treated as op_set: {}.'
.
format
(
self
.
support_opsets
,
opset_
number
,
run_opset
))
.
format
(
self
.
support_opsets
,
opset_
version
,
run_opset
))
opset
=
'OpSet'
+
str
(
run_opset
)
return
eval
(
opset
)()
x2paddle_model_zoo.md
浏览文件 @
98d1fd96
...
...
@@ -33,6 +33,8 @@
| MobileNet_V1 |
[
code
](
https://github.com/shicai/MobileNet-Caffe
)
|
| MobileNet_V2 |
[
code
](
https://github.com/shicai/MobileNet-Caffe
)
|
| ShuffleNet_v2 |
[
code
](
https://github.com/miaow1988/ShuffleNet_V2_pytorch_caffe/releases/tag/v0.1.0
)
|
| InceptionV3 |
[
code
](
https://github.com/soeaver/caffe-model/blob/master/cls/inception/
)
|
| InceptionV4 |
[
code
](
https://github.com/soeaver/caffe-model/blob/master/cls/inception/
)
|
| mNASNet |
[
code
](
https://github.com/LiJianfei06/MnasNet-caffe
)
|
| MTCNN |
[
code
](
https://github.com/kpzhang93/MTCNN_face_detection_alignment/tree/master/code/codes/MTCNNv1/model
)
|
| Mobilenet_SSD |
[
code
](
https://github.com/chuanqi305/MobileNet-SSD
)
|
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录