Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
079b8243
P
Paddle
项目概览
PaddlePaddle
/
Paddle
1 年多 前同步成功
通知
2302
Star
20931
Fork
5422
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
079b8243
编写于
12月 26, 2017
作者:
Y
ying
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
follow comments.
上级
b915fde9
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
172 addition
and
39 deletion
+172
-39
doc/howto/usage/capi/a_simple_example_cn.md
doc/howto/usage/capi/a_simple_example_cn.md
+45
-36
doc/howto/usage/capi/compile_paddle_lib_cn.md
doc/howto/usage/capi/compile_paddle_lib_cn.md
+122
-0
doc/howto/usage/capi/index_cn.rst
doc/howto/usage/capi/index_cn.rst
+3
-3
doc/howto/usage/capi/organization_of_the_inputs_cn.md
doc/howto/usage/capi/organization_of_the_inputs_cn.md
+2
-0
未找到文件。
doc/howto/usage/capi/a_simple_example.md
→
doc/howto/usage/capi/a_simple_example
_cn
.md
浏览文件 @
079b8243
...
...
@@ -4,8 +4,8 @@
### 使用流程
使用 C-API 分为:准备
工作
和预测程序开发两部分。
-
准备
使用 C-API 分为:准备
预测模型
和预测程序开发两部分。
-
准备
预测模型
1.
将神经网络模型结构进行序列化。
-
调用C-API预测时,需要提供序列化之后的网络结构和训练好的模型参数文件。
1.
将PaddlePaddle训练出的模型参数文件(多个)合并成一个文件。
...
...
@@ -14,18 +14,17 @@
-
**注意**
:以上两种方式只需选择其一即可。
-
调用 PaddlePaddle C-API 开发预测序
1.
初始化PaddlePaddle运行环境。
1.
创建神经网络的输入,组织输入数据。
1.
加载模型。
1.
创建神经网络的输入,组织输入数据。
1.
进行前向计算,获得计算结果。
1.
清理。
本文档以手写数字识别任务为例,介绍如何使用 C-API 进行预测,完整代码请查看
[
此目录
](
https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/capi/examples/model_inference/dense
)
。
这里我们以手写数字识别任务为例,介绍如何使用 C-API 进行预测,完整代码请查看
[
此目录
](
https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/capi/examples/model_inference/dense
)
。
运行目录下的
`python mnist_v2.py`
可以使用 PaddlePaddle 内置的
[
MNIST 数据集
](
http://yann.lecun.com/exdb/mnist/
)
进行训练。脚本中的模型定义了一个简单的含有
[
两个隐层的全连接网络
](
https://github.com/PaddlePaddle/book/blob/develop/02.recognize_digits/README.cn.md#softmax回归softmax-regression
)
,网络接受一幅图片作为输入,将图片分类到 0 ~ 9 类别标签之一。训练好的模型默认保存在当前运行目录下的
`models`
目录中。下面,我们将调用 C-API 加载训练好的模型进行预测。
### 准备预测模型
### 外部准备
通过在终端执行
`python mnist_v2.py`
运行
[
目录
](
https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/capi/examples/model_inference/dense
)
下的
`mnist_v2.py`
s可以使用 PaddlePaddle 内置的
[
MNIST 数据集
](
http://yann.lecun.com/exdb/mnist/
)
进行训练。脚本中的模型定义了一个简单的含有
[
两个隐层的全连接网络
](
https://github.com/PaddlePaddle/book/blob/develop/02.recognize_digits/README.cn.md#softmax回归softmax-regression
)
,网络接受一幅图片作为输入,将图片分类到 0 ~ 9 类别标签之一。训练好的模型默认保存在当前运行目录下的
`models`
目录中。下面,我们将调用 C-API 加载训练好的模型进行预测。
1.
序列化神经网络模型配置
...
...
@@ -52,8 +51,7 @@
代码示例如下:
```python
from paddle.utils.merge_model import merge_v2_model
from paddle.utils.merge_model import merge_v2_modelss
from mnist_v2 import network
net = network(is_infer=True)
...
...
@@ -70,54 +68,65 @@
### 编写预测代码
#### step 1. 初始化及加载模型
#### step 1. 初始化PaddlePaddle运行环境
使用C-API第一步需首先调用
[
`paddle_init`
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/capi/main.h#L27
)
初始化PaddlePaddle运行环境。接口接受两个参数:参数的个数和参数。
1.
初始化PaddlePaddle运行环境。
```
c
// Initalize the PaddlePaddle runtime environment.
char
*
argv
[]
=
{
"--use_gpu=False"
};
CHECK
(
paddle_init
(
1
,
(
char
**
)
argv
));
```
下面的代码片段在初始化PaddlePaddle运行环境时指定不使用GPU:
1.
加载训练好的模型。
```
c
// Initalize the PaddlePaddle runtime environment.
char
*
argv
[]
=
{
"--use_gpu=False"
};
CHECK
(
paddle_init
(
1
,
(
char
**
)
argv
));
```
这里需要介绍C-API使用中的一个重要概念:Gradient Machine。概念上,在 PaddlePaddle 内部,一个GradientMachine类的对象管理着一组计算层(PaddlePaddle Layers)来完成前向和反向计算,并处理与之相关的所有细节。特别的,在调用C-API预测时只需进行前向计算。这篇文档的之后部分我们会使用`gradient machine`来特指调用PaddlePaddle C-API创建的GradientMachine类的对象。
下面的代码片段在初始化PaddlePaddle运行环境时指定了两个参数:不使用GPU和
[
使用MKLDNN
](
https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/mkl/mkldnn.md
)
:
每一个 `gradient machine` 都会管理维护一份训练好的模型,模型可以通过以下两种方式获取:
1. 从磁盘加载;这时`gradient machine`会独立拥有一份训练好的模型;
1. 共享自其它`gradient machine`的模型;这种情况多出现在使用多线程预测时;
```
c
char
*
argv
[]
=
{
"--use_gpu=False"
,
"--use_mkldnn=True"
};
CHECK
(
paddle_init
(
2
,
(
char
**
)
argv
));
```
下面的代码片段创建 `gradient machine`,并从指定路径加载训练好的模型。
#### step2. 加载模型
```c
// Read the binary configuration file generated by `convert_protobin.sh`
long size;
void* buf = read_config(CONFIG_BIN, &size);
这里介绍C-API使用中的一个重要概念:Gradient Machine。概念上,在 PaddlePaddle 内部一个GradientMachine类的对象管理着一组计算层(PaddlePaddle Layers)来完成前向和反向计算,并处理与之相关的所有细节。在调用C-API预测时,只需进行前向计算而无需调用反向计算。这篇文档的之后部分我们会使用
`gradient machine`
来特指调用PaddlePaddle C-API创建的GradientMachine类的对象。
// Create the gradient machine for inference.
paddle_gradient_machine machine;
CHECK(paddle_gradient_machine_create_for_inference(&machine, buf, (int)size));
每一个
`gradient machine`
都会管理维护一份训练好的模型,下面是两种最常用的模型加载方式:
// Load the trained model. Modify the parameter MODEL_PATH to set the correct
// path of the trained model.
CHECK(paddle_gradient_machine_load_parameter_from_disk(machine, MODEL_PATH));
```
1.
从磁盘加载:这时
`gradient machine`
会独立拥有一份训练好的模型;
1.
共享自其它
`gradient machine`
的模型:这种情况多出现在使用多线程预测时,通过多个线程共享同一个模型来减少内存开销。可参考
[
此示例
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/capi/examples/model_inference/multi_thread/main.c
)
。
下面的代码片段创建
`gradient machine`
,并从指定路径加载训练好的模型。
```
c
// Read the binary configuration file generated by `convert_protobin.sh`
long
size
;
void
*
buf
=
read_config
(
CONFIG_BIN
,
&
size
);
// Create the gradient machine for inference.
paddle_gradient_machine
machine
;
CHECK
(
paddle_gradient_machine_create_for_inference
(
&
machine
,
buf
,
(
int
)
size
));
// Load the trained model. Modify the parameter MODEL_PATH to set the correct
// path of the trained model.
CHECK
(
paddle_gradient_machine_load_parameter_from_disk
(
machine
,
MODEL_PATH
));
```
##### 注意事项
1.
以上代码片段使用“仅序列化神经网络结构”的方式加载模型,需要同时指定模型参数存储的路径。
-
使用PaddlePaddle V2 API训练,模型中所有可学习参数会被存为一个压缩文件,需要手动进行解压,将它们放在同一目录中,C-API不会直接加载 V2 API 存储的压缩文件。
1.
如果使用
`merge model`
方式将神经网络结构和训练好的参数序列化到一个文件,请参考此
[
示例
](
https://github.com/PaddlePaddle/Mobile/blob/develop/Demo/linux/paddle_image_recognizer.cpp#L59
)
。
1.
加载模型有多种方式,也可以在程序运行过程中再加载另外一个模型。
#### step 2. 创建神经网络输入,组织输入数据
基本使用概念:
-
在PaddlePaddle内部,神经网络中一个计算层的输入
/输出被组织为一个
`Argument`
结构体,如果神经网络有多个输入或者多个输入,每一个输入/输入
都会对应有自己的
`Argument`
。
-
在PaddlePaddle内部,神经网络中一个计算层的输入
输出被组织为一个
`Argument`
结构体,如果神经网络有多个输入或者多个输出,每一个输入/输出
都会对应有自己的
`Argument`
。
-
`Argument`
并不真正“存储”数据,而是将输入/输出数据有机地组织在一起。
-
在
`Argument`
内部由:1.
`Matrix`
(二维矩阵,存储浮点类型输入/输出);2.
`IVector`
(一维数组,
**仅用于存储整型值**
,多用于自然语言处理任务)来实际存储数据。
*注:本文档使用的示例任务手写数字识别不涉及一维整型数组作为输入,因此,本文档仅讨论二维稠密矩阵作为输入的情形。更多输入数据格式请参考输入/输出数据一节的内容。*
这篇文档的之后部分会使用
`argument`
来
**特指**
PaddlePaddle C-API中神经网的一个输入/输出,使用
`paddle_matrix`
**特指**
`argument`
中用于存储数据的
`Matrix`
类的对象。
这篇文档的之后部分会使用
`argument`
来
**特指**
PaddlePaddle C-API中神经网
络
的一个输入/输出,使用
`paddle_matrix`
**特指**
`argument`
中用于存储数据的
`Matrix`
类的对象。
于是,在组织神经网络输入,获取输出时,需要思考完成以下工作:
1.
为每一个输入/输出创建
`argument`
;
...
...
doc/howto/usage/capi/compile_paddle_lib.md
→
doc/howto/usage/capi/compile_paddle_lib
_cn
.md
浏览文件 @
079b8243
## 编译 PaddlePaddle
链接
库
## 编译 PaddlePaddle
预测
库
### 概述
使用 C-API 进行预测依赖于将 PaddlePaddle 核心代码编译成链接库,只需在编译时指定编译选项:
`-DWITH_C_API=ON`
。同时,
**建议将:`DWITH_PYTHON`,`DWITH_SWIG_PY`,`DWITH_GOLANG`,均设置为`OFF`**
,以避免链接不必要的库。其它编译选项按需进行设定。
使用 C-API 进行预测依赖于将 PaddlePaddle 核心代码编译成链接库,只需在编译时需配制下面这些编译选项:
必须配置选项:
-
`WITH_C_API`
,必须配置为
`ON`
。
推荐配置选项:
-
`WITH_PYTHON`
,推荐配置为
`OFF`
-
`WITH_SWIG_PY`
,推荐配置为
`OFF`
-
`WITH_GOLANG`
,推荐设置为
`OFF`
可选配置选项:
-
`WITH_GPU`
,可配置为
`ON/OFF`
-
`WITH_MKL`
,可配置为
`ON/OFF`
对推荐配置中的选项建议按照设置,以避免链接不必要的库。其它可选编译选项按需进行设定。
下面的代码片段从github拉取最新代码,配制编译选项(需要将PADDLE_ROOT替换为PaddlePaddle预测库的安装路径):
```
shell
INSTALL_PREFIX
=
/path/of/capi/
PADDLE_ROOT
=
/path/of/paddle_source/
cmake
$PADDLE_ROOT
-DCMAKE_INSTALL_PREFIX
=
$INSTALL_PREFIX
\
PADDLE_ROOT
=
/path/of/capi
git clone https://github.com/PaddlePaddle/Paddle.git
cd
Paddle
mkdir
build
cd
build
cmake
-DCMAKE_INSTALL_PREFIX
=
$PADDLE_ROOT
\
-DCMAKE_BUILD_TYPE
=
Release
\
-DWITH_C_API
=
ON
\
-DWITH_SWIG_PY
=
OFF
\
-DWITH_GOLANG
=
OFF
\
-DWITH_PYTHON
=
OFF
\
-DWITH_MKLML
=
OFF
\
-DWITH_MKLDNN
=
OFF
\
-DWITH_GPU
=
OFF
\
...
-DWITH_MKL
=
OFF
\
-DWITH_GPU
=
OFF
\
..
```
在上面的代码片段中,
`PADDLE_ROOT`
表示 PaddlePaddle 源码所在目录,生成Makefile文件后执行:
`make && make install`
。成功执行后,使用CAPI所需的依赖(包括:(1)编译出的PaddlePaddle 链接和头文件;(2)第三方链接库和头文件)均会存放于
`INSTALL_PREFIX`
目录中。
编译成功后在
`INSTALL_PREFIX`
下会看到如下目录结构(包括了编译出的PaddlePaddle头文件和链接库,以及第三方依赖链接库和头文件(如果需要,由链接方式决定)):
执行上述代码生成Makefile文件后,执行:
`make && make install`
。成功编译后,使用C-API所需的依赖(包括:(1)编译出的PaddlePaddle预测库和头文件;(2)第三方链接库和头文件)均会存放于
`PADDLE_ROOT`
目录中。
编译成功后在
`PADDLE_ROOT`
下会看到如下目录结构(包括了编译出的PaddlePaddle头文件和链接库,以及第三方依赖链接库和头文件(如果需要,由链接方式决定)):
```
text
├── include
...
...
@@ -38,29 +57,62 @@ cmake $PADDLE_ROOT -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \
├── lib
│ ├── libpaddle_capi_engine.a
│ ├── libpaddle_capi_layers.a
│ ├── libpaddle_capi_shared.
dylib
│ ├── libpaddle_capi_shared.
so
│ └── libpaddle_capi_whole.a
└── third_party
├── ......
├── gflags
│ ├── include
│ │ └── gflags
│ │ ├── gflags_completions.h
│ │ ├── gflags_declare.h
│ │ ...
│ └── lib
│ └── libgflags.a
├── glog
│ ├── include
│ │ └── glog
│ │ ├── config.h
│ │ ...
│ └── lib
│ └── libglog.a
├── openblas
│ ├── include
│ │ ├── cblas.h
│ │ ...
│ └── lib
│ ...
├── protobuf
│ ├── include
│ │ └── google
│ │ └── protobuf
│ │ ...
│ └── lib
│ └── libprotobuf-lite.a
└── zlib
├── include
│ ...
└── lib
...
```
### 链接
方式
说明
### 链接说明
目前提供三种链接方式:
1.
链接
`libpaddle_capi_shared.so`
动态库
-
使用 PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_shared.so`
时,需注意:
1.
如果编译时指定编译CPU版本,且使用
`OpenBLAS`
矩阵库,在使用C
API开发预测程序时,只需要链接
`libpaddle_capi_shared.so`
这一个库。
1.
如果是用编译时指定CPU版本,且使用
`MKL`
矩阵库,由于
`MKL`
库有自己独立的动态库文件,在使用PaddlePaddle C
API开发预测程序时,需要自己链接MKL链接库。
1.
如果编译时指定编译CPU版本,且使用
`OpenBLAS`
数学库,在使用C-
API开发预测程序时,只需要链接
`libpaddle_capi_shared.so`
这一个库。
1.
如果是用编译时指定CPU版本,且使用
`MKL`
数学库,由于
`MKL`
库有自己独立的动态库文件,在使用PaddlePaddle C-
API开发预测程序时,需要自己链接MKL链接库。
1.
如果编译时指定编译GPU版本,CUDA相关库会在预测程序运行时动态装载,需要将CUDA相关的库设置到
`LD_LIBRARY_PATH`
环境变量中。
-
这种方式最为简便,链接相对容易,
**在无特殊需求情况下,推荐使用此方式**
。
2.
链接静态库
`libpaddle_capi_whole.a`
-
使用PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_whole.a`
时,需注意:
1.
需要指定
`-Wl,--whole-archive`
链接选项。
1.
需要显式地链接
`gflags`
、
`glog`
、
`libz`
、
`protobuf`
等第三方库,可在
`
INSTALL_PREFIX\
third_party`
下找到。
1.
如果在编译 C-API 时使用OpenBLAS
矩阵
库,需要显示地链接
`libopenblas.a`
。
1.
如果在编译 C-API 是使用
MKL 矩阵库,需要显示地链接 MKL
的动态库。
1.
需要显式地链接
`gflags`
、
`glog`
、
`libz`
、
`protobuf`
等第三方库,可在
`
PADDLE_ROOT/
third_party`
下找到。
1.
如果在编译 C-API 时使用OpenBLAS
数学
库,需要显示地链接
`libopenblas.a`
。
1.
如果在编译 C-API 是使用
MKL数学库,需要显示地链接MKL
的动态库。
3.
链接静态库
`libpaddle_capi_layers.a`
和
`libpaddle_capi_engine.a`
-
使用PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_whole.a`
时,需注意:
...
...
doc/howto/usage/capi/index_cn.rst
浏览文件 @
079b8243
...
...
@@ -4,6 +4,6 @@ PaddlePaddle C-API
.. toctree::
:maxdepth: 1
compile_paddle_lib.md
organization_of_the_inputs.md
a_simple_example.md
compile_paddle_lib
_cn
.md
organization_of_the_inputs
_cn
.md
a_simple_example
_cn
.md
doc/howto/usage/capi/organization_of_the_inputs.md
→
doc/howto/usage/capi/organization_of_the_inputs
_cn
.md
浏览文件 @
079b8243
...
...
@@ -260,6 +260,8 @@
</table>
</html>
<br>
### 输出数据
PaddlePaddle中一个计算层的输出数据组织方式和输入数据组织方式完全相同。一个输出数据同样被组织为一个
`argument`
,
`argument`
通过
`paddle_matrix`
或
`paddle_ivector`
存数数据,如果输出是一个序列,那么会携带有
`sequence_start_positions`
信息。调用C-API相关接口,读取需要的结果即可。
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录