@ -1,16 +1,17 @@
/* 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
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 . */
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/softmax_op.h"
namespace paddle {
@ -19,12 +20,13 @@ namespace operators {
class SoftmaxOp : public OperatorWithKernel {
protected :
void InferShape ( const InferShapeContext & ctx ) const override {
PADDLE_ENFORCE ( ctx . InputSize ( ) = = 1 , " Only one input is need for softmax " ) ;
PADDLE_ENFORCE ( ctx . Input < Tensor > ( 0 ) - > dims ( ) . size ( ) = = 2 ,
PADDLE_ENFORCE ( ctx . InputSize ( ) = = 1UL ,
" Only one input is need for softmax " ) ;
PADDLE_ENFORCE ( ctx . Input < Tensor > ( " X " ) - > dims ( ) . size ( ) = = 2UL ,
" The input of softmax op must be matrix " ) ;
PADDLE_ENFORCE ( ctx . OutputSize ( ) = = 1 ,
PADDLE_ENFORCE ( ctx . OutputSize ( ) = = 1 UL ,
" Only one output is need for softmax " ) ;
ctx . Output < Tensor > ( 0 ) - > Resize ( ctx . Input < Tensor > ( 0 ) - > dims ( ) ) ;
ctx . Output < Tensor > ( " Y " ) - > Resize ( ctx . Input < Tensor > ( " X " ) - > dims ( ) ) ;
}
} ;
@ -40,10 +42,19 @@ public:
class SoftmaxOpGrad : public OperatorWithKernel {
protected :
void InferShape ( const InferShapeContext & ctx ) const override { }
std : : string DebugString ( ) const override {
LOG ( INFO ) < < " SoftmaxOpGrad " ;
return " " ;
void InferShape ( const InferShapeContext & ctx ) const override {
PADDLE_ENFORCE ( ctx . InputSize ( ) = = 3UL ,
" Input of SoftmaxOpGrad should be 3, X, Y, YG " ) ;
PADDLE_ENFORCE ( ctx . OutputSize ( ) = = 1UL ,
" Output of SoftmaxOpGrad should be 1 " ) ;
PADDLE_ENFORCE ( ctx . InputVar ( " Y " ) ! = nullptr , " Input(Y) should not be null " ) ;
PADDLE_ENFORCE ( ctx . InputVar ( GRAD_VAR_NAME ( " Y " ) ) ! = nullptr ,
" Input(Y@GRAD) should not be null " ) ;
PADDLE_ENFORCE ( ctx . Input < Tensor > ( " Y " ) - > dims ( ) = =
ctx . Input < Tensor > ( GRAD_VAR_NAME ( " Y " ) ) - > dims ( ) ,
" the shape of Input(0) and Input(1) should be the same " ) ;
ctx . Output < Tensor > ( GRAD_VAR_NAME ( " X " ) )
- > Resize ( ctx . Input < Tensor > ( " Y " ) - > dims ( ) ) ;
}
} ;
@ -51,5 +62,7 @@ protected:
} // namespace paddle
REGISTER_OP ( softmax , ops : : SoftmaxOp , ops : : SoftmaxOpMaker ) ;
REGISTER_GRADIENT_OP ( softmax , softmax_grad , ops : : SoftmaxOpGrad ) ;
REGISTER_OP_CPU_KERNEL ( softmax , ops : : SoftmaxKernel < ops : : CPUPlace , float > ) ;
REGISTER_GRADIENT_OP ( softmax , softmax_grad , ops : : SoftmaxOpGrad ) ;
REGISTER_OP_CPU_KERNEL ( softmax_grad ,
ops : : SoftmaxGradKernel < ops : : CPUPlace , float > ) ;