Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
c19eae4c
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看板
提交
c19eae4c
编写于
8月 29, 2017
作者:
Q
qingqing01
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update doc about how to write new operators.
上级
d78521d4
变更
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
浏览文件 @
c19eae4c
...
@@ -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,18 +23,16 @@
...
@@ -22,18 +23,16 @@
-
`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定义
-------------- | :----------------------
-
Kernel实现
OpProtoMake定义 |
`.cc`
文件,Backward Op不需要定义OpProtoMake
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)
```
编译完成之后即可执行单测:
```
make test ARGS="-R test_mul_op -V"
```
或者:
```
ctest -R test_mul_op
```
python/paddle/v2/framework/tests/gradient_checker.py
浏览文件 @
c19eae4c
...
@@ -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 final output variable name.
: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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录