clip_by_norm_op.cc 2.7 KB
Newer Older
W
wwhu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

#include "paddle/operators/clip_by_norm_op.h"

namespace paddle {
namespace operators {

class ClipByNormOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

 protected:
  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("X"),
                   "Input(X) of ClipByNormOp should not be null.");
    PADDLE_ENFORCE(ctx->HasOutput("Out"),
                   "Output(Out) of ClipByNormOp should not be null.");
    auto max_norm = Attr<float>("max_norm");
    PADDLE_ENFORCE_GT(max_norm, 0, "max_norm should be greater than 0.");
    auto x_dims = ctx->GetInputDim("X");
    ctx->SetOutputDim("Out", x_dims);
    ctx->ShareLoD("X", /*->*/ "Out");
  }
};

template <typename AttrType>
class ClipByNormOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  ClipByNormOpMaker(framework::OpProto* proto,
W
wwhu 已提交
42
                    framework::OpAttrChecker* op_checker)
W
wwhu 已提交
43 44
      : OpProtoAndCheckerMaker(proto, op_checker) {
    AddInput("X",
W
wwhu 已提交
45
             "(Tensor) The input of clip_by_norm op."
W
wwhu 已提交
46 47
             "The number of dimensions must be between [1, 9].");
    AddOutput("Out",
W
wwhu 已提交
48
              "(Tensor) The output of clip_by_norm op with shape as input(X)");
W
fix doc  
wwhu 已提交
49
    AddAttr<AttrType>("max_norm", "(float) The maximum norm value.");
W
wwhu 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    AddComment(R"DOC(
ClipByNorm operator limits the L2 norm of the input 'X' within 'max_norm'. 
If the L2 norm of 'X' is less than or equal to 'max_norm', 'Out' will be 
the same as 'X'. If the L2 norm of 'X' is greater than 'max_norm', 'X' will 
be linearly scaled to make the L2 norm of 'Out' equal to 'max_norm', as 
shown in the following formula:

'Out' = 'max_norm' * 'X' / norm('X'),

where norm('X') represents the L2 norm of 'X'.
)DOC");
  }
};

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
W
wwhu 已提交
68
REGISTER_OP_WITHOUT_GRADIENT(clip_by_norm, ops::ClipByNormOp,
W
wwhu 已提交
69
                             ops::ClipByNormOpMaker<float>);
W
wwhu 已提交
70 71
REGISTER_OP_CPU_KERNEL(
    clip_by_norm, ops::ClipByNormKernel<paddle::platform::CPUPlace, float>);