1 #include "caffe2/operators/sparse_normalize_op.h" 2 #include "caffe2/core/tensor.h" 7 template <
typename SIndex>
8 bool SparseNormalizeOp<float, CPUContext>::DoRunWithType() {
9 const auto* indices = Input(INDICES).template data<SIndex>();
10 const auto* paramIn = Input(PARAM).template data<float>();
11 auto* paramOut = Output(OUTPUT_PARAM)->template mutable_data<float>();
12 const float kEps = 1e-12f;
15 auto n = Input(INDICES).size();
21 auto block_size = Input(GRAD).size() / n;
22 for (
int i = 0; i < n; ++i) {
23 auto idx = indices[i];
24 auto offsetIdx = idx * block_size;
25 ConstEigenVectorMap<float> xVec(paramIn + offsetIdx, block_size);
26 auto norm = xVec.template lpNorm<2>() + kEps;
28 if (use_max_norm_ && norm < norm_) {
32 for (
int j = 0; j < block_size; j++) {
33 paramOut[offsetIdx + j] = paramOut[offsetIdx + j] * (norm_ / norm);
39 REGISTER_CPU_OPERATOR(SparseNormalize, SparseNormalizeOp<float, CPUContext>);
40 OPERATOR_SCHEMA(SparseNormalize)
43 .Input(0,
"param",
"Parameters to be normalized")
44 .Input(1,
"indices",
"Sparse indices")
45 .Input(2,
"grad",
"Gradient computed")
46 .Output(0,
"output_param",
"Normalized parameters")
47 .EnforceOneToOneInplace()
50 "A bool variable to control whether to use max norm \ 51 or constant norm. When use_max_norm = false, constant norm is used so that \ 52 all the embedding vectors are scaled to have a L2 norm equals to A \ 53 (see blow arugment norm=A). If use_max_norm = true, \ 54 max norm is used so that embedding is scaled so that its l2 norm is no larger \ 55 than A. If an embedding's norm is less than A originally, \ 56 the embedding is left unchanged.\ 57 The default is True.")
58 .Arg(
"norm",
"L2 norm of the embedding. The default is 1.0.")
60 Given a sparse matrix, apply max_norm or constant_norm sparse regularization. 63 SHOULD_NOT_DO_GRADIENT(SparseNormalize); A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...