Caffe2 - C++ API
A deep learning, cross platform ML framework
softplus_op.cc
1 #include "caffe2/operators/softplus_op.h"
2 
3 #include "caffe2/utils/math.h"
4 
5 namespace caffe2 {
6 
7 template <>
8 bool SoftplusOp<float, CPUContext>::RunOnDevice() {
9  auto& X = Input(0);
10  auto* Y = Output(0);
11  Y->ResizeLike(X);
12 
13  EigenVectorMap<float>(Y->mutable_data<float>(), X.size()) =
14  (ConstEigenVectorMap<float>(X.data<float>(), X.size()).array().exp() +
15  1.0f)
16  .log();
17  return true;
18 }
19 
20 template <>
21 bool SoftplusGradientOp<float, CPUContext>::RunOnDevice() {
22  auto& Y = Input(0);
23  auto& dY = Input(1);
24  auto* dX = Output(0);
25  DCHECK_EQ(dY.size(), Y.size());
26  dX->ResizeLike(Y);
27 
28  const float* Ydata = Y.data<float>();
29  const float* dYdata = dY.data<float>();
30  float* dXdata = dX->mutable_data<float>();
31  EigenVectorArrayMap<float> dXvec(dXdata, dX->size());
32  ConstEigenVectorArrayMap<float> Yvec(Ydata, Y.size());
33  ConstEigenVectorArrayMap<float> dYvec(dYdata, dY.size());
34  dXvec = dYvec * (1.0 - (-Yvec).exp());
35  return true;
36 }
37 
38 REGISTER_CPU_OPERATOR(Softplus, SoftplusOp<float, CPUContext>);
39 REGISTER_CPU_OPERATOR(SoftplusGradient, SoftplusGradientOp<float, CPUContext>);
40 
41 // Input: X, output: Y
42 OPERATOR_SCHEMA(Softplus)
43  .NumInputs(1)
44  .NumOutputs(1)
45  .AllowInplace({{0, 0}})
46  .IdenticalTypeAndShape()
47  .SetDoc(R"DOC(
48 Softplus takes one input data (Tensor<T>) and produces one output data
49 (Tensor<T>) where the softplus function, y = ln(exp(x) + 1), is applied to
50 the tensor elementwise.
51 )DOC")
52  .Input(0, "X", "1D input tensor")
53  .Output(0, "Y", "1D input tensor")
54  .InheritOnnxSchema("Softplus");
55 
56 // Input: Y, dY, output: dX
57 OPERATOR_SCHEMA(SoftplusGradient)
58  .NumInputs(2)
59  .NumOutputs(1)
60  .AllowInplace({{1, 0}});
61 
63  using GradientMakerBase::GradientMakerBase;
64  vector<OperatorDef> GetGradientDefs() override {
65  return SingleGradientDef(
66  "SoftplusGradient",
67  "",
68  vector<string>{O(0), GO(0)},
69  vector<string>{GI(0)});
70  }
71 };
72 REGISTER_GRADIENT(Softplus, GetSoftplusGradient);
73 
74 } // namespace caffe2
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
static vector< OperatorDef > SingleGradientDef(const Args &...args)
a helper function to allow one to create one single operator def, which is usually the case for many ...