Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
079b8243
P
Paddle
项目概览
机器未来
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
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 @@
...
@@ -4,8 +4,8 @@
### 使用流程
### 使用流程
使用 C-API 分为:准备
工作
和预测程序开发两部分。
使用 C-API 分为:准备
预测模型
和预测程序开发两部分。
-
准备
-
准备
预测模型
1.
将神经网络模型结构进行序列化。
1.
将神经网络模型结构进行序列化。
-
调用C-API预测时,需要提供序列化之后的网络结构和训练好的模型参数文件。
-
调用C-API预测时,需要提供序列化之后的网络结构和训练好的模型参数文件。
1.
将PaddlePaddle训练出的模型参数文件(多个)合并成一个文件。
1.
将PaddlePaddle训练出的模型参数文件(多个)合并成一个文件。
...
@@ -14,18 +14,17 @@
...
@@ -14,18 +14,17 @@
-
**注意**
:以上两种方式只需选择其一即可。
-
**注意**
:以上两种方式只需选择其一即可。
-
调用 PaddlePaddle C-API 开发预测序
-
调用 PaddlePaddle C-API 开发预测序
1.
初始化PaddlePaddle运行环境。
1.
初始化PaddlePaddle运行环境。
1.
创建神经网络的输入,组织输入数据。
1.
加载模型。
1.
加载模型。
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.
序列化神经网络模型配置
1.
序列化神经网络模型配置
...
@@ -52,8 +51,7 @@
...
@@ -52,8 +51,7 @@
代码示例如下:
代码示例如下:
```python
```python
from paddle.utils.merge_model import merge_v2_model
from paddle.utils.merge_model import merge_v2_modelss
from mnist_v2 import network
from mnist_v2 import network
net = network(is_infer=True)
net = network(is_infer=True)
...
@@ -70,54 +68,65 @@
...
@@ -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运行环境。
下面的代码片段在初始化PaddlePaddle运行环境时指定不使用GPU:
```
c
// Initalize the PaddlePaddle runtime environment.
char
*
argv
[]
=
{
"--use_gpu=False"
};
CHECK
(
paddle_init
(
1
,
(
char
**
)
argv
));
```
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` 都会管理维护一份训练好的模型,模型可以通过以下两种方式获取:
```
c
1. 从磁盘加载;这时`gradient machine`会独立拥有一份训练好的模型;
char
*
argv
[]
=
{
"--use_gpu=False"
,
"--use_mkldnn=True"
};
1. 共享自其它`gradient machine`的模型;这种情况多出现在使用多线程预测时;
CHECK
(
paddle_init
(
2
,
(
char
**
)
argv
));
```
下面的代码片段创建 `gradient machine`,并从指定路径加载训练好的模型。
#### step2. 加载模型
```c
这里介绍C-API使用中的一个重要概念:Gradient Machine。概念上,在 PaddlePaddle 内部一个GradientMachine类的对象管理着一组计算层(PaddlePaddle Layers)来完成前向和反向计算,并处理与之相关的所有细节。在调用C-API预测时,只需进行前向计算而无需调用反向计算。这篇文档的之后部分我们会使用
`gradient machine`
来特指调用PaddlePaddle C-API创建的GradientMachine类的对象。
// 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.
每一个
`gradient machine`
都会管理维护一份训练好的模型,下面是两种最常用的模型加载方式:
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
1.
从磁盘加载:这时
`gradient machine`
会独立拥有一份训练好的模型;
// path of the trained model.
1.
共享自其它
`gradient machine`
的模型:这种情况多出现在使用多线程预测时,通过多个线程共享同一个模型来减少内存开销。可参考
[
此示例
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/capi/examples/model_inference/multi_thread/main.c
)
。
CHECK(paddle_gradient_machine_load_parameter_from_disk(machine, MODEL_PATH));
```
下面的代码片段创建
`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.
以上代码片段使用“仅序列化神经网络结构”的方式加载模型,需要同时指定模型参数存储的路径。
1.
以上代码片段使用“仅序列化神经网络结构”的方式加载模型,需要同时指定模型参数存储的路径。
-
使用PaddlePaddle V2 API训练,模型中所有可学习参数会被存为一个压缩文件,需要手动进行解压,将它们放在同一目录中,C-API不会直接加载 V2 API 存储的压缩文件。
-
使用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.
如果使用
`merge model`
方式将神经网络结构和训练好的参数序列化到一个文件,请参考此
[
示例
](
https://github.com/PaddlePaddle/Mobile/blob/develop/Demo/linux/paddle_image_recognizer.cpp#L59
)
。
1.
加载模型有多种方式,也可以在程序运行过程中再加载另外一个模型。
#### step 2. 创建神经网络输入,组织输入数据
#### step 2. 创建神经网络输入,组织输入数据
基本使用概念:
基本使用概念:
-
在PaddlePaddle内部,神经网络中一个计算层的输入
/输出被组织为一个
`Argument`
结构体,如果神经网络有多个输入或者多个输入,每一个输入/输入
都会对应有自己的
`Argument`
。
-
在PaddlePaddle内部,神经网络中一个计算层的输入
输出被组织为一个
`Argument`
结构体,如果神经网络有多个输入或者多个输出,每一个输入/输出
都会对应有自己的
`Argument`
。
-
`Argument`
并不真正“存储”数据,而是将输入/输出数据有机地组织在一起。
-
`Argument`
并不真正“存储”数据,而是将输入/输出数据有机地组织在一起。
-
在
`Argument`
内部由:1.
`Matrix`
(二维矩阵,存储浮点类型输入/输出);2.
`IVector`
(一维数组,
**仅用于存储整型值**
,多用于自然语言处理任务)来实际存储数据。
-
在
`Argument`
内部由:1.
`Matrix`
(二维矩阵,存储浮点类型输入/输出);2.
`IVector`
(一维数组,
**仅用于存储整型值**
,多用于自然语言处理任务)来实际存储数据。
*注:本文档使用的示例任务手写数字识别不涉及一维整型数组作为输入,因此,本文档仅讨论二维稠密矩阵作为输入的情形。更多输入数据格式请参考输入/输出数据一节的内容。*
*注:本文档使用的示例任务手写数字识别不涉及一维整型数组作为输入,因此,本文档仅讨论二维稠密矩阵作为输入的情形。更多输入数据格式请参考输入/输出数据一节的内容。*
这篇文档的之后部分会使用
`argument`
来
**特指**
PaddlePaddle C-API中神经网的一个输入/输出,使用
`paddle_matrix`
**特指**
`argument`
中用于存储数据的
`Matrix`
类的对象。
这篇文档的之后部分会使用
`argument`
来
**特指**
PaddlePaddle C-API中神经网
络
的一个输入/输出,使用
`paddle_matrix`
**特指**
`argument`
中用于存储数据的
`Matrix`
类的对象。
于是,在组织神经网络输入,获取输出时,需要思考完成以下工作:
于是,在组织神经网络输入,获取输出时,需要思考完成以下工作:
1.
为每一个输入/输出创建
`argument`
;
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
```
shell
INSTALL_PREFIX
=
/path/of/capi/
PADDLE_ROOT
=
/path/of/capi
PADDLE_ROOT
=
/path/of/paddle_source/
git clone https://github.com/PaddlePaddle/Paddle.git
cmake
$PADDLE_ROOT
-DCMAKE_INSTALL_PREFIX
=
$INSTALL_PREFIX
\
cd
Paddle
mkdir
build
cd
build
cmake
-DCMAKE_INSTALL_PREFIX
=
$PADDLE_ROOT
\
-DCMAKE_BUILD_TYPE
=
Release
\
-DCMAKE_BUILD_TYPE
=
Release
\
-DWITH_C_API
=
ON
\
-DWITH_C_API
=
ON
\
-DWITH_SWIG_PY
=
OFF
\
-DWITH_SWIG_PY
=
OFF
\
-DWITH_GOLANG
=
OFF
\
-DWITH_GOLANG
=
OFF
\
-DWITH_PYTHON
=
OFF
\
-DWITH_PYTHON
=
OFF
\
-DWITH_MKLML
=
OFF
\
-DWITH_MKL
=
OFF
\
-DWITH_MKLDNN
=
OFF
\
-DWITH_GPU
=
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
```
text
├── include
├── include
...
@@ -38,29 +57,62 @@ cmake $PADDLE_ROOT -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \
...
@@ -38,29 +57,62 @@ cmake $PADDLE_ROOT -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \
├── lib
├── lib
│ ├── libpaddle_capi_engine.a
│ ├── libpaddle_capi_engine.a
│ ├── libpaddle_capi_layers.a
│ ├── libpaddle_capi_layers.a
│ ├── libpaddle_capi_shared.
dylib
│ ├── libpaddle_capi_shared.
so
│ └── libpaddle_capi_whole.a
│ └── libpaddle_capi_whole.a
└── third_party
└── 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`
动态库
1.
链接
`libpaddle_capi_shared.so`
动态库
-
使用 PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_shared.so`
时,需注意:
-
使用 PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_shared.so`
时,需注意:
1.
如果编译时指定编译CPU版本,且使用
`OpenBLAS`
矩阵库,在使用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版本,且使用
`MKL`
数学库,由于
`MKL`
库有自己独立的动态库文件,在使用PaddlePaddle C-
API开发预测程序时,需要自己链接MKL链接库。
1.
如果编译时指定编译GPU版本,CUDA相关库会在预测程序运行时动态装载,需要将CUDA相关的库设置到
`LD_LIBRARY_PATH`
环境变量中。
1.
如果编译时指定编译GPU版本,CUDA相关库会在预测程序运行时动态装载,需要将CUDA相关的库设置到
`LD_LIBRARY_PATH`
环境变量中。
-
这种方式最为简便,链接相对容易,
**在无特殊需求情况下,推荐使用此方式**
。
-
这种方式最为简便,链接相对容易,
**在无特殊需求情况下,推荐使用此方式**
。
2.
链接静态库
`libpaddle_capi_whole.a`
2.
链接静态库
`libpaddle_capi_whole.a`
-
使用PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_whole.a`
时,需注意:
-
使用PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_whole.a`
时,需注意:
1.
需要指定
`-Wl,--whole-archive`
链接选项。
1.
需要指定
`-Wl,--whole-archive`
链接选项。
1.
需要显式地链接
`gflags`
、
`glog`
、
`libz`
、
`protobuf`
等第三方库,可在
`
INSTALL_PREFIX\
third_party`
下找到。
1.
需要显式地链接
`gflags`
、
`glog`
、
`libz`
、
`protobuf`
等第三方库,可在
`
PADDLE_ROOT/
third_party`
下找到。
1.
如果在编译 C-API 时使用OpenBLAS
矩阵
库,需要显示地链接
`libopenblas.a`
。
1.
如果在编译 C-API 时使用OpenBLAS
数学
库,需要显示地链接
`libopenblas.a`
。
1.
如果在编译 C-API 是使用
MKL 矩阵库,需要显示地链接 MKL
的动态库。
1.
如果在编译 C-API 是使用
MKL数学库,需要显示地链接MKL
的动态库。
3.
链接静态库
`libpaddle_capi_layers.a`
和
`libpaddle_capi_engine.a`
3.
链接静态库
`libpaddle_capi_layers.a`
和
`libpaddle_capi_engine.a`
-
使用PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_whole.a`
时,需注意:
-
使用PaddlePaddle C-API 开发预测程序链接
`libpaddle_capi_whole.a`
时,需注意:
...
...
doc/howto/usage/capi/index_cn.rst
浏览文件 @
079b8243
...
@@ -4,6 +4,6 @@ PaddlePaddle C-API
...
@@ -4,6 +4,6 @@ PaddlePaddle C-API
.. toctree::
.. toctree::
:maxdepth: 1
:maxdepth: 1
compile_paddle_lib.md
compile_paddle_lib
_cn
.md
organization_of_the_inputs.md
organization_of_the_inputs
_cn
.md
a_simple_example.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 @@
...
@@ -260,6 +260,8 @@
</table>
</table>
</html>
</html>
<br>
<br>
### 输出数据
### 输出数据
PaddlePaddle中一个计算层的输出数据组织方式和输入数据组织方式完全相同。一个输出数据同样被组织为一个
`argument`
,
`argument`
通过
`paddle_matrix`
或
`paddle_ivector`
存数数据,如果输出是一个序列,那么会携带有
`sequence_start_positions`
信息。调用C-API相关接口,读取需要的结果即可。
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录