README.md 8.1 KB
Newer Older
J
Jason 已提交
1 2 3
### X2Paddle已经发布0.5版本,提供统一的模型转换工具,支持onnx/caffe/tensorflow,最新代码在develop分支:)
develop分支: https://github.com/PaddlePaddle/X2Paddle/tree/develop

J
jiangjiajun 已提交
4
# tensorflow2fluid
J
Jason 已提交
5
[![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](LICENSE)
J
Jason 已提交
6

J
Jason 已提交
7
tensorflow2fluid支持将训练好的TensorFlow模型转换为PaddlePaddle模型,包括基于PaddlePaddle实现的模型前向计算网络python代码,以及PaddlePaddle可加载的模型参数文件。  
J
Jason 已提交
8
此外在[[doc](doc)]目录中整理了TensorFlow-PaddlePaddle的常用API对比分析。  
J
Jason 已提交
9
[环境安装](#环境安装)  [使用方法](#使用方法)  [验证模型](#验证模型)  [常见问题](#常见问题)
J
Jason 已提交
10

J
Jason 已提交
11
## 环境安装
J
Jason 已提交
12

J
Jason 已提交
13
工具开发过程中,我们在如下环境配置中测试模型转换,建议使用[anaconda](https://docs.anaconda.com/anaconda/install)
J
Jason 已提交
14

J
Jason 已提交
15 16 17 18 19
> python == 2.7 or 3.6

> tensorflow == 1.12.0

> paddlepaddle == 1.3.0
J
Jason 已提交
20

J
Jason 已提交
21 22 23 24 25 26 27 28 29
``` shell
# pip install tensorflow-gpu
conda install tensorflow-gpu
pip install paddlepaddle-gpu

# 上述安装过程可能会提示protobuf版本问题
# 升级protobuf解决
pip install protobuf --upgrade
```
J
Jason 已提交
30
         
J
Jason 已提交
31
## 使用方法
J
Jason 已提交
32
本目录下提供了demo示例,展示如何将VGG_16模型转换为PaddlePaddle模型,详见[vgg_translate_tutorial](vgg_translate_tutorial.ipynb)
J
Jason 已提交
33
### 转换模型
J
Jason 已提交
34
```
J
Jason 已提交
35
python tf2fluid/convert.py --pb_file tf_model.pb \
J
Jason 已提交
36 37 38 39
                      --in_nodes inputs \
                      --output_nodes outputs \
                      --input_shape None,224,224,3 \
                      --input_format NHWC \
J
Jason 已提交
40
                      --use_cuda True \
J
Jason 已提交
41 42 43
                      --save_dir translated_paddle_model
```
### 加载模型并预测  
J
Jason 已提交
44 45
本目录下提供了[model_loader.py](tf2fluid/model_loader.py),可以辅助用户简单的加载模型和预测,和dump模型,用户可直接参考其实现  

J
Jason 已提交
46 47 48 49 50 51 52 53 54
``` python
# coding:utf-8
# 代码运行目录 X2Paddle/tensorflow2fluid
import sys
import tf2fluid.model_loader as ml

# 加载模型
model = ml.ModelLoader("translated_paddle_model", use_cuda=True)

J
Jason 已提交
55 56 57 58 59 60 61 62
# 随机生成数据用于模型预测
# 注意Paddle CV模型输入格式为NCHW !!!
data = numpy.random.rand(5, 3, 224, 224).astype('float32')
results = model.inference(feed_dict={model.inputs[0]:data})

# 返回的results为list,元素为np.array
for res in results:
    print(res.shape)
J
Jason 已提交
63
```
J
Jason 已提交
64

J
Jason 已提交
65 66
使用转换后的模型主要注意,**模型转换后,计算结果与原模型存在一定精度的diff,因此务必检查模型转换前后,在输入同样的数据前提下,diff是否符合预期**  

J
Jason 已提交
67 68 69 70 71 72
### 序列化模型结构  
tensorflow2fluid转换后的模型结构以python代码定义形式供用户直观阅读或修改,如若需要将模型结构和参数均序列化存储,可以上面的示例代码中,调用如下代码即可,序列化的模型结构和参数如何加载可见PaddlePaddle使用文档中的[加载预测模型](http://www.paddlepaddle.org/documentation/docs/zh/1.3/api_guides/low_level/inference.html#id4)
``` python
model.save_inference_model("new_model_dir")
```

J
Jason 已提交
73
### 参数说明  
J
Jason 已提交
74
|tf2fluid参数|说明|
J
Jason 已提交
75
|-----------|-----------------------------------------------|
J
Jason 已提交
76
|meta_file|TensorFlow模型序列化后保存的meta文件|
J
Jason 已提交
77
|ckpt_dir|TensorFlow模型保存checkpoint目录|
J
Jason 已提交
78
|pb_file|Tensorflow保存的pb格式模型|
J
Jason 已提交
79
|in_nodes|输入tensor名,多个输入时以空格分隔|
J
Jason 已提交
80
|input_shape|输入tensor的shape(batch维度以None表示),shape之间以空格分隔,shape内各维度以逗号分隔|
J
Jason 已提交
81
|input_format|输入数据格式,NHWC/NCHW/OTHER|
J
Jason 已提交
82
|output_nodes|输出tensor名,多个输出时以空格分隔|
J
Jason 已提交
83
|use_cuda|转换过程中是否使用GPU,默认True|
J
Jason 已提交
84
|save_dir|转换后的模型保存路径|
J
Jason 已提交
85

J
Jason 已提交
86
目前支持tensorflow保存的checkpoint模型和将参数及模型结构序列化存储的pb模型,前者须指定meta_file和ckpt_dir,后者则指定pb_file  
J
Jason 已提交
87
**FAQ:输入tensor名和输出tensor名是指什么?**  
J
Jason 已提交
88
TensorFlow模型在infer时,一般调用代码形如`sess.run([output], {input:data})`,其中output即为输出tensor,input则为输入tensor,在进行模型转换时,需提供这input和output对应的`tensor name`,如在[vgg_translate_tutorial](vgg_translate_tutorial.ipynb)中转换VGG_16模型,输入的tensor名为 "inputs", 输出的tensor名为 "vgg_16/fc8/squeezed"
J
Jason 已提交
89

J
Jason 已提交
90
### 转换后模型文件说明  
J
Jason 已提交
91 92
文件|作用
:------------------:|:-----------------------------------------------:
J
Jason 已提交
93
mymodel.py|基于PaddlePaddle实现的模型网络结构python代码
J
Jason 已提交
94
ref_name.info|my_model.py中各tensor与原TensorFlow模型中的tensor对应关系
J
Jason 已提交
95
const_\*/params_\*|转换后的模型参数文件
J
Jason 已提交
96 97
save_var.list|模型载入过程中的变量list

J
Jason 已提交
98
## 验证模型
J
Jason 已提交
99 100
tensorflow2fluid在如下tensorflow模型上测试了模型转换前后的diff  

J
Jason 已提交
101 102 103 104 105 106 107
| 模型类别 | 模型          | Code   | 最大diff |
| -------- | ------------- | ------ | -------- |
| 图像分类 | VGG_16        | [code](https://github.com/tensorflow/models/blob/master/research/slim/nets/vgg.py) | 1.04E-05 |
|          | VGG_19        | [code](https://github.com/tensorflow/models/blob/master/research/slim/nets/vgg.py) | 9.07E-06 |
|          | ResNet V1 50  | [code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py) | 1.31E-06 |
|          | ResNet V1 101 | [code](https://github.com/tensorflow/models/blob/master/research/slim/nets/resnet_v1.py) | 4.74E-07 |
|          | Inception V3  | [code](https://github.com/tensorflow/models/blob/master/research/slim/nets/inception_v3.py) | 1.55E-04 |
J
Jason 已提交
108
|         | NASNet_Large | [code](https://github.com/tensorflow/models/blob/master/research/slim/nets/nasnet/nasnet.py) | - |
J
Jason 已提交
109
|         | PNASNet_Large | [code](https://github.com/tensorflow/models/blob/master/research/slim/nets/nasnet/pnasnet.py) | - |
J
Jason 已提交
110 111 112 113
| 目标检测 | YOLO-Small    | [code](https://github.com/gliese581gg/YOLO_tensorflow) | 1.40E-06 |
|          | YOLO-V3       | [code](https://github.com/mystic123/tensorflow-yolo-v3) | 6.20E-04 |
| 语义分割 | Unet          | [code](https://github.com/jakeret/tf_unet) | 4.17E-07 |

J
Jason 已提交
114 115
## 常见问题
1. 转换参数`input_format`的设定?
J
Jason 已提交
116 117
> TensorFlow中的CV模型,大多采用`NHWC`的输入格式,但同时也可以支持`NCHW`的格式输入;而在PaddlePaddle中,支持的是`NCHW`的格式。因此需要在转换模型时,指定TensorFlow模型的输入格式,转换过程中会根据输入格式,对输入数据,参数进行变换。

J
Jason 已提交
118
2. 转换参数`input_shape`的设定?
J
Jason 已提交
119 120 121

> 在模型转换时,需设定输入数据的具体`shape`。因为转换过程中,涉及到较多参数的转换,因此模型转换完成应用到预测时,输入数据的`shape`也须与之前指定的一致,否则可能会出错。

J
Jason 已提交
122
3. 转换参数`use_cuda`的设定?
J
Jason 已提交
123 124 125

> 受限于PaddlePaddle与TensorFlow部分OP上的实现差异,部分tensor参数(在TensorFlow中,这部分参数类型是tensor类型,但值保持不变)需要通过infer得到。因此模型转换过程中,同时也会加载tensorflow模型进行预测,消耗计算资源。在有GPU资源的的前提下,将`use_cuda`设为`True`有助于提升转换速度。

J
Jason 已提交
126
4. 模型转换前后diff对比?
J
Jason 已提交
127

J
Jason 已提交
128
> tensorflow2fluid仍在不断完善和测试中,用户转换完模型后,注意对比模型在转换前后的输出diff是否在可接受范围内。此外转换后的模型结构`mymodel.py`如存在构建失败的问题,可能是由于部分参数在特殊情况下未被考虑到导致,用户可以直接通过修改`mymodel.py`来解决。
J
Jason 已提交
129

J
Jason 已提交
130 131
5. 模型转换失败,提示"Unsupported OP: XXX"?

J
Jason 已提交
132
> 目前tf2fluid支持50个左右常见OP的转换,仍然在不断补充中,当出现如上提示时,即表示模型存在暂未支持的OP,用户可以直接在[tf2fluid/paddle_emitter.py](tf2fluid/paddle_emitter.py)中仿照`emit_xxx`函数添加转换代码支持,或者也欢迎通过提ISSUE的方式让我们知道你的需求!
J
Jason 已提交
133

J
Jason 已提交
134 135
## Link

J
Jason 已提交
136
本目录下部分代码参考了MMdnn-Tensorflow,对此表示感谢!
J
Jason 已提交
137

J
Jason 已提交
138
[MMdnn-Tensorflow](https://github.com/Microsoft/MMdnn/tree/master/mmdnn/conversion/tensorflow)