Caffe2 - C++ API
A deep learning, cross platform ML framework
softsign_op.cc
1 #include "caffe2/operators/elementwise_op.h"
2 #include "caffe2/utils/math.h"
3 
4 namespace caffe2 {
5 
7  template <typename T>
8  inline void
9  operator()(const int n, const T* x, T* y, CPUContext* /*device_context*/) {
10  ConstEigenVectorArrayMap<T> x_arr(x, n);
11  EigenVectorMap<T>(y, n) = (1 + x_arr.abs()).inverse() * x_arr;
12  }
13 };
14 
16  template <typename T>
17  inline void Run(
18  const int n,
19  const T* x,
20  const T* dy,
21  T* dx,
22  CPUContext* /*device_context*/) {
23  ConstEigenVectorArrayMap<T> dy_arr(dy, n);
24  ConstEigenVectorArrayMap<T> x_arr(x, n);
25  EigenVectorMap<T>(dx, n) = dy_arr * (1 + x_arr.abs()).pow(2).inverse();
26  }
27 };
28 
29 REGISTER_CPU_OPERATOR(
30  Softsign,
32 REGISTER_CPU_OPERATOR(
33  SoftsignGradient,
36  CPUContext,
38 
39 OPERATOR_SCHEMA(Softsign)
40  .NumInputs(1)
41  .NumOutputs(1)
42  .AllowInplace({{0, 0}})
43  .IdenticalTypeAndShape()
44  .SetDoc(R"DOC(
45 Calculates the softsign (x/1+|x|) of the given input tensor element-wise. This
46 operation can be done in an in-place fashion too, by providing the same input
47 and output blobs.
48 )DOC")
49  .Input(0, "input", "1-D input tensor")
50  .Output(
51  0,
52  "output",
53  "The softsign (x/1+|x|) values of the input tensor "
54  "computed element-wise")
55  .InheritOnnxSchema("Softsign");
56 
57 OPERATOR_SCHEMA(SoftsignGradient)
58  .NumInputs(2)
59  .NumOutputs(1)
60  .AllowInplace({{1, 0}})
61  .SetDoc(R"DOC(
62 Calculates the softsign gradient (sgn(x)/(1+|x|)^2) of the given input tensor
63 element-wise.
64 )DOC")
65  .Input(0, "input", "1-D input tensor")
66  .Input(1, "input", "1-D input tensor")
67  .Output(
68  0,
69  "output",
70  "The softsign gradient (sgn(x)/(1+|x|)^2) values of the input tensor "
71  "computed element-wise");
72 
74  using GradientMakerBase::GradientMakerBase;
75  vector<OperatorDef> GetGradientDefs() override {
76  CAFFE_ENFORCE(
77  I(0) != O(0),
78  "Cannot compute softsign gradient "
79  "if you choose to do an in-place calculation.");
80 
81  return SingleGradientDef(
82  "SoftsignGradient",
83  "",
84  vector<string>{I(0), GO(0)},
85  vector<string>{GI(0)});
86  }
87 };
88 
89 REGISTER_GRADIENT(Softsign, GetSoftsignGradient);
90 
91 } // namespace caffe2
The CPU Context, representing the bare minimum of what a Context class in Caffe2 should implement...
Definition: context.h:66
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Performs a binary operation (e.g.