Caffe2 - C++ API
A deep learning, cross platform ML framework
logit_op.cc
1 
16 #include "caffe2/operators/logit_op.h"
17 #include "caffe2/operators/elementwise_op.h"
18 
19 namespace caffe2 {
21  explicit LogitCPUFunctor(OperatorBase& op)
22  : eps_(op.GetSingleArgument<float>("eps", 1e-6f)) {
23  CAFFE_ENFORCE_GT(eps_, 0.0);
24  CAFFE_ENFORCE_LT(eps_, 0.5);
25  }
26  template <typename T>
27  inline void
28  operator()(const int n, const T* x, T* y, CPUContext* /* unused */) {
29  ConstEigenArrayMap<T> X(x, n, 1);
30  EigenArrayMap<T> Y(y, n, 1);
31  const T k_one = 1.0;
32 
33  Y = X.min(k_one - eps_);
34  Y = Y.max(eps_);
35  Y = (Y / (k_one - Y)).log();
36  }
37 
38  private:
39  float eps_;
40 };
41 
42 template <>
44  const auto& X = Input(0);
45  const auto& dY = Input(1);
46  auto* dX = Output(0);
47  dX->ResizeLike(X);
48  int channels = X.dim32(X.ndim() - 1);
49  ConstEigenArrayMap<float> Xmat(
50  X.template data<float>(), channels, X.size() / channels);
51  ConstEigenArrayMap<float> dYmat(
52  dY.template data<float>(), channels, X.size() / channels);
53  EigenArrayMap<float> dXmat(
54  dX->template mutable_data<float>(), channels, X.size() / channels);
55  dXmat = (Xmat < eps_ || Xmat > 1.0 - eps_)
56  .select(0, dYmat * ((1 - Xmat) * Xmat).inverse());
57  return true;
58 }
59 
60 REGISTER_CPU_OPERATOR(
61  Logit,
64  CPUContext,
66 
67 REGISTER_CPU_OPERATOR(LogitGradient, LogitGradientOp<float, CPUContext>);
68 
69 OPERATOR_SCHEMA(Logit)
70  .NumInputs(1)
71  .NumOutputs(1)
72  .AllowInplace({{0, 0}})
73  .IdenticalTypeAndShape()
74  .SetDoc(R"DOC(
75 Elementwise logit transform: logit(x) = log(x / (1 - x)), where x is the
76 input data clampped in (eps, 1-eps).
77 )DOC")
78  .Arg("eps (optional)", "small positive epsilon value, the default is 1e-6.")
79  .Input(0, "X", "input float tensor")
80  .Output(0, "Y", "output float tensor");
81 
82 OPERATOR_SCHEMA(LogitGradient)
83  .NumInputs(2)
84  .NumOutputs(1)
85  .Input(0, "X", "input float tensor")
86  .Input(1, "dY", "input float tensor")
87  .Output(0, "dX", "output float tensor")
88  .Arg("eps", "small positive epsilon value, the default is 1e-6.");
89 
90 class GetLogitGradient : public GradientMakerBase {
91  using GradientMakerBase::GradientMakerBase;
92  vector<OperatorDef> GetGradientDefs() override {
93  return vector<OperatorDef>{CreateOperatorDef(
94  "LogitGradient",
95  "",
96  std::vector<string>{I(0), GO(0)},
97  std::vector<string>{GI(0)})};
98  }
99 };
100 
101 REGISTER_GRADIENT(Logit, GetLogitGradient);
102 } // namespace caffe2
The CPU Context, representing the bare minimum of what a Context class in Caffe2 should implement...
Definition: context.h:82
Copyright (c) 2016-present, Facebook, Inc.