Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
Paddle
提交
58419e7c
P
Paddle
项目概览
BaiXuePrincess
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
58419e7c
编写于
8月 29, 2017
作者:
Q
qingqing01
提交者:
GitHub
8月 29, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3734 from qingqing01/write_new_op
Update doc about how to write new operators.
上级
75e16bd3
751d8533
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
41 addition
and
17 deletion
+41
-17
doc/howto/dev/new_op_cn.md
doc/howto/dev/new_op_cn.md
+40
-16
python/paddle/v2/framework/tests/gradient_checker.py
python/paddle/v2/framework/tests/gradient_checker.py
+1
-1
未找到文件。
doc/howto/dev/new_op_cn.md
浏览文件 @
58419e7c
...
@@ -5,12 +5,13 @@
...
@@ -5,12 +5,13 @@
-
[
定义ProtoMaker类
](
#定义ProtoMaker类
)
-
[
定义ProtoMaker类
](
#定义ProtoMaker类
)
-
[
定义Operator类
](
#定义Operator类
)
-
[
定义Operator类
](
#定义Operator类
)
-
[
定义OpKernel类
](
#定义OpKernel类
)
-
[
定义OpKernel类
](
#定义OpKernel类
)
-
[
注册
类
](
#注册类
)
-
[
注册
Operator
](
#注册Operator
)
-
[
编译
](
#编译
)
-
[
编译
](
#编译
)
-
[
绑定Python
](
#绑定Python
)
-
[
绑定Python
](
#绑定Python
)
-
[
实现单元测试
](
#实现单元测试
)
-
[
实现单元测试
](
#实现单元测试
)
-
[
前向Operator单测
](
#前向Operator单测
)
-
[
前向Operator单测
](
#前向Operator单测
)
-
[
反向Operator单测
](
#反向Operator单测
)
-
[
反向Operator单测
](
#反向Operator单测
)
-
[
编译和执行
](
#编译和执行
)
## 概念简介
## 概念简介
...
@@ -22,19 +23,17 @@
...
@@ -22,19 +23,17 @@
-
`framework::OperatorWithKernel`
:继承自OperatorBase,Op有计算函数,称作有Kernel。
-
`framework::OperatorWithKernel`
:继承自OperatorBase,Op有计算函数,称作有Kernel。
-
`class OpProtoAndCheckerMaker`
:描述该Op的输入、输出、属性、注释,主要用于Python API接口生成
-
`class OpProtoAndCheckerMaker`
:描述该Op的输入、输出、属性、注释,主要用于Python API接口生成
依据是否包含kernel,将Op分为两种:包含Kernel的Op和不包含kernel的Op,前者Op的定义继承自
`OperatorBase`
,后者继承自
`OperatorWithKernel`
。本教程主要介绍带Kernel的Op如何写,简单总结如下:
依据是否包含kernel,将Op分为两种:包含Kernel的Op和不包含kernel的Op,前者Op的定义继承自
`OperatorBase`
,后者继承自
`OperatorWithKernel`
。本教程主要介绍带Kernel的Op如何写,简单总结
Op需要包含的内容
如下:
Forward Op需要包含:
内容 | 定义位置
-
OpProtoMake定义
-------------- | :----------------------
-
Op定义
OpProtoMake定义 |
`.cc`
文件,Backward Op不需要定义OpProtoMake
-
Kernel实现
Op定义 |
`.cc`
文件
Kernel实现 | CPU、GPU共享Kernel在
`.h`
文件,否则,CPU可以在
`.cc`
文件,GPU可在
`.cu`
文件。
注册Op | Op注册在
`.cc`
文件;Kernel注册CPU在
`.cc`
文件,GPU在
`.cu`
文件
与之对应的Backward Op包含:
-
Op定义
-
Kernel实现
下面以矩阵乘操作,即
[
MulOp
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/mul_op.cc
)
为例来介绍如何写带Kernel的Operator。
下面以矩阵乘操作,即
[
MulOp
](
https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/mul_op.cc
)
为例来介绍如何写带Kernel的Operator。
...
@@ -137,8 +136,9 @@ MulOp(const std::string &type, const framework::VariableNameMap &inputs,
...
@@ -137,8 +136,9 @@ MulOp(const std::string &type, const framework::VariableNameMap &inputs,
```
```
还需要重写
`InferShape`
接口。
`InferShape`
为const函数,不能修改Op的成员变量,参数为
`const framework::InferShapeContext &ctx`
,通过该参数可获取到输入输出以及属性。它的功能是:
还需要重写
`InferShape`
接口。
`InferShape`
为const函数,不能修改Op的成员变量,参数为
`const framework::InferShapeContext &ctx`
,通过该参数可获取到输入输出以及属性。它的功能是:
-
1). 做检查, 尽早报错:检查输入数据维度、类型等是否合法
-
2). 设置输出Tensor的形状
-
1). 做检查, 尽早报错:检查输入数据维度、类型等是否合法。
-
2). 设置输出Tensor的形状。
通常
`OpProtoMaker`
和
`Op`
类的定义写在
`.cc`
文件中,和要讲到的注册函数一起放在
`.cc`
中
通常
`OpProtoMaker`
和
`Op`
类的定义写在
`.cc`
文件中,和要讲到的注册函数一起放在
`.cc`
中
...
@@ -172,7 +172,7 @@ class MulKernel : public framework::OpKernel {
...
@@ -172,7 +172,7 @@ class MulKernel : public framework::OpKernel {
到此前向Op实现完成,需要在
`.cc`
文件中注册该op和kernel。反向Op类的定义和Kernel定义与前向Op类似,这里不再重复。但注意,反向Op没有
`ProtoMaker`
。
到此前向Op实现完成,需要在
`.cc`
文件中注册该op和kernel。反向Op类的定义和Kernel定义与前向Op类似,这里不再重复。但注意,反向Op没有
`ProtoMaker`
。
### 4. 注册
类
### 4. 注册
Operator
在
`.cc`
文件中注册前向、反向Op类,注册CPU Kernel。
在
`.cc`
文件中注册前向、反向Op类,注册CPU Kernel。
...
@@ -297,4 +297,28 @@ class TestMulOp(unittest.TestCase):
...
@@ -297,4 +297,28 @@ class TestMulOp(unittest.TestCase):
-
调用
`create_op("mul")`
创建反向Op对应的前向Op。
-
调用
`create_op("mul")`
创建反向Op对应的前向Op。
-
定义输入
`inputs`
。
-
定义输入
`inputs`
。
-
调用
`compare_grad`
函数对比CPU、GPU计算结果。
-
调用
`compare_grad`
函数对比CPU、GPU计算结果。
-
调用
`check_grad`
检查梯度稳定性。
-
调用
`check_grad`
检查梯度稳定性,这里采用数值法检测梯度正确性。
-
第一个参数
`op`
: 前向op。
-
第二个参数
`inputs`
: 输入词典,词典的Key和
`ProtoMaker`
定义保持一致。
-
第三个参数
`set(["X", "Y"])`
: 指定对输入变量
`X`
、
`Y`
做梯度检测。
-
第四个参数
`"Out"`
: 指定前向网络最终的输出目标变量
`Out`
### 编译和执行
单测完成之后,在
[
`python/paddle/v2/framework/tests/CMakeLists.txt`
](
https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/v2/framework/tests/CMakeLists.txt
)
里添加编译:
```
py_test(test_mul_op SRCS test_mul_op.py)
```
编译时需要打开
`WITH_TESTING`
, 即
`cmake paddle_dir -DWITH_TESTING=ON`
,编译成功之后执行单测命令为:
```
make test ARGS="-R test_mul_op -V"
```
或者:
```
ctest -R test_mul_op
```
python/paddle/v2/framework/tests/gradient_checker.py
浏览文件 @
58419e7c
...
@@ -268,7 +268,7 @@ class GradientChecker(unittest.TestCase):
...
@@ -268,7 +268,7 @@ class GradientChecker(unittest.TestCase):
:param input_vars: numpy value of input variable. The following
:param input_vars: numpy value of input variable. The following
computation will use these variables.
computation will use these variables.
:param inputs_to_check: inputs var names that should check gradient.
:param inputs_to_check: inputs var names that should check gradient.
:param output_name:
output name that used to
:param output_name:
the output variable name of forward network.
:param max_relative_error: The relative tolerance parameter.
:param max_relative_error: The relative tolerance parameter.
:param no_grad_set: used when create backward ops
:param no_grad_set: used when create backward ops
:param only_cpu: only compute and check gradient on cpu kernel.
:param only_cpu: only compute and check gradient on cpu kernel.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录