提交 0560733c 编写于 作者: D dangqingqing

Add sigmoid backward implenmention.

上级 f70e8077
...@@ -37,10 +37,12 @@ public: ...@@ -37,10 +37,12 @@ public:
class SigmoidOpGrad : public OperatorWithKernel { class SigmoidOpGrad : public OperatorWithKernel {
protected: protected:
void InferShape(const InferShapeContext &ctx) const override {} void InferShape(const InferShapeContext &ctx) const override {
std::string DebugString() const override { PADDLE_ENFORCE(ctx.InputSize() == 1,
LOG(INFO) << "SigmoidGrad"; "Sigmoid Gradient Op only have one input");
return ""; PADDLE_ENFORCE(ctx.OutputSize() == 1,
"Sigmoid Gradient Op only have one output");
ctx.Output<Tensor>(0)->Resize(ctx.Input<Tensor>(0)->dims());
} }
}; };
...@@ -51,3 +53,5 @@ REGISTER_OP(sigmoid, ops::SigmoidOp, ops::SigmoidOpMaker); ...@@ -51,3 +53,5 @@ REGISTER_OP(sigmoid, ops::SigmoidOp, ops::SigmoidOpMaker);
REGISTER_GRADIENT_OP(sigmoid, sigmoid_grad, ops::SigmoidOpGrad); REGISTER_GRADIENT_OP(sigmoid, sigmoid_grad, ops::SigmoidOpGrad);
REGISTER_OP_CPU_KERNEL(sigmoid, ops::SigmoidKernel<ops::CPUPlace, float>); REGISTER_OP_CPU_KERNEL(sigmoid, ops::SigmoidKernel<ops::CPUPlace, float>);
REGISTER_OP_CPU_KERNEL(sigmoid_grad,
ops::SigmoidGradKernel<ops::CPUPlace, float>);
#include "paddle/operators/sigmoid_op.h" #include "paddle/operators/sigmoid_op.h"
REGISTER_OP_GPU_KERNEL(sigmoid, ops::SigmoidKernel<ops::GPUPlace, float>); REGISTER_OP_GPU_KERNEL(sigmoid, ops::SigmoidKernel<ops::GPUPlace, float>);
REGISTER_OP_GPU_KERNEL(sigmoid_grad, ops::SigmoidGradKernel<ops::GPUPlace, float>);
...@@ -32,5 +32,24 @@ public: ...@@ -32,5 +32,24 @@ public:
1.0 / (1.0 + (-1.0 * EigenVector<T>::Flatten(*input)).exp()); 1.0 / (1.0 + (-1.0 * EigenVector<T>::Flatten(*input)).exp());
} }
}; };
template <typename Place, typename T>
class SigmoidGradKernel : public OpKernel {
public:
void Compute(const ExecutionContext& context) const override {
// TODO(qingqing) maybe a helper funciton is needed fo the name x@GRAD
auto y_t = context.Input<Tensor>("Y");
auto dy_t = context.Input<Tensor>("Y@GRAD");
auto dx_t = context.Output<Tensor>("X@GRAD");
dx_t->mutable_data<T>(context.GetPlace());
auto dx = EigenVector<T>::Flatten(*dx_t);
auto y = EigenVector<T>::Flatten(*y_t);
auto dy = EigenVector<T>::Flatten(*dy_t);
dx.device(*(context.GetEigenDevice<Place>())) = dy * y * (1. - y);
}
};
} // namespace operators } // namespace operators
} // namespace paddle } // namespace paddle
...@@ -12,5 +12,16 @@ class TestSigmoidOp(unittest.TestCase): ...@@ -12,5 +12,16 @@ class TestSigmoidOp(unittest.TestCase):
self.Y = 1 / (1 + np.exp(-self.X)) self.Y = 1 / (1 + np.exp(-self.X))
#class TestSigmoidGradOp(unittest.TestCase):
# __metaclass__ = OpTestMeta
#
# def setUp(self):
# self.type = "sigmoid_grad"
# self.Y = np.random.random((32, 100)).astype("float32")
# self.dY = np.random.random((32, 100)).astype("float32")
# self.dX = self.dY * self.Y * (1 - self.Y)
# print self.dX
#
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册