Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
X2Paddle
提交
9eaa7470
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看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
9eaa7470
编写于
4月 26, 2019
作者:
J
Jason
提交者:
GitHub
4月 26, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #22 from MacroBull/master
minor tweaks and update of README
上级
ab8c3854
a538420a
变更
16
显示空白变更内容
内联
并排
Showing
16 changed file
with
214 addition
and
201 deletion
+214
-201
README.md
README.md
+1
-1
onnx2fluid/README.md
onnx2fluid/README.md
+61
-38
onnx2fluid/README_en.md
onnx2fluid/README_en.md
+45
-9
onnx2fluid/examples/convert_data_pb_0.py
onnx2fluid/examples/convert_data_pb_0.py
+1
-3
onnx2fluid/examples/gen_some_samples.py
onnx2fluid/examples/gen_some_samples.py
+2
-3
onnx2fluid/examples/gen_unet.py
onnx2fluid/examples/gen_unet.py
+0
-4
onnx2fluid/examples/gen_yolov2.py
onnx2fluid/examples/gen_yolov2.py
+0
-4
onnx2fluid/examples/onnx_model_zoo.sh
onnx2fluid/examples/onnx_model_zoo.sh
+2
-2
onnx2fluid/onnx2fluid/__main__.py
onnx2fluid/onnx2fluid/__main__.py
+12
-15
onnx2fluid/onnx2fluid/cmdline.py
onnx2fluid/onnx2fluid/cmdline.py
+17
-38
onnx2fluid/onnx2fluid/conversion.py
onnx2fluid/onnx2fluid/conversion.py
+19
-21
onnx2fluid/onnx2fluid/symbolic.py
onnx2fluid/onnx2fluid/symbolic.py
+21
-21
onnx2fluid/onnx2fluid/validation.py
onnx2fluid/onnx2fluid/validation.py
+26
-17
onnx2fluid/onnx2fluid/writer.py
onnx2fluid/onnx2fluid/writer.py
+5
-23
onnx2fluid/requirements.txt
onnx2fluid/requirements.txt
+1
-1
onnx2fluid/setup.cfg
onnx2fluid/setup.cfg
+1
-1
未找到文件。
README.md
浏览文件 @
9eaa7470
...
...
@@ -18,7 +18,7 @@ X2Paddle支持将Caffe和TensorFlow模型转至PaddlePaddle模型,同时我们
## [onnx2fluid](onnx2fluid)
1.
支持将ONNX模型转至PaddlePaddle fluid可加载预测模型
2.
Py
t
orch支持导出为ONNX模型,因此也可通过onnx2fluid支持PyTorch模型的转换
2.
Py
T
orch支持导出为ONNX模型,因此也可通过onnx2fluid支持PyTorch模型的转换
# 贡献代码
clone代码至本地后,先运行
`X2Paddle/commit-prepare.sh`
配置代码提交环境
onnx2fluid/README.md
浏览文件 @
9eaa7470
...
...
@@ -2,59 +2,82 @@
[
![License
](
https://img.shields.io/badge/license-Apache%202-blue.svg
)
](LICENSE)
onnx2fluid支持将
onnx模型转换为PaddlePaddle模型,并用于预测,用户也可以通过将Pytorch模型导出为ONNX格式
模型,再使用onnx2fluid将模型转为PaddlePaddle模型。
onnx2fluid支持将
ONNX模型转换为PaddlePaddle模型,并用于预测,用户也可以通过将PyTorch模型导出为ONNX
模型,再使用onnx2fluid将模型转为PaddlePaddle模型。
##
环境安装
##
特色
工具开发过程中,我们在如下环境配置中测试模型转换:
*
导出Python代码和fluid ProgramDesc模型
*
权重可嵌入支持的算子中
*
转换验证打包三合一
*
转换过程不依赖PaddlePaddle
*
可自由扩展算子
*
python3.5+
*
onnx == 1.4.0
*
paddlepaddle == 1.3.0
## 环境配置
在如下环境配置中测试成功:
建议使用
[
anaconda
](
https://docs.anaconda.com/anaconda/install
)
:
*
python 3.5+
*
onnx == 1.4.0
*
paddlepaddle == 1.3.0 (可选,仅用于验证)
使用
[
Anaconda
](
https://docs.anaconda.com/anaconda/install
)
:
```
shell
# 安装onnx
# 也可参考https://github.com/onnx/onnx
conda
install
-c
conda-forge onnx
pip
install
paddlepaddle
==
1.3.0
```
## 使用说明
```
shell
# 安装
git clone https://github.com/PaddlePaddle/X2Paddle.git
cd
X2Paddle/onnx2fluid
## 动手玩
测试ONNX官方预训练模型,包含alexnet, googlenet, caffenet, rcnn
inception_v1, inception_v2, resnet50, shufflenet, squeezenet,
vgg19, zfnet512等:
```
shell
python setup.py
install
cd
examples
sh onnx_model_zoo.sh
```
# 模型转换
python
-m
onnx2fluid
-o
/path/to/export_dir/ /path/of/onnx/model.onnx
使用PyTorch搭建模型,导出ONNX,转换并验证:
```
shell
python setup.py
install
cd
examples
python gen_some_samples.py
onnx2fluid sample_1.onnx
-t
sample_1.npz
```
**示例:VGG19模型**
## 使用说明
onnx2fluid:
```
shell
wget https://s3.amazonaws.com/download.onnx/models/opset_9/vgg19.tar.gz
tar
xzvf vgg19.tar.gz
onnx2fluid
[
-dexy
]
[
-o
/path/to/export_dir/]
[
-z
archive.zip]
[
-t
test_data.npz] /path/to/onnx/model.onnx
python
-m
onnx2fluid
-o
paddle_model vgg19/model.onnx
optional arguments:
--debug
,
-d
启用调试
--embed_params
,
-e
尝试权重内嵌
--no-pedantic
,
-x
转换扩展的ONNX算子
--skip-version-conversion
,
-y
跳过ONNX算子版本转换
--output_dir
,
-o
指定输出目录
--archive
[
ARCHIVE],
-z
[
ARCHIVE]
如果验证通过,打包到指定的ZIP文件
```
转换后的PaddlePaddle模型加载可参考文档
[
加载预测模型
](
http://www.paddlepaddle.org/documentation/docs/zh/1.3/api_guides/low_level/inference.html#id4
)
## 模型测试
目录
[
examples
](
examples
)
中集成了部分ONNX预训练模型的转换测试
转换工具onnx2fluid.conversion:
```
shell
cd
examples
# 测试和验证各onnx模型的转换
sh onnx_model_zoo.sh
onnx2fluid.conversion
[
-dexy
]
[
-o
/path/to/export_dir/] /path/to/onnx/model.onnx
```
目前测试脚本中已包含的测试模型如下,
1.
[
bvlc_alexnet
](
https://s3.amazonaws.com/download.onnx/models/opset_9/bvlc_alexnet.tar.gz
)
2.
[
bvlc_googlenet
](
https://s3.amazonaws.com/download.onnx/models/opset_9/bvlc_googlenet.tar.gz
)
3.
[
bvlc_reference_caffenet
](
https://s3.amazonaws.com/download.onnx/models/opset_9/bvlc_reference_caffenet.tar.gz
)
4.
[
bvlc_reference_rcnn_ilsvrc13
](
https://s3.amazonaws.com/download.onnx/models/opset_9/bvlc_reference_rcnn_ilsvrc13.tar.gz
)
5.
[
inception_v1
](
https://s3.amazonaws.com/download.onnx/models/opset_9/inception_v1.tar.gz
)
6.
[
inception_v2
](
https://s3.amazonaws.com/download.onnx/models/opset_9/inception_v2.tar.gz
)
7.
[
resnet50
](
https://s3.amazonaws.com/download.onnx/models/opset_9/resnet50.tar.gz
)
8.
[
shufflenet
](
https://s3.amazonaws.com/download.onnx/models/opset_9/shufflenet.tar.gz
)
9.
[
squeezenet
](
https://s3.amazonaws.com/download.onnx/models/opset_9/squeezenet.tar.gz
)
10.
[
vgg19
](
https://s3.amazonaws.com/download.onnx/models/opset_9/vgg19.tar.gz
)
11.
[
zfnet512
](
https://s3.amazonaws.com/download.onnx/models/opset_9/zfnet512.tar.gz
)
验证工具onnx2fluid.validate:
```
shell
onnx2fluid.validate
[
-d
]
[
-t
test_data.npz]
[
-p
1e-3] /path/to/onnx/model.onnx
```
## 参考
*
PaddlePaddle
[
算子
](
http://www.paddlepaddle.org/documentation/docs/zh/1.4/api_cn/layers_cn.html
)
*
PaddlePaddle
[
加载预测模型
](
http://www.paddlepaddle.org/documentation/docs/zh/1.4/api_guides/low_level/inference.html#id4
)
onnx2fluid/README_en.md
浏览文件 @
9eaa7470
...
...
@@ -2,13 +2,25 @@
[
![License
](
https://img.shields.io/badge/license-Apache%202-blue.svg
)
](LICENSE)
onnx2fluid supports converting ONNX model to PaddlePaddle
Model for prediction.
onnx2fluid supports converting ONNX model to PaddlePaddle
fluid model for prediction.
## Running Environment
PyTorch to Paddlepaddle model conversion can be easily achieved with PyTorch ONNX export functions.
*
python3.5+ (python2 working in progress)
## Features
*
Python code + ProgramDesc proto generation, flexible and compatible
*
fluid layer weight embedding support
*
conversion, validation, archiving all in one
*
convert without PaddlePaddle dependency
*
export and validation helper functions for PyTorch to PaddlePaddle conversion
*
extra ONNX operator optimization for inference
*
easily extensible for user-defined operators
## Environment and dependency
*
python 3.5+ (python 2 not fully supported yet)
*
onnx == 1.4.0
*
paddlepaddle == 1.3.0
*
paddlepaddle == 1.3.0
(optional for validation)
## Get started
...
...
@@ -20,26 +32,50 @@ cd examples
sh onnx_model_zoo.sh
```
Try exporting
from PyTorch to
Paddle fluid:
Try exporting
and validating from PyTorch to Paddle
Paddle fluid:
```
shell
python setup.py
install
cd
examples
python gen_some_samples.py
onnx2fluid sample_1.onnx
-t
sample_1.npz
python gen_unet.py
onnx2fluid sample_unet.onnx
-t
sample_unet.npz
```
## Usage
onnx2fluid (all in one):
```
shell
onnx2fluid
[
-dexy
]
-o
/path/to/export_dir/ /path/of
/onnx/model.onnx
onnx2fluid
[
-dexy
]
[
-o
/path/to/export_dir/]
[
-z
archive.zip]
[
-t
test_data.npz] /path/to
/onnx/model.onnx
optional arguments:
--embed_params
,
-e
try to embed parameters
for
trainable Paddle fluid layers
--debug
,
-d
enable
debug logging and checking
--embed_params
,
-e
try to embed parameters
for
trainable PaddlePaddle fluid layers
--no-pedantic
,
-x
process non-standard ONNX ops
--skip-version-conversion
,
-y
skip ONNX op version conversion, workaround
for
RumtimeErrors
skip ONNX op version conversion, workaround
for
RumtimeErrors
--output_dir
,
-o
output directory
--archive
[
ARCHIVE],
-z
[
ARCHIVE]
compress outputs to ZIP file
if
conversion successed
```
onnx2fluid.conversion:
```
shell
onnx2fluid.conversion
[
-dexy
]
[
-o
/path/to/export_dir/] /path/to/onnx/model.onnx
```
onnx2fluid.validate:
```
shell
onnx2fluid.validate
[
-d
]
[
-t
test_data.npz]
[
-p
1e-3] /path/to/onnx/model.onnx
```
## Reference
*
[
PaddlePaddle fluid operators
](
http://www.paddlepaddle.org/documentation/docs/en/1.4/api/layers.html
)
*
load converted model via
[
load_inference_model
](
http://www.paddlepaddle.org/documentation/docs/en/1.4/api/io.html#permalink-1-load_inference_model
)
onnx2fluid/examples/convert_data_pb_0.py
浏览文件 @
9eaa7470
...
...
@@ -6,9 +6,7 @@ Created on Wed Mar 27 11:50:03 2019
@author: Macrobull
"""
# import os, sys
import
os
import
sys
import
os
,
sys
import
numpy
as
np
import
onnx
import
onnx.numpy_helper
as
numpy_helper
...
...
onnx2fluid/examples/gen_some_samples.py
浏览文件 @
9eaa7470
...
...
@@ -5,9 +5,8 @@ Created on Fri Mar 22 11:19:45 2019
@author: Macrobull
Not all ops in this file are supported by both Pytorch and ONNX
This only demostrates the conversion/validation workflow from Pytorch to ONNX to Paddle fluid
Not all ops in this file are supported by both PyTorch and ONNX
This only demostrates the conversion/validation workflow from PyTorch to ONNX to Paddle fluid
"""
from
__future__
import
print_function
...
...
onnx2fluid/examples/gen_unet.py
浏览文件 @
9eaa7470
...
...
@@ -4,10 +4,6 @@
Created on Fri Mar 22 11:19:45 2019
@author: Macrobull
Not all ops in this file are supported by both Pytorch and ONNX
This only demostrates the conversion/validation workflow from Pytorch to ONNX to Paddle fluid
"""
from
__future__
import
print_function
...
...
onnx2fluid/examples/gen_yolov2.py
浏览文件 @
9eaa7470
...
...
@@ -4,10 +4,6 @@
Created on Fri Mar 22 11:19:45 2019
@author: Macrobull
Not all ops in this file are supported by both Pytorch and ONNX
This only demostrates the conversion/validation workflow from Pytorch to ONNX to Paddle fluid
"""
from
__future__
import
print_function
...
...
onnx2fluid/examples/onnx_model_zoo.sh
浏览文件 @
9eaa7470
...
...
@@ -97,8 +97,8 @@ bvlc_reference_rcnn_ilsvrc13()
do
echo
"converting
$pb_dir
"
python convert_data_pb_0.py
"
$pb_dir
"
data_0 fc-rcnn_1
python
-m
onnx2fluid.validation
$validate_flags1
-t
$(
dirname
"
$pb_dir
/x"
)
.npz
-p
0
python
-m
onnx2fluid.validation
$validate_flags2
-t
$(
dirname
"
$pb_dir
/x"
)
.npz
-p
0
python
-m
onnx2fluid.validation
$validate_flags1
-t
$(
dirname
"
$pb_dir
/x"
)
.npz
python
-m
onnx2fluid.validation
$validate_flags2
-t
$(
dirname
"
$pb_dir
/x"
)
.npz
done
}
...
...
onnx2fluid/onnx2fluid/__main__.py
浏览文件 @
9eaa7470
...
...
@@ -16,10 +16,7 @@ from __future__ import division
from
__future__
import
print_function
from
__future__
import
unicode_literals
# import argparse, logging, sys
import
argparse
import
logging
import
sys
import
argparse
,
logging
,
sys
parser
=
argparse
.
ArgumentParser
(
description
=
'onnx2fluid'
,
...
...
@@ -86,11 +83,17 @@ parser.add_argument(
help
=
'compress outputs to ZIP file if conversion successed'
,
)
parser
.
add_argument
(
'--
precision
'
,
'--
atol
'
,
'-p'
,
type
=
int
,
default
=
3
,
help
=
'assertion decimal for validation'
,
type
=
float
,
default
=
1e-3
,
help
=
'assertion absolute tolerance for validation'
,
)
parser
.
add_argument
(
'--rtol'
,
type
=
float
,
default
=
1e-4
,
help
=
'assertion relative tolerance for validation'
,
)
args
=
parser
.
parse_args
()
...
...
@@ -98,12 +101,6 @@ logging_format = '[%(levelname)8s]%(name)s::%(funcName)s:%(lineno)04d: %(message
logging_level
=
logging
.
DEBUG
if
args
.
debug
else
logging
.
INFO
logging
.
basicConfig
(
format
=
logging_format
,
level
=
logging_level
)
try
:
from
.
import
cmdline
except
ImportError
:
import
cmdline
# imports
main
=
cmdline
.
main
from
.cmdline
import
main
sys
.
exit
(
main
(
**
args
.
__dict__
))
onnx2fluid/onnx2fluid/cmdline.py
浏览文件 @
9eaa7470
...
...
@@ -17,9 +17,6 @@ from __future__ import print_function
from
__future__
import
unicode_literals
import
logging
,
shutil
,
zipfile
#import logging
#import shutil
#import zipfile
__all__
=
[
'main'
,
...
...
@@ -33,31 +30,23 @@ DEFAULT_MODEL_FUNC = 'inference'
def
main
(
**
kwargs
):
"""主程序入口"""
try
:
from
.
import
conversion
except
ImportError
:
import
conversion
# imports
convert
=
conversion
.
convert
from
.conversion
import
convert
logger
=
logging
.
getLogger
(
'onnx2fluid'
)
debug
=
kwargs
.
get
(
'debug'
,
False
)
#
debug = kwargs.get('debug', False)
# prepare arguments
filename
=
kwargs
[
'model'
]
[
0
]
filename
=
kwargs
.
pop
(
'model'
)
[
0
]
basepath
,
_
=
shutil
.
os
.
path
.
splitext
(
filename
)
save_dir
=
kwargs
.
get
(
'output_dir'
,
''
)
save_dir
=
kwargs
.
pop
(
'output_dir'
,
''
)
# model.onnx -> model/
save_dir
=
(
save_dir
.
rstrip
(
shutil
.
os
.
sep
)
if
save_dir
else
basepath
)
+
shutil
.
os
.
sep
model_basename
=
DEFAULT_MODEL_MODULE
+
'.py'
model_func_name
=
DEFAULT_MODEL_FUNC
embed_params
=
kwargs
.
get
(
'embed_params'
,
False
)
onnx_opset_version
=
DEFAULT_ONNX_OPSET_VERSION
onnx_opset_pedantic
=
kwargs
.
get
(
'pedantic'
,
True
)
onnx_skip_version_conversion
=
kwargs
.
get
(
'skip_version_conversion'
,
False
)
archive
=
kwargs
.
get
(
'archive'
,
None
)
onnx_opset_pedantic
=
kwargs
.
pop
(
'pedantic'
,
True
)
onnx_skip_version_conversion
=
kwargs
.
pop
(
'skip_version_conversion'
,
False
)
# convert
convert
(
...
...
@@ -65,49 +54,35 @@ def main(**kwargs):
save_dir
,
model_basename
=
model_basename
,
model_func_name
=
model_func_name
,
embed_params
=
embed_params
,
onnx_opset_version
=
onnx_opset_version
,
onnx_opset_pedantic
=
onnx_opset_pedantic
,
onnx_skip_version_conversion
=
onnx_skip_version_conversion
,
debug
=
debug
)
**
kwargs
)
# validate
passed
=
True
golden_data_filename
=
kwargs
.
get
(
'test_data'
,
''
)
golden_data_filename
=
kwargs
.
pop
(
'test_data'
,
''
)
if
golden_data_filename
:
try
:
from
.
import
validation
except
ImportError
:
import
validation
# imports
validate
=
validation
.
validate
# in fact fluid can not fully clear the context
# continuous validation may be inaccurate
decimal
=
kwargs
.
get
(
'precision'
,
3
)
from
.validation
import
validate
logger
.
info
(
'starting validation on desc ...'
)
passed
&=
validate
(
shutil
.
os
.
path
.
join
(
save_dir
,
'__model__'
),
golden_data_filename
,
decimal
=
decimal
,
)
shutil
.
os
.
path
.
join
(
save_dir
,
'__model__'
),
golden_data_filename
,
**
kwargs
)
logger
.
info
(
'starting validation on code ...'
)
passed
&=
validate
(
shutil
.
os
.
path
.
join
(
save_dir
,
model_basename
),
golden_data_filename
,
model_func_name
=
model_func_name
,
decimal
=
decimal
,
save_inference_model
=
debug
,
# this overwrite desc file for test
)
**
kwargs
)
if
not
passed
:
logger
.
error
(
'validation failed, exit'
)
return
# create zip file
archive
=
kwargs
.
pop
(
'archive'
,
None
)
if
archive
is
not
None
:
if
archive
==
''
:
archive
=
save_dir
.
rstrip
(
shutil
.
os
.
sep
)
+
'.zip'
...
...
@@ -132,6 +107,10 @@ if __name__ == '__main__':
level
=
logging
.
DEBUG
,
)
del
main
from
onnx2fluid.cmdline
import
main
main
(
model
=
[
'../examples/t1.onnx'
],
output_dir
=
'/tmp/export/'
,
...
...
onnx2fluid/onnx2fluid/conversion.py
浏览文件 @
9eaa7470
...
...
@@ -9,8 +9,6 @@ Created on Mon Feb 25 09:50:35 2019
from
__future__
import
division
import
logging
,
shutil
#import logging
#import shutil
__all__
=
[
'convert'
,
...
...
@@ -25,7 +23,8 @@ def convert(onnx_model_filename,
onnx_opset_version
=
9
,
onnx_opset_pedantic
=
True
,
onnx_skip_version_conversion
=
False
,
debug
=
False
):
debug
=
False
,
**
kwargs
):
"""
convert an ONNX model to Paddle fluid Python code and desc pb
"""
...
...
@@ -37,21 +36,14 @@ def convert(onnx_model_filename,
from
onnx.utils
import
polish_model
from
onnx.version_converter
import
convert_version
try
:
from
.
import
onnx_utils
,
writer
except
ImportError
:
import
onnx_utils
,
writer
# imports
DEFAULT_OP_DOMAIN
=
onnx_utils
.
DEFAULT_OP_DOMAIN
graph_ops
,
graph_weights
=
onnx_utils
.
graph_ops
,
onnx_utils
.
graph_weights
inferred_model_value_info
=
onnx_utils
.
inferred_model_value_info
optimize_model_skip_op_for_inference
=
onnx_utils
.
optimize_model_skip_op_for_inference
optimize_model_strip_initializer
=
onnx_utils
.
optimize_model_strip_initializer
optimize_model_cast
=
onnx_utils
.
optimize_model_cast
optimize_model_slice
=
onnx_utils
.
optimize_model_slice
Program
,
Writer
=
writer
.
Program
,
writer
.
Writer
make_var_name
=
writer
.
make_var_name
from
.onnx_utils
import
DEFAULT_OP_DOMAIN
from
.onnx_utils
import
graph_ops
,
graph_weights
from
.onnx_utils
import
inferred_model_value_info
from
.onnx_utils
import
optimize_model_skip_op_for_inference
from
.onnx_utils
import
optimize_model_strip_initializer
from
.onnx_utils
import
optimize_model_cast
,
optimize_model_slice
from
.writer
import
Program
,
Writer
from
.writer
import
make_var_name
logger
=
logging
.
getLogger
(
'convert'
)
...
...
@@ -94,6 +86,8 @@ def convert(onnx_model_filename,
model
=
onnx
.
shape_inference
.
infer_shapes
(
onnx_model
)
debug_model_filename
,
_
=
shutil
.
os
.
path
.
splitext
(
onnx_model_filename
)
onnx
.
save
(
model
,
debug_model_filename
+
'.optimized_and_inffered.onnx'
)
# onnx.save(model, '/tmp/export/optimized_and_inffered.onnx')
# I/O instances
...
...
@@ -218,12 +212,13 @@ def convert(onnx_model_filename,
logger
.
info
(
'conversion finished'
)
# globals().update(locals())
if
__name__
==
'__main__'
:
del
convert
import
argparse
from
onnx2fluid.conversion
import
convert
parser
=
argparse
.
ArgumentParser
(
description
=
'onnx2fluid.convert'
,
formatter_class
=
argparse
.
ArgumentDefaultsHelpFormatter
,
...
...
@@ -280,7 +275,10 @@ if __name__ == '__main__':
debug
=
args
.
debug
model_filename
=
args
.
model
[
0
]
basepath
,
_
=
shutil
.
os
.
path
.
splitext
(
model_filename
)
save_dir
=
args
.
output_dir
save_dir
=
(
save_dir
.
rstrip
(
shutil
.
os
.
sep
)
if
save_dir
else
basepath
)
+
shutil
.
os
.
sep
embed_params
=
args
.
embed_params
pedantic
=
args
.
pedantic
skip_version_conversion
=
args
.
skip_version_conversion
...
...
onnx2fluid/onnx2fluid/symbolic.py
浏览文件 @
9eaa7470
...
...
@@ -13,7 +13,7 @@ Created on Mon Feb 25 09:33:43 2019
from
__future__
import
division
import
logging
as
_logging
import
numpy
as
np
import
numpy
as
_
np
from
collections
import
OrderedDict
as
_dict
from
onnx.mapping
import
TENSOR_TYPE_TO_NP_TYPE
...
...
@@ -77,11 +77,11 @@ DEFAULT_OP_MAPPING = {
'Sqrt'
:
[
'sqrt'
,
[
'X'
],
[
'Out'
]],
'Tanh'
:
[
'tanh'
,
[
'X'
],
[
'Out'
]],
'ThresholdedRelu'
:
[
'thresholded_relu'
,
[
'X'
],
[
'Out'
],
dict
(
alpha
=
'threshold'
)],
#
'Transpose': ['transpose', ['X'], ['Out']],
#
'Transpose': ['transpose', ['X'], ['Out']],
'Unsqueeze'
:
[
'unsqueeze'
,
[
'X'
],
[
'Out'
]],
# attrs bypassed, FIXME: emit unsqueeze2
## binary ops ##
'Add'
:
[
'elementwise_add'
,
[
'X'
,
'Y'
],
[
'Out'
],
dict
(),
dict
(
axis
=-
1
)],
#
'AffineGrid': ['affine_grid', ['Theta'], ['Output'], dict(size='out_shape')],
#
'AffineGrid': ['affine_grid', ['Theta'], ['Output'], dict(size='out_shape')],
'And'
:
[
'logical_and'
,
[
'X'
,
'Y'
],
[
'Out'
]],
'Div'
:
[
'elementwise_div'
,
[
'X'
,
'Y'
],
[
'Out'
],
dict
(),
dict
(
axis
=-
1
)],
'Equal'
:
[
'equal'
,
[
'X'
,
'Y'
],
[
'Out'
],
dict
(),
dict
(),
None
,
None
,
False
],
...
...
@@ -110,7 +110,7 @@ DEFAULT_OP_MAPPING = {
'TopK'
:
[
'topk'
,
[
'X'
,
'K'
],
[
'Out'
,
'Indices'
]],
}
DEFAULT_IOA_CONSTRAINT
=
{
DEFAULT_IOA_CONSTRAINT
S
=
{
'ArgMax'
:
[
(
lambda
i
,
o
,
a
:
a
.
get
(
'keepdims'
,
1
)
==
1
,
'only keepdims = 0 is supported'
),
...
...
@@ -164,7 +164,7 @@ def _make_var_name(name):
def
_dtype
(
value_infos
,
val_name
):
return
np
.
dtype
(
value_infos
[
val_name
][
'dtype'
])
return
_
np
.
dtype
(
value_infos
[
val_name
][
'dtype'
])
def
_dtype_or_none
(
value_infos
,
val_name
):
...
...
@@ -173,7 +173,7 @@ def _dtype_or_none(value_infos, val_name):
value_info
=
value_infos
[
val_name
]
if
'dtype'
not
in
value_info
:
return
None
return
np
.
dtype
(
value_info
[
'dtype'
])
return
_
np
.
dtype
(
value_info
[
'dtype'
])
def
_shape
(
value_infos
,
val_name
):
...
...
@@ -217,8 +217,8 @@ def _default(prog, op_type, inputs, outputs, attrs, *args, name='', **kwargs):
fill_name_field
,
)
=
info
if
fluid_op
in
DEFAULT_IOA_CONSTRAINT
:
for
predicate
,
message
in
DEFAULT_IOA_CONSTRAINT
[
fluid_op
]:
if
fluid_op
in
DEFAULT_IOA_CONSTRAINT
S
:
for
predicate
,
message
in
DEFAULT_IOA_CONSTRAINT
S
[
fluid_op
]:
assert
predicate
(
inputs
,
outputs
,
attrs
),
message
# bypass if key absent, drop if mapped key is '' or '_'
...
...
@@ -268,14 +268,13 @@ def _default(prog, op_type, inputs, outputs, attrs, *args, name='', **kwargs):
(
var_outs
,
*
fluid_output_args
),
fluid_attrs
)
def
_assign
(
prog
,
attrs
):
mapping
=
attrs
[
'mapping'
]
# additional
def
_assign
(
prog
,
mapping
):
fluid_op
=
'assign'
for
val_dst
,
val_src
in
mapping
.
items
():
var_dst
=
_make_var_name
(
val_dst
)
var_src
=
_make_var_name
(
val_src
)
prog
.
Code
(
'{} = {}'
.
format
(
var_dst
,
var_src
))
prog
.
Code
(
'{} = {}
# assign
'
.
format
(
var_dst
,
var_src
))
# prog.Code('{} = layers.{}({})'
# .format(var_dst,
# fluid_op,
...
...
@@ -552,7 +551,6 @@ def _roi_pool(prog, fluid_op, inputs, outputs, attrs, value_infos, name):
def
_interpolate
(
prog
,
inputs
,
outputs
,
attrs
,
value_infos
,
name
=
''
):
# I/O
val_x
,
val_scales
=
inputs
val_y
,
=
outputs
...
...
@@ -775,7 +773,7 @@ def Cast(prog, inputs, outputs, attrs, value_infos, *args, **kwargs):
# interpretation
dtype
=
attrs
[
'to'
]
# required
if
not
isinstance
(
dtype
,
np
.
dtype
):
# additional: possible np.dtype
if
not
isinstance
(
dtype
,
_
np
.
dtype
):
# additional: possible np.dtype
dtype
=
TENSOR_TYPE_TO_NP_TYPE
[
dtype
]
output_dtype
=
_dtype_or_none
(
value_infos
,
val_output
)
if
output_dtype
:
...
...
@@ -852,13 +850,13 @@ def Constant(prog, inputs, outputs, attrs, value_infos, *args, **kwargs):
# interpretation
value
=
attrs
[
'value'
]
# required
dtype
=
np
.
dtype
(
value
.
dtype
)
dtype
=
_
np
.
dtype
(
value
.
dtype
)
output_dtype
=
_dtype_or_none
(
value_infos
,
val_output
)
if
output_dtype
:
assert
dtype
==
output_dtype
,
'tensor dtype unmatches storage dtype'
# dtype = np.dtype('float32') # HINT: force to float32
# dtype =
_
np.dtype('float32') # HINT: force to float32
shape
=
attrs
.
get
(
'shape'
,
None
)
#
if
shape
is
None
:
shape
=
_shape_or_none
(
value_infos
,
val_output
)
...
...
@@ -1161,7 +1159,7 @@ def ConvTranspose(prog,
# val_output, = outputs[:1]
#
# _assign(prog,
# dict(
mapping=dict([(val_output, val_data)])
),
# dict(
[(val_output, val_data)]
),
# value_infos,
# )
...
...
@@ -1216,13 +1214,13 @@ def Gemm(prog, inputs, outputs, attrs, value_infos, name, *args, **kwargs):
if
beta
.
is_integer
():
vm_dtype
=
_dtype_or_none
(
value_infos
,
val_c
)
if
vm_dtype
is
None
:
vm_dtype
=
np
.
dtype
(
'float32'
)
vm_dtype
=
_
np
.
dtype
(
'float32'
)
_logger
.
warning
(
'in %s(%s -> Gemm -> %s): '
'attribute "beta" seems to be an interger, '
'however dtype can not be inferred, '
'still use float32'
,
name
,
inputs
,
outputs
)
beta
=
np
.
dtype
(
vm_dtype
).
type
(
beta
)
beta
=
_
np
.
dtype
(
vm_dtype
).
type
(
beta
)
prog
.
Op
(
''
,
'Constant'
,
...
...
@@ -1388,7 +1386,7 @@ def Pad(prog, inputs, outputs, attrs, value_infos, name='', *args, **kwargs):
mode
)
fluid_op
=
'pad'
pad2d_attr
=
''
paddings
=
np
.
array
(
pads
).
reshape
(
paddings
=
_
np
.
array
(
pads
).
reshape
(
(
-
1
,
2
)).
transpose
().
flatten
().
tolist
()
# SSEE -> SESE
od_attrs
[
'paddings'
]
=
paddings
name_attr
=
', name={}'
.
format
(
repr
(
name
))
if
name
else
''
...
...
@@ -1526,7 +1524,7 @@ def Reshape(prog, inputs, outputs, attrs, value_infos, name, *args, **kwargs):
'Cast'
,
[
val_shape
],
[
val_shape_int32
],
# var
dict
(
to
=
np
.
dtype
(
'int32'
)),
# use np.dtype
dict
(
to
=
_
np
.
dtype
(
'int32'
)),
# use np.dtype
value_infos
=
value_infos
,
name
=
(
name
+
'_cast'
),
)
...
...
@@ -1841,7 +1839,9 @@ if __name__ == '__main__':
)
logger
=
_logging
.
getLogger
(
'symbolic_test'
)
from
writer
import
Program
import
numpy
as
np
from
onnx2fluid.writer
import
Program
prog
=
Program
()
AdaptiveAveragePool
(
...
...
onnx2fluid/onnx2fluid/validation.py
浏览文件 @
9eaa7470
...
...
@@ -8,11 +8,6 @@ Created on Fri Mar 22 12:17:19 2019
import
importlib
,
logging
,
os
,
sys
#import importlib
#import logging
#import os
#import sys
def
_flatten_dict
(
obj
,
out
=
None
):
assert
isinstance
(
obj
,
dict
)
...
...
@@ -37,10 +32,12 @@ def _ensure_list(obj):
def
validate
(
fluid_model_filename
,
golden_data_filename
,
model_func_name
=
'inference'
,
decimal
=
3
,
save_inference_model
=
False
):
atol
=
1e-3
,
rtol
=
1e-4
,
save_inference_model
=
False
,
**
kwargs
):
"""
inferece the converted Paddle fluid model, validate with given golden data
infere
n
ce the converted Paddle fluid model, validate with given golden data
"""
import
numpy
as
np
...
...
@@ -125,7 +122,13 @@ def validate(fluid_model_filename,
for
(
name
,
truth
),
output
in
zip
(
output_data
.
items
(),
outputs
):
logger
.
info
(
'testing output {} ...'
.
format
(
name
))
try
:
np
.
testing
.
assert_almost_equal
(
output
,
truth
,
decimal
=
decimal
)
np
.
testing
.
assert_allclose
(
output
,
truth
,
rtol
=
rtol
,
atol
=
atol
,
equal_nan
=
False
,
verbose
=
True
)
except
AssertionError
as
e
:
passed
=
False
logger
.
error
(
'failed: %s
\n
'
,
e
)
...
...
@@ -134,10 +137,9 @@ def validate(fluid_model_filename,
else
:
logger
.
info
(
'accuracy not passed'
)
# globals().update(locals())
return
passed
if
__name__
==
'__main__'
:
import
argparse
...
...
@@ -163,11 +165,17 @@ if __name__ == '__main__':
help
=
'I/O golden data for validation, e.g. test.npy, test.npz'
,
)
parser
.
add_argument
(
'--
precision
'
,
'--
atol
'
,
'-p'
,
type
=
int
,
default
=
3
,
help
=
'assertion decimal for validation'
,
type
=
float
,
default
=
1e-3
,
help
=
'assertion absolute tolerance for validation'
,
)
parser
.
add_argument
(
'--rtol'
,
type
=
float
,
default
=
1e-4
,
help
=
'assertion relative tolerance for validation'
,
)
args
=
parser
.
parse_args
()
...
...
@@ -178,10 +186,11 @@ if __name__ == '__main__':
debug
=
args
.
debug
fluid_model_filename
=
args
.
model
[
0
]
golden_data_filename
=
args
.
test_data
decimal
=
args
.
precision
atol
,
rtol
=
args
.
atol
,
args
.
rtol
validate
(
fluid_model_filename
,
golden_data_filename
,
decimal
=
decimal
,
atol
=
atol
,
rtol
=
rtol
,
save_inference_model
=
debug
)
onnx2fluid/onnx2fluid/writer.py
浏览文件 @
9eaa7470
...
...
@@ -9,27 +9,17 @@ Created on Sun Feb 24 20:44:43 2019
from
__future__
import
division
import
logging
,
os
#import logging
#import os
import
numpy
as
np
logger
=
logging
.
getLogger
(
__name__
)
try
:
from
.
import
symbolic
except
ImportError
:
import
symbolic
# imports
make_var_name
=
symbolic
.
_make_var_name
from
.
import
symbolic
from
.symbolic
import
_make_var_name
as
make_var_name
try
:
import
paddle.fluid.proto.framework_pb2
as
framework_pb2
except
ImportError
:
try
:
from
.
import
framework_pb2
except
ImportError
:
import
framework_pb2
logger
.
warning
(
'importing paddle.fluid.proto.framework_pb2d failed,'
'using fallback framework_pb2'
)
...
...
@@ -176,16 +166,13 @@ class Program(object):
self
.
op_descs
=
[]
self
.
var_descs
=
[]
def
__
st
r__
(
self
):
def
__
rep
r__
(
self
):
return
(
'Program(code mutable: {}) with:
\n
'
'codes: {}
\n
'
'op_descs: {}
\n
'
'var_descs: {}
\n
'
).
format
(
self
.
code_mutable
,
self
.
codes
,
self
.
op_descs
,
self
.
var_descs
)
def
__repr__
(
self
):
return
self
.
__str__
()
def
Code
(
self
,
code
):
"""
add Python code
...
...
@@ -218,11 +205,9 @@ class Program(object):
name
,
persistable
=
False
,
value_info
=
None
,
remove_batch
=
None
,
dummy_dtype
=
'float32'
):
remove_batch
=
None
):
"""
add VarDesc,
dummy_dtype: WORKAROUND for Netron viewer
"""
var_desc
=
framework_pb2
.
VarDesc
()
...
...
@@ -241,9 +226,6 @@ class Program(object):
not
persistable
)
if
remove_batch
:
tensor_desc
.
dims
[
0
]
=
-
1
else
:
# REMOVEIT: WORKAROUND: Netron: null.tensor error
tensor_desc
=
var_desc
.
type
.
lod_tensor
.
tensor
tensor_desc
.
data_type
=
self
.
Dtype
(
dummy_dtype
)
# required
self
.
var_descs
.
append
(
var_desc
)
...
...
onnx2fluid/requirements.txt
浏览文件 @
9eaa7470
-e .
onnx>=1.4
.0
onnx>=1.4
paddlepaddle
onnx2fluid/setup.cfg
浏览文件 @
9eaa7470
...
...
@@ -7,7 +7,7 @@ name = onnx2fluid
author = Macrobull
# author_email = .Github@github.com
# 项目版本号,1.0以上版本才视为正式版
version = 0.1.
0
version = 0.1.
1
# 项目概要描述信息,一句话让用户明白项目概要,不支持中文
description = Inference model conversion from ONNX/PyTorch to Paddle fluid
# 项目的详细描述内容和格式,包括readme和changelog等,通常使用md或rst等格式
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录