1 #include "caffe2/operators/relu_op.h" 7 #include "caffe2/utils/eigen_utils.h" 13 bool ReluFunctor<CPUContext>::
14 operator()(
const int N,
const T* X,
T* Y, CPUContext* )
const {
15 EigenVectorMap<T>(Y, N) = ConstEigenVectorMap<float>(X, N).cwiseMax(
T(0));
19 #ifdef CAFFE2_USE_ACCELERATE 23 bool ReluFunctor<CPUContext>::operator()<
float>(
28 const float zero = 0.0f;
29 vDSP_vthres(X, 1, &zero, Y, 1, N);
33 #endif // CAFFE2_USE_ACCELERATE 37 bool ReluGradientFunctor<CPUContext>::Forward(
38 const std::vector<int>& Y_dims,
39 const std::vector<int>& ,
44 const int size = std::accumulate(
45 Y_dims.cbegin(), Y_dims.cend(), 1, std::multiplies<int>());
46 EigenVectorArrayMap<T>(dX, size) =
47 (ConstEigenVectorArrayMap<T>(Y, size) >
T(0))
48 .select(ConstEigenVectorArrayMap<T>(dY, size),
T(0));
54 OpSchema::Cost CostInferenceForRelu(
55 const OperatorDef& def,
56 const vector<TensorShape>& in) {
57 struct OpSchema::Cost cost = PointwiseCostInference<0>(def, in);
58 cost.params_bytes = 0;
64 REGISTER_CPU_OPERATOR(
69 ReluFunctor<CPUContext>>);
70 REGISTER_CPU_GRADIENT_OPERATOR(
75 ReluGradientFunctor<CPUContext>>);
81 .AllowInplace({{0, 0}})
82 .CostInferenceFunction(CostInferenceForRelu)
83 .IdenticalTypeAndShape()
85 Applies rectified linear unit operation to the input data element-wise. The Relu operation takes one input $X$, produces one output $Y$, and is defined as: 90 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/relu_op.h 91 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/relu_op.cc 95 <summary> <b>Example</b> </summary> 100 workspace.ResetWorkspace() 102 op = core.CreateOperator( 108 workspace.FeedBlob("X", np.random.randn(4, 4).astype(np.float32)) // NCHW 109 print("X:\n", workspace.FetchBlob("X"), "\n") 111 workspace.RunOperatorOnce(op) 112 print("Y:\n", workspace.FetchBlob("Y")) 121 [[-1.4655551 0.64575136 0.7921748 0.4150579 ] 122 [ 0.41085166 -0.2837964 0.9881425 -1.9300346 ] 123 [ 0.39705405 0.44639114 0.9940703 0.2926532 ] 124 [-0.6726489 0.01330667 1.101319 0.33858967]] 127 [[0. 0.64575136 0.7921748 0.4150579 ] 128 [0.41085166 0. 0.9881425 0. ] 129 [0.39705405 0.44639114 0.9940703 0.2926532 ] 130 [0. 0.01330667 1.101319 0.33858967]] 138 .Input(0, "X",
"1D input tensor")
139 .Output(0,
"Y",
"1D output tensor with same shape as input")
140 .InheritOnnxSchema();
143 GRADIENT_OPERATOR_SCHEMA(ReluGradient)
146 .AllowInplace({{1, 0}})
148 ReluGradient takes both Y and dY and uses this to update dX according to the 149 chain rule and derivatives of the rectified linear function. 154 class GetReluGradient :
public GradientMakerBase {
155 using GradientMakerBase::GradientMakerBase;
156 std::vector<OperatorDef> GetGradientDefs()
override {
157 return SingleGradientDef(
158 def_.type() +
"Gradient",
160 std::vector<std::string>{O(0), GO(0)},
161 std::vector<std::string>{GI(0)});
167 REGISTER_GRADIENT(
Relu, GetReluGradient);
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...