|
|
@ -24,26 +24,26 @@ class GRUUnitOp : public framework::OperatorWithKernel {
|
|
|
|
using framework::OperatorWithKernel::OperatorWithKernel;
|
|
|
|
using framework::OperatorWithKernel::OperatorWithKernel;
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
protected:
|
|
|
|
void InferShape(framework::InferShapeContextBase *ctx) const override {
|
|
|
|
void InferShape(framework::InferShapeContext* ctx) const override {
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("input"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("Input"),
|
|
|
|
"Input(%s) of GRUUnitOp should not be null.", "input");
|
|
|
|
"Input(%s) of GRUUnitOp should not be null.", "Input");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("hidden_prev"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("HiddenPrev"),
|
|
|
|
"Input(%s) of GRUUnitOp should not be null.", "hidden_prev");
|
|
|
|
"Input(%s) of GRUUnitOp should not be null.", "HiddenPrev");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("weight"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("Weight"),
|
|
|
|
"Input(%s) of GRUUnitOp should not be null.", "weight");
|
|
|
|
"Input(%s) of GRUUnitOp should not be null.", "Weight");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("bias"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("Bias"),
|
|
|
|
"Input(%s) of GRUUnitOp should not be null.", "bias");
|
|
|
|
"Input(%s) of GRUUnitOp should not be null.", "Bias");
|
|
|
|
PADDLE_ENFORCE(ctx->HasOutput("gate"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasOutput("Gate"),
|
|
|
|
"Output(%s) of GRUUnitOp should not be null.", "gate");
|
|
|
|
"Output(%s) of GRUUnitOp should not be null.", "Gate");
|
|
|
|
PADDLE_ENFORCE(ctx->HasOutput("reset_hidden_prev"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasOutput("ResetHiddenPrev"),
|
|
|
|
"Output(%s) of GRUUnitOp should not be null.",
|
|
|
|
"Output(%s) of GRUUnitOp should not be null.",
|
|
|
|
"reset_hidden_prev");
|
|
|
|
"ResetHiddenPrev");
|
|
|
|
PADDLE_ENFORCE(ctx->HasOutput("hidden"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasOutput("Hidden"),
|
|
|
|
"Output(%s) of GRUUnitOp should not be null.", "hidden");
|
|
|
|
"Output(%s) of GRUUnitOp should not be null.", "Hidden");
|
|
|
|
auto input_dims = ctx->GetInputDim("input");
|
|
|
|
auto input_dims = ctx->GetInputDim("Input");
|
|
|
|
auto hidden_prev_dims = ctx->GetInputDim("hidden_prev");
|
|
|
|
auto hidden_prev_dims = ctx->GetInputDim("HiddenPrev");
|
|
|
|
auto weight_dims = ctx->GetInputDim("weight");
|
|
|
|
auto weight_dims = ctx->GetInputDim("Weight");
|
|
|
|
auto bias_dims = ctx->GetInputDim("bias");
|
|
|
|
auto bias_dims = ctx->GetInputDim("Bias");
|
|
|
|
int batch_size = input_dims[0];
|
|
|
|
int batch_size = input_dims[0];
|
|
|
|
int input_size = input_dims[1];
|
|
|
|
int input_size = input_dims[1];
|
|
|
|
int frame_size = hidden_prev_dims[1];
|
|
|
|
int frame_size = hidden_prev_dims[1];
|
|
|
@ -53,54 +53,64 @@ class GRUUnitOp : public framework::OperatorWithKernel {
|
|
|
|
int bias_width = bias_dims[1];
|
|
|
|
int bias_width = bias_dims[1];
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
input_size, frame_size * 3,
|
|
|
|
input_size, frame_size * 3,
|
|
|
|
"The innput_size must be 3 times of frame_size in GRUUnitOp.");
|
|
|
|
"The input_size must be 3 times of frame_size in GRUUnitOp.");
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
weight_height, frame_size,
|
|
|
|
weight_height, frame_size,
|
|
|
|
"The shape of weight matrix must be [frame_size, frame_size * 3].");
|
|
|
|
"The shape of Weight matrix must be [frame_size, frame_size * 3].");
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
weight_width, frame_size * 3,
|
|
|
|
weight_width, frame_size * 3,
|
|
|
|
"The shape of weight matrix must be [frame_size, frame_size * 3].");
|
|
|
|
"The shape of Weight matrix must be [frame_size, frame_size * 3].");
|
|
|
|
PADDLE_ENFORCE_EQ(bias_height, 1,
|
|
|
|
PADDLE_ENFORCE_EQ(bias_height, 1,
|
|
|
|
"The shape of bias must be [1, frame_size * 3].");
|
|
|
|
"The shape of Bias must be [1, frame_size * 3].");
|
|
|
|
PADDLE_ENFORCE_EQ(bias_width, frame_size * 3,
|
|
|
|
PADDLE_ENFORCE_EQ(bias_width, frame_size * 3,
|
|
|
|
"The shape of bias must be [1, frame_size * 3].");
|
|
|
|
"The shape of Bias must be [1, frame_size * 3].");
|
|
|
|
ctx->SetOutputDim("gate", {batch_size, frame_size * 3});
|
|
|
|
ctx->SetOutputDim("Gate", {batch_size, frame_size * 3});
|
|
|
|
ctx->SetOutputDim("reset_hidden_prev", {batch_size, frame_size});
|
|
|
|
ctx->SetOutputDim("ResetHiddenPrev", {batch_size, frame_size});
|
|
|
|
ctx->SetOutputDim("hidden", {batch_size, frame_size});
|
|
|
|
ctx->SetOutputDim("Hidden", {batch_size, frame_size});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class GRUUnitOpMaker : public framework::OpProtoAndCheckerMaker {
|
|
|
|
class GRUUnitOpMaker : public framework::OpProtoAndCheckerMaker {
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
GRUUnitOpMaker(framework::OpProto *proto,
|
|
|
|
GRUUnitOpMaker(framework::OpProto* proto,
|
|
|
|
framework::OpAttrChecker *op_checker)
|
|
|
|
framework::OpAttrChecker* op_checker)
|
|
|
|
: OpProtoAndCheckerMaker(proto, op_checker) {
|
|
|
|
: OpProtoAndCheckerMaker(proto, op_checker) {
|
|
|
|
AddInput("input",
|
|
|
|
AddInput("Input",
|
|
|
|
"(Tensor) Matrix with shape [batch_size, frame_size * 3] for the "
|
|
|
|
"(Tensor) Matrix with shape [batch_size, frame_size * 3] for the "
|
|
|
|
"input.");
|
|
|
|
"input.");
|
|
|
|
AddInput("hidden_prev",
|
|
|
|
AddInput("HiddenPrev",
|
|
|
|
"(Tensor) Matrix with shape [batch_size, frame_size] for the "
|
|
|
|
"(Tensor) Matrix with shape [batch_size, frame_size] for the "
|
|
|
|
"states of previous time step.");
|
|
|
|
"states of previous time step.");
|
|
|
|
AddInput("weight",
|
|
|
|
AddInput("Weight",
|
|
|
|
"(Tensor) Weight matrix with shape [frame_size, frame_size * 3]. "
|
|
|
|
"(Tensor) Weight matrix with shape [frame_size, frame_size * 3]. "
|
|
|
|
"The elements continuous in memory can be divided into two parts. "
|
|
|
|
"The elements continuous in memory can be divided into two parts. "
|
|
|
|
"The first part are weights of the update gate and reset gate "
|
|
|
|
"The first part are weights of the update gate and reset gate "
|
|
|
|
"with shape [frame_size, frame_size * 2], and the second part are "
|
|
|
|
"with shape [frame_size, frame_size * 2], and the second part are "
|
|
|
|
"weights of output candidate with shape [frame_size, frame_size]");
|
|
|
|
"weights of output candidate with shape [frame_size, frame_size]");
|
|
|
|
AddInput("bias",
|
|
|
|
AddInput("Bias",
|
|
|
|
"(Tensor) Bias vector with shape [1, frame_size * 3] concating "
|
|
|
|
"(Tensor) Bias vector with shape [1, frame_size * 3] concating "
|
|
|
|
"bias of the update gate, reset gate and output candidate.");
|
|
|
|
"bias of the update gate, reset gate and output candidate.");
|
|
|
|
AddOutput("gate",
|
|
|
|
AddOutput("Gate",
|
|
|
|
"(Tensor) Matrix with shape [batch_size, frame_size * 3] for the "
|
|
|
|
"(Tensor) Matrix with shape [batch_size, frame_size * 3] for the "
|
|
|
|
"output of update gate, reset gate and output candidate")
|
|
|
|
"output of update gate, reset gate and output candidate")
|
|
|
|
.AsIntermediate();
|
|
|
|
.AsIntermediate();
|
|
|
|
AddOutput("reset_hidden_prev",
|
|
|
|
AddOutput("ResetHiddenPrev",
|
|
|
|
"(Tensor) Matrix with shape [batch_size, frame_size] for the "
|
|
|
|
"(Tensor) Matrix with shape [batch_size, frame_size] for the "
|
|
|
|
"reseted hidden state of previous time step.")
|
|
|
|
"reseted hidden state of previous time step.")
|
|
|
|
.AsIntermediate();
|
|
|
|
.AsIntermediate();
|
|
|
|
AddOutput("hidden",
|
|
|
|
AddOutput("Hidden",
|
|
|
|
"(Tensor) The GRU hidden state of the current time step "
|
|
|
|
"(Tensor) The GRU hidden state of the current time step "
|
|
|
|
"with shape [batch_size, frame_size].");
|
|
|
|
"with shape [batch_size, frame_size].");
|
|
|
|
|
|
|
|
AddAttr<int>("activation",
|
|
|
|
|
|
|
|
"(enum int, default tanh) "
|
|
|
|
|
|
|
|
"The activation type used for output candidate {h}_t.")
|
|
|
|
|
|
|
|
.SetDefault(tanh)
|
|
|
|
|
|
|
|
.InEnum({identity, sigmoid, tanh, relu});
|
|
|
|
|
|
|
|
AddAttr<int>("gate_activation",
|
|
|
|
|
|
|
|
"(enum int, default sigmoid) "
|
|
|
|
|
|
|
|
"The activation type used in update gate and reset gate.")
|
|
|
|
|
|
|
|
.SetDefault(sigmoid)
|
|
|
|
|
|
|
|
.InEnum({identity, sigmoid, tanh, relu});
|
|
|
|
AddComment(R"DOC(
|
|
|
|
AddComment(R"DOC(
|
|
|
|
GRUUnitOp implements part calculations of the GRU unit as following:
|
|
|
|
GRUUnitOp implements part calculations of the GRU unit as following:
|
|
|
|
|
|
|
|
|
|
|
@ -121,36 +131,36 @@ class GRUUnitGradOp : public framework::OperatorWithKernel {
|
|
|
|
using framework::OperatorWithKernel::OperatorWithKernel;
|
|
|
|
using framework::OperatorWithKernel::OperatorWithKernel;
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
protected:
|
|
|
|
void InferShape(framework::InferShapeContextBase *ctx) const override {
|
|
|
|
void InferShape(framework::InferShapeContext* ctx) const override {
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("input"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("Input"),
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "input");
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "Input");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("hidden_prev"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("HiddenPrev"),
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.",
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.",
|
|
|
|
"hidden_prev");
|
|
|
|
"HiddenPrev");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("weight"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("Weight"),
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "weight");
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "Weight");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("bias"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("Bias"),
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "bias");
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "Bias");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("gate"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("Gate"),
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "gate");
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "Gate");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("reset_hidden_prev"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("ResetHiddenPrev"),
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.",
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.",
|
|
|
|
"reset_hidden_prev");
|
|
|
|
"ResetHiddenPrev");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("hidden"),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput("Hidden"),
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "hidden");
|
|
|
|
"Input(%s) of GRUUnitGradOp should not be null.", "Hidden");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("gate")),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Gate")),
|
|
|
|
"Input(%s@GRAD) of GRUUnitGradOp should not be null.",
|
|
|
|
"Input(%s@GRAD) of GRUUnitGradOp should not be null.",
|
|
|
|
"gate");
|
|
|
|
"Gate");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("reset_hidden_prev")),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("ResetHiddenPrev")),
|
|
|
|
"Input(%s@GRAD) of GRUUnitGradOp should not be null.",
|
|
|
|
"Input(%s@GRAD) of GRUUnitGradOp should not be null.",
|
|
|
|
"reset_hidden_prev");
|
|
|
|
"ResetHiddenPrev");
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("hidden")),
|
|
|
|
PADDLE_ENFORCE(ctx->HasInput(framework::GradVarName("Hidden")),
|
|
|
|
"Input(%s@GRAD) of GRUUnitGradOp should not be null.",
|
|
|
|
"Input(%s@GRAD) of GRUUnitGradOp should not be null.",
|
|
|
|
"hidden");
|
|
|
|
"Hidden");
|
|
|
|
auto input_dims = ctx->GetInputDim("input");
|
|
|
|
auto input_dims = ctx->GetInputDim("Input");
|
|
|
|
auto hidden_prev_dims = ctx->GetInputDim("hidden_prev");
|
|
|
|
auto hidden_prev_dims = ctx->GetInputDim("HiddenPrev");
|
|
|
|
auto weight_dims = ctx->GetInputDim("weight");
|
|
|
|
auto weight_dims = ctx->GetInputDim("Weight");
|
|
|
|
auto bias_dims = ctx->GetInputDim("bias");
|
|
|
|
auto bias_dims = ctx->GetInputDim("Bias");
|
|
|
|
// int batch_size = input_dims[0];
|
|
|
|
// int batch_size = input_dims[0];
|
|
|
|
int input_size = input_dims[1];
|
|
|
|
int input_size = input_dims[1];
|
|
|
|
int frame_size = hidden_prev_dims[1];
|
|
|
|
int frame_size = hidden_prev_dims[1];
|
|
|
@ -160,27 +170,27 @@ class GRUUnitGradOp : public framework::OperatorWithKernel {
|
|
|
|
int bias_width = bias_dims[1];
|
|
|
|
int bias_width = bias_dims[1];
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
input_size, frame_size * 3,
|
|
|
|
input_size, frame_size * 3,
|
|
|
|
"The innput_size must be 3 times of frame_size in GRUUnitOp.");
|
|
|
|
"The input_size must be 3 times of frame_size in GRUUnitOp.");
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
weight_height, frame_size,
|
|
|
|
weight_height, frame_size,
|
|
|
|
"The shape of weight matrix must be [frame_size, frame_size * 3].");
|
|
|
|
"The shape of Weight matrix must be [frame_size, frame_size * 3].");
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
PADDLE_ENFORCE_EQ(
|
|
|
|
weight_width, frame_size * 3,
|
|
|
|
weight_width, frame_size * 3,
|
|
|
|
"The shape of weight matrix must be [frame_size, frame_size * 3].");
|
|
|
|
"The shape of Weight matrix must be [frame_size, frame_size * 3].");
|
|
|
|
PADDLE_ENFORCE_EQ(bias_height, 1,
|
|
|
|
PADDLE_ENFORCE_EQ(bias_height, 1,
|
|
|
|
"The shape of bias must be [1, frame_size * 3].");
|
|
|
|
"The shape of Bias must be [1, frame_size * 3].");
|
|
|
|
PADDLE_ENFORCE_EQ(bias_width, frame_size * 3,
|
|
|
|
PADDLE_ENFORCE_EQ(bias_width, frame_size * 3,
|
|
|
|
"The shape of bias must be [1, frame_size * 3].");
|
|
|
|
"The shape of Bias must be [1, frame_size * 3].");
|
|
|
|
auto input_grad_name = framework::GradVarName("input");
|
|
|
|
auto input_grad_name = framework::GradVarName("Input");
|
|
|
|
if (ctx->HasOutput(input_grad_name))
|
|
|
|
if (ctx->HasOutput(input_grad_name))
|
|
|
|
ctx->SetOutputDim(input_grad_name, input_dims);
|
|
|
|
ctx->SetOutputDim(input_grad_name, input_dims);
|
|
|
|
auto hidden_prev_grad_name = framework::GradVarName("hidden_prev");
|
|
|
|
auto hidden_prev_grad_name = framework::GradVarName("HiddenPrev");
|
|
|
|
if (ctx->HasOutput(hidden_prev_grad_name))
|
|
|
|
if (ctx->HasOutput(hidden_prev_grad_name))
|
|
|
|
ctx->SetOutputDim(hidden_prev_grad_name, hidden_prev_dims);
|
|
|
|
ctx->SetOutputDim(hidden_prev_grad_name, hidden_prev_dims);
|
|
|
|
auto weight_grad_name = framework::GradVarName("weight");
|
|
|
|
auto weight_grad_name = framework::GradVarName("Weight");
|
|
|
|
if (ctx->HasOutput(weight_grad_name))
|
|
|
|
if (ctx->HasOutput(weight_grad_name))
|
|
|
|
ctx->SetOutputDim(weight_grad_name, weight_dims);
|
|
|
|
ctx->SetOutputDim(weight_grad_name, weight_dims);
|
|
|
|
auto bias_grad_name = framework::GradVarName("bias");
|
|
|
|
auto bias_grad_name = framework::GradVarName("Bias");
|
|
|
|
if (ctx->HasOutput(bias_grad_name))
|
|
|
|
if (ctx->HasOutput(bias_grad_name))
|
|
|
|
ctx->SetOutputDim(bias_grad_name, bias_dims);
|
|
|
|
ctx->SetOutputDim(bias_grad_name, bias_dims);
|
|
|
|
}
|
|
|
|
}
|
|
|
|