1 #include "caffe2/operators/logit_op.h" 2 #include "caffe2/operators/elementwise_op.h" 7 : eps_(op.GetSingleArgument<
float>(
"eps", 1e-6f)) {
8 CAFFE_ENFORCE_GT(eps_, 0.0);
9 CAFFE_ENFORCE_LT(eps_, 0.5);
13 operator()(
const int n,
const T* x, T* y,
CPUContext* ) {
14 ConstEigenArrayMap<T> X(x, n, 1);
15 EigenArrayMap<T> Y(y, n, 1);
18 Y = X.min(k_one - eps_);
20 Y = (Y / (k_one - Y)).log();
29 const auto& X = Input(0);
30 const auto& dY = Input(1);
33 int channels = X.dim32(X.ndim() - 1);
34 ConstEigenArrayMap<float> Xmat(
35 X.template data<float>(), channels, X.size() / channels);
36 ConstEigenArrayMap<float> dYmat(
37 dY.template data<float>(), channels, X.size() / channels);
38 EigenArrayMap<float> dXmat(
39 dX->template mutable_data<float>(), channels, X.size() / channels);
40 dXmat = (Xmat < eps_ || Xmat > 1.0 - eps_)
41 .select(0, dYmat * ((1 - Xmat) * Xmat).inverse());
45 REGISTER_CPU_OPERATOR(
54 OPERATOR_SCHEMA(Logit)
57 .AllowInplace({{0, 0}})
58 .IdenticalTypeAndShape()
60 Elementwise logit transform: logit(x) = log(x / (1 - x)), where x is the 61 input data clampped in (eps, 1-eps). 63 .Arg("eps (optional)",
"small positive epsilon value, the default is 1e-6.")
64 .Input(0,
"X",
"input float tensor")
65 .Output(0,
"Y",
"output float tensor");
67 OPERATOR_SCHEMA(LogitGradient)
70 .Input(0,
"X",
"input float tensor")
71 .Input(1,
"dY",
"input float tensor")
72 .Output(0,
"dX",
"output float tensor")
73 .Arg(
"eps",
"small positive epsilon value, the default is 1e-6.");
76 using GradientMakerBase::GradientMakerBase;
77 vector<OperatorDef> GetGradientDefs()
override {
78 return vector<OperatorDef>{CreateOperatorDef(
81 std::vector<string>{I(0), GO(0)},
82 std::vector<string>{GI(0)})};
86 REGISTER_GRADIENT(Logit, GetLogitGradient);
The CPU Context, representing the bare minimum of what a Context class in Caffe2 should implement...
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...