Caffe2 - C++ API
A deep learning, cross platform ML framework
softplus_op.cc
1 
17 #include "caffe2/operators/softplus_op.h"
18 
19 #include "caffe2/utils/math.h"
20 
21 namespace caffe2 {
22 
23 template <>
24 bool SoftplusOp<float, CPUContext>::RunOnDevice() {
25  auto& X = Input(0);
26  auto* Y = Output(0);
27  Y->ResizeLike(X);
28 
29  EigenVectorMap<float>(Y->mutable_data<float>(), X.size()) =
30  (ConstEigenVectorMap<float>(X.data<float>(), X.size()).array().exp() +
31  1.0f)
32  .log();
33  return true;
34 }
35 
36 template <>
37 bool SoftplusGradientOp<float, CPUContext>::RunOnDevice() {
38  auto& Y = Input(0);
39  auto& dY = Input(1);
40  auto* dX = Output(0);
41  DCHECK_EQ(dY.size(), Y.size());
42  dX->ResizeLike(Y);
43 
44  const float* Ydata = Y.data<float>();
45  const float* dYdata = dY.data<float>();
46  float* dXdata = dX->mutable_data<float>();
47  EigenVectorArrayMap<float> dXvec(dXdata, dX->size());
48  ConstEigenVectorArrayMap<float> Yvec(Ydata, Y.size());
49  ConstEigenVectorArrayMap<float> dYvec(dYdata, dY.size());
50  dXvec = dYvec * (1.0 - (-Yvec).exp());
51  return true;
52 }
53 
54 REGISTER_CPU_OPERATOR(Softplus, SoftplusOp<float, CPUContext>);
55 REGISTER_CPU_OPERATOR(SoftplusGradient, SoftplusGradientOp<float, CPUContext>);
56 
57 // Input: X, output: Y
58 OPERATOR_SCHEMA(Softplus)
59  .NumInputs(1)
60  .NumOutputs(1)
61  .AllowInplace({{0, 0}})
62  .IdenticalTypeAndShape()
63  .SetDoc(R"DOC(
64 Softplus takes one input data (Tensor<T>) and produces one output data
65 (Tensor<T>) where the softplus function, y = ln(exp(x) + 1), is applied to
66 the tensor elementwise.
67 )DOC")
68  .Input(0, "X", "1D input tensor")
69  .Output(0, "Y", "1D input tensor");
70 
71 // Input: Y, dY, output: dX
72 OPERATOR_SCHEMA(SoftplusGradient)
73  .NumInputs(2)
74  .NumOutputs(1)
75  .AllowInplace({{1, 0}});
76 
78  using GradientMakerBase::GradientMakerBase;
79  vector<OperatorDef> GetGradientDefs() override {
80  return SingleGradientDef(
81  "SoftplusGradient",
82  "",
83  vector<string>{O(0), GO(0)},
84  vector<string>{GI(0)});
85  }
86 };
87 REGISTER_GRADIENT(Softplus, GetSoftplusGradient);
88 
89 } // namespace caffe2
Copyright (c) 2016-present, Facebook, Inc.
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 ...