diff --git a/paddle/operators/fc_op.cc b/paddle/operators/fc_op.cc index be0fca3c7189b5a5709a57805e0fc374ae9ca20f..14a7fa8467d17ef3709738a11816c84f92da343b 100644 --- a/paddle/operators/fc_op.cc +++ b/paddle/operators/fc_op.cc @@ -41,10 +41,19 @@ class FCOp : public NetOp { "The size of inputs X(%d) should be no less than 1.", n); auto x_num_col_dims = Attr>("xNumColDims"); - PADDLE_ENFORCE_EQ(x_num_col_dims.size(), n, - "The size of attribute xNumColDims(%d) should be the " - "same as that of inputs X(%d).", - x_num_col_dims.size(), n); + + // Set all values or set no values (use the default value) + if (!x_num_col_dims.empty()) { + PADDLE_ENFORCE_EQ(x_num_col_dims.size(), n, + "The size of attribute xNumColDims(%d) should be the " + "same as that of inputs X(%d).", + x_num_col_dims.size(), n); + } else { + x_num_col_dims.resize(n); + for (size_t i = 0; i < n; i++) { + x_num_col_dims[i] = 1; + } + } // mul_out[i] = X[i] * W[i] for (size_t i = 0; i < n; i++) { @@ -81,7 +90,7 @@ class FCOp : public NetOp { auto activation = Attr("activation"); AppendOp(framework::OpRegistry::CreateOp( - activation, {{"X", {Output(add_out)}}}, {{"Y", {Output("Y")}}}, {})); + activation, {{"X", {Output(add_out)}}}, {{"Y", {Output("Out")}}}, {})); CompleteAddOp(false); } }; @@ -105,7 +114,7 @@ class FCOpMaker : public framework::OpProtoAndCheckerMaker { "(Tensor) the bias of FC operator, a 1-D vector of size " "number_of_neurons."); - AddOutput("Y", + AddOutput("Out", "(Tensor) the activated output matrix of FC operator, a 2-D " "matrix of size (minibatch, number_of_neurons)."); AddOutput("MulOut", @@ -137,7 +146,8 @@ class FCOpMaker : public framework::OpProtoAndCheckerMaker { "`X_i.dims[0] x ... x X_i.dims[xNumColDims_i - 1]`. " "The matrix's second dimension (the length of row) will be the product " "of `X_i`'s first `rank - xNumColDims_i` dimensions, that is " - "`X_i.dims[xNumColDims_i] x ... x X_i.dims[rank - 1]`)"); + "`X_i.dims[xNumColDims_i] x ... x X_i.dims[rank - 1]`)") + .SetDefault(std::vector{}); AddComment(R"DOC( Fully Connected Operator, known as Fully Connected Layer or Inner Product Layer @@ -148,13 +158,13 @@ learned weights with a matrix multiplication followed by a bias offset (optionally). Equation: - Y = Act(sum_n{X_i * W_i} + B) + Out = Act(sum_n{X_i * W_i} + B) where X_i is Tensor that will be reshaped to a 2-D matrix of size (M x K), usually M is the minibatch size and K is the number of input features. W_i is a 2-D matrix of size (K x N), where N means the number of neurons in the fully connected layer. B is a 1-D vector of size N. -Thus, the output Y is a 2-D matrix of size (M x N). +Thus, the output Out is a 2-D matrix of size (M x N). Activation type can be set to `identity` (default), `sigmoid` or `softmax`. )DOC"); } diff --git a/python/paddle/v2/framework/tests/test_fc_op.py b/python/paddle/v2/framework/tests/test_fc_op.py index f646fad33735549c5133c60bddb2e834986fc2f5..ed8d869a407298fb3291b8fcb4dff56c257ad097 100644 --- a/python/paddle/v2/framework/tests/test_fc_op.py +++ b/python/paddle/v2/framework/tests/test_fc_op.py @@ -20,15 +20,14 @@ class TestFCOp1(OpTest): "MulOut": [("MulOut0", mul_out0)], "SumOut": sum_out, "AddOut": add_out, - "Y": identity_out + "Out": identity_out } - self.attrs = {"xNumColDims": [1]} def test_check_output(self): self.check_output() def test_check_grad(self): - self.check_grad(["X0", "W0", "B"], "Y", max_relative_error=0.01) + self.check_grad(["X0", "W0", "B"], "Out", max_relative_error=0.01) class TestFCOp2(OpTest): @@ -56,7 +55,7 @@ class TestFCOp2(OpTest): "MulOut": [("MulOut0", mul_out0), ("MulOut1", mul_out1)], "SumOut": sum_out, "AddOut": add_out, - "Y": sigmoid_out + "Out": sigmoid_out } def test_check_output(self): @@ -64,7 +63,7 @@ class TestFCOp2(OpTest): def test_check_grad(self): self.check_grad( - ["X0", "X1", "W0", "W1", "B"], "Y", max_relative_error=0.01) + ["X0", "X1", "W0", "W1", "B"], "Out", max_relative_error=0.01) if __name__ == '__main__':