1 #include "caffe2/core/operator_gradient.h" 2 #include "caffe2/operators/reduce_front_back_sum_mean_ops.h" 6 #define REDUCTION_OP_SHAPE_INFERENCE(is_front_reducer) \ 7 CAFFE_ENFORCE_LE(1, in.size()); \ 8 CAFFE_ENFORCE_GE(2, in.size()); \ 9 ArgumentHelper helper(def); \ 10 int num_reduce_dims = helper.GetSingleArgument<int>("num_reduce_dim", 1); \ 11 int start_index = is_front_reducer ? num_reduce_dims : 0; \ 12 int end_index = is_front_reducer ? in[0].dims_size() \ 13 : in[0].dims_size() - num_reduce_dims; \ 14 vector<int> output_shape; \ 15 for (int i = start_index; i < end_index; ++i) { \ 16 output_shape.push_back(in[0].dims(i)); \ 18 return vector<TensorShape>{ \ 19 CreateTensorShape(output_shape, in[0].data_type())}; 28 void SumReduceDimsOp<CPUContext, true, true>::Compute(
32 const int32_t* lengths_data,
34 for (
int j = 0; j < cols; j++) {
36 int length = lengths_data ==
nullptr ? rows : lengths_data[j];
37 for (
int i = 1; i < length; i++) {
38 sum += in_data[i * cols + j];
40 out_data[j] = sum / length;
47 void SumReduceDimsOp<CPUContext, false, true>::Compute(
51 const int32_t* lengths_data,
53 for (
int i = 0; i < rows; i++) {
54 int offset = i * cols;
55 T sum = in_data[offset];
56 int length = lengths_data ==
nullptr ? cols : lengths_data[i];
57 for (
int j = 1; j < length; j++) {
58 sum += in_data[offset + j];
60 out_data[i] = sum / length;
67 void SumReduceDimsGradientOp<CPUContext, true, true>::Compute(
71 const int* lengths_data,
73 for (
int i = 0; i < rows * cols; i++) {
76 if (lengths_data ==
nullptr) {
77 dXdata[i] = dYdata[col] / rows;
78 }
else if (row < lengths_data[col]) {
79 dXdata[i] = dYdata[col] / lengths_data[col];
89 void SumReduceDimsGradientOp<CPUContext, false, true>::Compute(
93 const int* lengths_data,
95 for (
int i = 0; i < rows * cols; i++) {
98 if (lengths_data ==
nullptr) {
99 dXdata[i] = dYdata[row] / cols;
100 }
else if (col < lengths_data[row]) {
101 dXdata[i] = dYdata[row] / lengths_data[row];
108 REGISTER_CPU_OPERATOR(ReduceFrontMean, SumReduceDimsOp<CPUContext, true, true>);
109 REGISTER_CPU_OPERATOR(
110 ReduceFrontMeanGradient,
111 SumReduceDimsGradientOp<CPUContext, true, true>);
114 using GradientMakerBase::GradientMakerBase;
115 vector<OperatorDef> GetGradientDefs()
override {
116 vector<string> grad_in = {GO(0), I(0)};
117 if (def_.input_size() == 2) {
118 grad_in.push_back(I(1));
121 "ReduceFrontMeanGradient",
"", grad_in, vector<string>{GI(0)});
127 OPERATOR_SCHEMA(ReduceFrontMean)
132 "(*int*): number of dimensions to reduce (default=1)")
134 Reduces the input tensor along the last dimension of the by applying **mean**. 136 Can reduce more than one of the "first" dimensions by setting `num_reduce_dim`. 138 A second (optional) input, `lengths`, can be passed, which enforces that only a subset of the elements are considered in the mean operation. 139 - If input tensor `X` has shape $(d_0, d_1, d_2, ..., d_n)$, `lengths` must have shape $(d_1 * d_2 * ... * d_{n})$. 140 - The values of the `lengths` tensor determine how many of the values to consider for each vector in the $d_{0}$ dimension. 142 For example if $X = [[1,5,2,9],[4,1,8,2],[2,7,0,3]]$ and $lengths = [2,3,1,2]$, then $Y = [mean(1,4), mean(5,1,7), mean(2), mean(9,2)] = [2.5, 4.333, 2, 5.5]$ 145 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/reduce_front_back_mean_ops.cc 149 <summary> <b>Example</b> </summary> 155 workspace.ResetWorkspace() 157 op = core.CreateOperator( 164 workspace.FeedBlob("X", np.random.randint(10, size=(2,3,3)).astype(np.float32)) 165 print("X:", workspace.FetchBlob("X")) 166 workspace.RunOperatorOnce(op) 167 print("Y:", workspace.FetchBlob("Y")) 183 Y: [4.3333335 2.1666667 6.] 190 .Input(0, "X",
"(*Tensor`<float>`*): input tensor")
191 .Input(1,
"lengths",
"(*Tensor`<int>`*): number of elements in each sample")
192 .Output(0,
"Y",
"(*Tensor`<float>`*): reduced tensor")
193 .TensorInferenceFunction([](
const OperatorDef& def,
194 const vector<TensorShape>& in) {
195 REDUCTION_OP_SHAPE_INFERENCE(
true)
197 .InheritOnnxSchema(
"ReduceMean");
198 OPERATOR_SCHEMA(ReduceFrontMeanGradient).NumInputs(2, 3).NumOutputs(1);
201 REGISTER_CPU_OPERATOR(
202 ReduceBackMeanGradient,
206 using GradientMakerBase::GradientMakerBase;
207 vector<OperatorDef> GetGradientDefs()
override {
208 vector<string> grad_in = {GO(0), I(0)};
209 if (def_.input_size() == 2) {
210 grad_in.push_back(I(1));
213 "ReduceBackMeanGradient",
"", grad_in, vector<string>{GI(0)});
217 REGISTER_GRADIENT(ReduceBackMean, GetReduceBackMeanGradient);
219 OPERATOR_SCHEMA(ReduceBackMean)
224 "(*int*): number of dimensions to reduce (default=1)")
226 Reduces the input tensor along the last dimension of the by applying **mean**. 228 Can reduce more than one of the "last" dimensions by setting `num_reduce_dim`. 230 A second (optional) input, `lengths`, can be passed, which enforces that only a subset of the elements are considered in the mean operation. 231 - If input tensor `X` has shape $(d_0, d_1, d_2, ..., d_n)$, `lengths` must have shape $(d_0 * d_1 * d_2 * ... * d_{n-1})$. 232 - The values of the `lengths` tensor determine how many of the values to consider for each vector in the $d_{n-1}$ dimension. 234 For example if $X = [[1,5,2,9],[4,1,8,2],[2,7,0,3]]$ and $lengths = [2,3,1]$, then $Y = [mean(1,5), mean(4,1,8), mean(2)] = [3, 4.333, 2]$ 238 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/reduce_front_back_mean_ops.cc 242 <summary> <b>Example</b> </summary> 248 workspace.ResetWorkspace() 250 op = core.CreateOperator( 257 workspace.FeedBlob("X", np.random.randint(10, size=(1,2,3,3)).astype(np.float32)) 258 print("X:", workspace.FetchBlob("X")) 259 workspace.RunOperatorOnce(op) 260 print("Y:", workspace.FetchBlob("Y")) 276 Y: [[3.7777777 4.888889 ]] 283 .Input(0, "X",
"(*Tensor`<float>`*): input tensor")
284 .Input(1,
"lengths",
"(*Tensor`<int>`*): number of elements in each sample")
285 .Output(0,
"Y",
"(*Tensor`<float>`*): reduced tensor")
286 .TensorInferenceFunction([](
const OperatorDef& def,
287 const vector<TensorShape>& in) {
288 REDUCTION_OP_SHAPE_INFERENCE(
false)
290 .InheritOnnxSchema(
"ReduceMean");
291 OPERATOR_SCHEMA(ReduceBackMeanGradient).NumInputs(2, 3).NumOutputs(1);
293 #undef REDUCTION_OP_SHAPE_INFERENCE
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 ...