提交 ab55d793 编写于 作者: D dangqingqing

revert scatter_op and other mirror changes.

上级 95955cc7
...@@ -280,28 +280,50 @@ class TestMulOp(unittest.TestCase): ...@@ -280,28 +280,50 @@ class TestMulOp(unittest.TestCase):
反向Op单测继承自`GradientChecker`,而`GradientChecker`集成自`unittest.TestCase`,所以反向单测函数需要`test_`开头。 反向Op单测继承自`GradientChecker`,而`GradientChecker`集成自`unittest.TestCase`,所以反向单测函数需要`test_`开头。
``` ```
class MulGradOpTest(GradientChecker): class TestMulGradOp(GradientChecker):
def test_mul(self): def setUp(self):
op = create_op("mul") self.op = create_op("mul")
inputs = { self.inputs = {
'X': np.random.random((32, 84)).astype("float32"), 'X': np.random.random((32, 84)).astype("float32"),
'Y': np.random.random((84, 100)).astype("float32") 'Y': np.random.random((84, 100)).astype("float32")
} }
self.compare_grad(op, inputs)
def test_cpu_gpu_compare(self):
self.compare_grad(self.op, self.inputs)
def test_normal(self):
# mul op will enlarge the relative error # mul op will enlarge the relative error
self.check_grad( self.check_grad(
op, inputs, set(["X", "Y"]), "Out", max_relative_error=0.5) self.op, self.inputs, ["X", "Y"], "Out", max_relative_error=0.5)
```
def test_ignore_x(self):
self.check_grad(
self.op,
self.inputs, ["Y"],
"Out",
max_relative_error=0.5,
no_grad_set={"X"})
def test_ignore_y(self):
self.check_grad(
self.op,
self.inputs, ["X"],
"Out",
max_relative_error=0.5,
no_grad_set={"Y"})
```
下面解释一些关键的地方:
- 调用`create_op("mul")`创建反向Op对应的前向Op。 - 调用`create_op("mul")`创建反向Op对应的前向Op。
- 定义输入`inputs`
- 调用`compare_grad`函数对比CPU、GPU计算结果。 - 调用`compare_grad`函数对比CPU、GPU计算结果。
- 调用`check_grad`检查梯度稳定性,这里采用数值法检测梯度正确性。 - `test_normal`调用`check_grad`检查梯度稳定性,这里采用数值法检测梯度正确性。
- 第一个参数`op` : 前向op。 - 第一个参数`self.op` : 前向Op。
- 第二个参数`inputs` : 输入词典,词典的Key和`ProtoMaker`定义保持一致。 - 第二个参数`self.inputs` : 输入词典,词典的Key和`ProtoMaker`定义保持一致。
- 第三个参数`set(["X", "Y"])` : 指定对输入变量`X``Y`做梯度检测。 - 第三个参数`["X", "Y"]` : 指定对输入变量`X``Y`做梯度检测。
- 第四个参数`"Out"` : 指定前向网络最终的输出目标变量`Out` - 第四个参数`"Out"` : 指定前向网络最终的输出目标变量`Out`
- `test_ignore_x``test_ignore_y`分支测试只需要计算一个输入梯度的情况。
### 编译和执行 ### 编译和执行
......
...@@ -54,8 +54,8 @@ class MulGradKernel : public framework::OpKernel { ...@@ -54,8 +54,8 @@ class MulGradKernel : public framework::OpKernel {
auto* device_context = auto* device_context =
const_cast<platform::DeviceContext*>(ctx.device_context_); const_cast<platform::DeviceContext*>(ctx.device_context_);
if (dx) { if (dx) {
// dx = dout * y'. dx: M x K, dout : M x N, y : K x N
dx->mutable_data<T>(ctx.GetPlace()); dx->mutable_data<T>(ctx.GetPlace());
// dx = dout * y'. dx: M x K, dout : M x N, y : K x N
math::matmul<Place, T>(*dout, false, *y, true, 1, dx, 0, device_context); math::matmul<Place, T>(*dout, false, *y, true, 1, dx, 0, device_context);
} }
if (dy) { if (dy) {
......
...@@ -50,8 +50,8 @@ class ScatterGradOp : public framework::OperatorWithKernel { ...@@ -50,8 +50,8 @@ class ScatterGradOp : public framework::OperatorWithKernel {
auto *dRef = ctx.Output<Tensor>(framework::GradVarName("Ref")); auto *dRef = ctx.Output<Tensor>(framework::GradVarName("Ref"));
auto *Ref = ctx.Input<Tensor>("Ref"); auto *Ref = ctx.Input<Tensor>("Ref");
if (dRef) dRef->Resize(Ref->dims()); dRef->Resize(Ref->dims());
if (dUpdates) dUpdates->Resize(Updates->dims()); dUpdates->Resize(Updates->dims());
} }
}; };
......
...@@ -49,12 +49,10 @@ class ScatterGradientOpKernel : public framework::OpKernel { ...@@ -49,12 +49,10 @@ class ScatterGradientOpKernel : public framework::OpKernel {
auto *dOut = ctx.Input<Tensor>(framework::GradVarName("Out")); auto *dOut = ctx.Input<Tensor>(framework::GradVarName("Out"));
// In place gradient: dRef = dO // In place gradient: dRef = dO
if (dRef) dRef->ShareDataWith<T>(*dOut); dRef->ShareDataWith<T>(*dOut);
if (dUpdates) { dUpdates->mutable_data<T>(ctx.GetPlace());
dUpdates->mutable_data<T>(ctx.GetPlace()); // Gradient by Gather: dUpdates += dO[Index]
// Gradient by Gather: dUpdates += dO[Index] Gather<T>(ctx.GetPlace(), dOut, Index, dUpdates);
Gather<T>(ctx.GetPlace(), dOut, Index, dUpdates);
}
} }
}; };
......
...@@ -24,6 +24,9 @@ class TestMulGradOp(GradientChecker): ...@@ -24,6 +24,9 @@ class TestMulGradOp(GradientChecker):
'Y': np.random.random((84, 100)).astype("float32") 'Y': np.random.random((84, 100)).astype("float32")
} }
def test_cpu_gpu_compare(self):
self.compare_grad(self.op, self.inputs)
def test_normal(self): def test_normal(self):
# mul op will enlarge the relative error # mul op will enlarge the relative error
self.check_grad( self.check_grad(
......
...@@ -16,7 +16,7 @@ class TestRowwiseAddOp(unittest.TestCase): ...@@ -16,7 +16,7 @@ class TestRowwiseAddOp(unittest.TestCase):
self.outputs = {'Out': np.add(self.inputs['X'], self.inputs['b'])} self.outputs = {'Out': np.add(self.inputs['X'], self.inputs['b'])}
class RowwiseAddGradOpTest(GradientChecker): class TestRowwiseAddGradOp(GradientChecker):
def setUp(self): def setUp(self):
self.op = create_op("rowwise_add") self.op = create_op("rowwise_add")
self.inputs = { self.inputs = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册