|
|
|
@ -27,6 +27,7 @@ class SigmoidKernel : public OpKernel {
|
|
|
|
|
auto output = context.Output<Tensor>(0);
|
|
|
|
|
output->mutable_data<T>(context.GetPlace());
|
|
|
|
|
|
|
|
|
|
// The clipping is used in Paddle's raw implenmention
|
|
|
|
|
auto X = EigenVector<T>::Flatten(*input);
|
|
|
|
|
auto Y = EigenVector<T>::Flatten(*output);
|
|
|
|
|
auto place = context.GetEigenDevice<Place>();
|
|
|
|
@ -34,5 +35,23 @@ class SigmoidKernel : public OpKernel {
|
|
|
|
|
Y.device(place) = 1.0 / (1.0 + (-1.0 * X).exp());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename Place, typename T>
|
|
|
|
|
class SigmoidGradKernel : public OpKernel {
|
|
|
|
|
public:
|
|
|
|
|
void Compute(const ExecutionContext& context) const override {
|
|
|
|
|
auto Y_t = context.Input<Tensor>("Y");
|
|
|
|
|
auto dY_t = context.Input<Tensor>(framework::GradVarName("Y"));
|
|
|
|
|
auto dX_t = context.Output<Tensor>(framework::GradVarName("X"));
|
|
|
|
|
|
|
|
|
|
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 paddle
|
|
|
|
|