diff --git a/paddle/framework/attribute.cc b/paddle/framework/attribute.cc index 159ed03b92bbc57ab79734de832845ef1f367de9..fda89252e35c382468877e8cab148e5f91d77ac2 100644 --- a/paddle/framework/attribute.cc +++ b/paddle/framework/attribute.cc @@ -28,6 +28,10 @@ ProgramDesc& GetProgramDesc() { return *g_program_desc; } +template <> +AttrType AttrTypeID() { + return BOOLEAN; +} template <> AttrType AttrTypeID() { return INT; @@ -41,6 +45,10 @@ AttrType AttrTypeID() { return STRING; } template <> +AttrType AttrTypeID>() { + return BOOLEANS; +} +template <> AttrType AttrTypeID>() { return INTS; } @@ -63,6 +71,9 @@ AttrType AttrTypeID() { Attribute GetAttrValue(const OpDesc::Attr& attr_desc) { switch (attr_desc.type()) { + case framework::AttrType::BOOLEAN: { + return attr_desc.b(); + } case framework::AttrType::INT: { return attr_desc.i(); } @@ -72,6 +83,13 @@ Attribute GetAttrValue(const OpDesc::Attr& attr_desc) { case framework::AttrType::STRING: { return attr_desc.s(); } + case framework::AttrType::BOOLEANS: { + std::vector val(attr_desc.bools_size()); + for (int i = 0; i < attr_desc.bools_size(); ++i) { + val[i] = attr_desc.bools(i); + } + return val; + } case framework::AttrType::INTS: { std::vector val(attr_desc.ints_size()); for (int i = 0; i < attr_desc.ints_size(); ++i) { diff --git a/paddle/framework/attribute.h b/paddle/framework/attribute.h index 6735ca0a8d70d04dae9dd610742370e83472e9b0..48b54b5422de8c45e15a1b7040b78373dce8fa3a 100644 --- a/paddle/framework/attribute.h +++ b/paddle/framework/attribute.h @@ -27,8 +27,9 @@ limitations under the License. */ namespace paddle { namespace framework { -typedef boost::variant, - std::vector, std::vector, +typedef boost::variant, std::vector, std::vector, + std::vector, std::vector>, BlockDesc*> Attribute; diff --git a/paddle/framework/framework.proto b/paddle/framework/framework.proto index 89a49f69062486ace67154f52450e7449a948851..cf83d4cec312ac16366d84f897e7dc4784596ae8 100644 --- a/paddle/framework/framework.proto +++ b/paddle/framework/framework.proto @@ -23,7 +23,9 @@ enum AttrType { FLOATS = 4; STRINGS = 5; INT_PAIRS = 6; - BLOCK = 7; + BOOLEAN = 7; + BOOLEANS = 8; + BLOCK = 9; } message IntPair { @@ -45,7 +47,9 @@ message OpDesc { repeated float floats = 7; repeated string strings = 8; repeated IntPair int_pairs = 9; - optional int32 block_idx = 10; + optional bool b = 10; + repeated bool bools = 11; + optional int32 block_idx = 12; }; message Var { diff --git a/paddle/operators/cross_entropy_op.cc b/paddle/operators/cross_entropy_op.cc index 679f068c3d2bf0223ccf7bba82b003139f273125..b11dc1472d153dd188a0b3553d6950774216a3fd 100644 --- a/paddle/operators/cross_entropy_op.cc +++ b/paddle/operators/cross_entropy_op.cc @@ -33,19 +33,16 @@ class CrossEntropyOp : public framework::OperatorWithKernel { PADDLE_ENFORCE_EQ(x->dims().size(), 2, "Input(X)'s rank must be 2."); PADDLE_ENFORCE_EQ(label->dims().size(), 2, "Input(Label)'s rank must be 2."); - // TODO(xinghai-sun): remove this check after swtiching to bool - PADDLE_ENFORCE(ctx.Attr("soft_label") == 0 || - ctx.Attr("soft_label") == 1); PADDLE_ENFORCE_EQ(x->dims()[0], label->dims()[0], "The 1st dimension of Input(X) and Input(Label) must " "be equal."); - if (ctx.Attr("soft_label") == 1) { + if (ctx.Attr("soft_label")) { PADDLE_ENFORCE_EQ(x->dims()[1], label->dims()[1], - "If Attr(soft_label) == 1, The 2nd dimension of " + "If Attr(soft_label) == true, The 2nd dimension of " "Input(X) and Input(Label) must be equal."); } else { PADDLE_ENFORCE_EQ(label->dims()[1], 1, - "If Attr(soft_label) == 0, The 2nd dimension of " + "If Attr(soft_label) == false, The 2nd dimension of " "Input(Label) must be 1."); } @@ -73,9 +70,6 @@ class CrossEntropyGradientOp : public framework::OperatorWithKernel { PADDLE_ENFORCE_EQ(dy->dims().size(), 2, "Input(Y@Grad)'s rank must be 2."); PADDLE_ENFORCE_EQ(label->dims().size(), 2, "Input(Label)'s rank must be 2."); - // TODO(xinghai-sun): remove this check after swtiching to bool - PADDLE_ENFORCE(ctx.Attr("soft_label") == 0 || - ctx.Attr("soft_label") == 1); PADDLE_ENFORCE_EQ(x->dims()[0], label->dims()[0], "The 1st dimension of Input(X) and Input(Label) must " "be equal."); @@ -84,13 +78,13 @@ class CrossEntropyGradientOp : public framework::OperatorWithKernel { "be equal."); PADDLE_ENFORCE_EQ(dy->dims()[1], 1, "The 2nd dimension of Input(Y@Grad) must be 1."); - if (ctx.Attr("soft_label") == 1) { + if (ctx.Attr("soft_label")) { PADDLE_ENFORCE_EQ(x->dims()[1], label->dims()[1], - "If Attr(soft_label) == 1, The 2nd dimension of " + "If Attr(soft_label) == true, The 2nd dimension of " "Input(X) and Input(Label) must be equal."); } else { PADDLE_ENFORCE_EQ(label->dims()[1], 1, - "If Attr(soft_label) == 0, The 2nd dimension of " + "If Attr(soft_label) == false, The 2nd dimension of " "Input(Label) must be 1."); } @@ -107,7 +101,8 @@ class CrossEntropyOpMaker : public framework::OpProtoAndCheckerMaker { AddInput("X", "The first input of CrossEntropyOp"); AddInput("Label", "The second input of CrossEntropyOp"); AddOutput("Y", "The output of CrossEntropyOp"); - AddAttr("soft_label", "Is soft label. Default zero.").SetDefault(0); + AddAttr("soft_label", "Is soft label. Default zero.") + .SetDefault(false); AddComment(R"DOC( CrossEntropy Operator. @@ -115,12 +110,12 @@ CrossEntropy Operator. It supports both standard cross-entropy and soft-label cross-entropy loss computation. 1) One-hot cross-entropy: - soft_label = 0, Label[i, 0] indicates the class index for sample i: + soft_label = False, Label[i, 0] indicates the class index for sample i: Y[i] = -log(X[i, Label[i]]) 2) Soft-label cross-entropy: - soft_label = 1, Label[i, j] indicates the soft label of class j + soft_label = True, Label[i, j] indicates the soft label of class j for sample i: Y[i] = \sum_j{-Label[i, j] * log(X[i, j])} diff --git a/paddle/operators/cross_entropy_op.cu b/paddle/operators/cross_entropy_op.cu index ab6ad0e062269483948bf70e492c9431991221fb..1d6361a81472a49729958120c52060b1dff803f2 100644 --- a/paddle/operators/cross_entropy_op.cu +++ b/paddle/operators/cross_entropy_op.cu @@ -102,7 +102,7 @@ class CrossEntropyOpCUDAKernel : public framework::OpKernel { int grid = (n + block - 1) / block; // TODO(qingqing) launch kernel on specified stream // base on ExecutionContext. - if (ctx.Attr("soft_label") == 1) { + if (ctx.Attr("soft_label")) { auto* label_data = ctx.Input("Label")->data(); SoftCrossEntropyKernel<<>>(y_data, x_data, label_data, n, d); @@ -137,7 +137,7 @@ class CrossEntropyGradientOpCUDAKernel : public framework::OpKernel { grid = (n + block - 1) / block; // TODO(qingqing): launch kernel on specified stream // base on ExecutionContext. - if (ctx.Attr("soft_label") == 1) { + if (ctx.Attr("soft_label")) { auto* label_data = label->data(); SoftCrossEntropyGradientKernel<<>>( dx_data, dy_data, x_data, label_data, n, d); diff --git a/paddle/operators/cross_entropy_op.h b/paddle/operators/cross_entropy_op.h index 1b4b23ac2029138afadef0168262203ac2e20430..69caba5ff31f60df2c24cef0e6331f058f6ba8d6 100644 --- a/paddle/operators/cross_entropy_op.h +++ b/paddle/operators/cross_entropy_op.h @@ -51,7 +51,7 @@ class CrossEntropyOpKernel : public framework::OpKernel { int batch_size = x->dims()[0]; int class_num = x->dims()[1]; - if (ctx.Attr("soft_label") == 1) { + if (ctx.Attr("soft_label")) { auto* label_data = ctx.Input("Label")->data(); int index = 0; for (int i = 0; i < batch_size; ++i) { @@ -92,7 +92,7 @@ class CrossEntropyGradientOpKernel : public framework::OpKernel { int class_num = x->dims()[1]; // TODO(qingqing): make zero setting an common function. - if (ctx.Attr("soft_label") == 1) { + if (ctx.Attr("soft_label")) { auto* label_data = ctx.Input("Label")->data(); int index = 0; for (int i = 0; i < batch_size; ++i) { diff --git a/paddle/operators/dropout_op.cc b/paddle/operators/dropout_op.cc index 7a6351b61287eccb0454fe279ea9bf38ed055bdf..2130eda6a42c893d8ec251a7022a0bfa44433bb7 100644 --- a/paddle/operators/dropout_op.cc +++ b/paddle/operators/dropout_op.cc @@ -28,13 +28,10 @@ class DropoutOp : public framework::OperatorWithKernel { PADDLE_ENFORCE_NOT_NULL(ctx.InputVar("X"), "Input(X) must not be null."); PADDLE_ENFORCE_GE(ctx.Attr("dropout_prob"), 0); PADDLE_ENFORCE_LE(ctx.Attr("dropout_prob"), 1); - // TODO(xinghai-sun): remove this check after swtiching to bool - PADDLE_ENFORCE(ctx.Attr("is_training") == 0 || - ctx.Attr("is_training") == 1); auto dims = ctx.Input("X")->dims(); ctx.Output("Out")->Resize(dims); - if (ctx.Attr("is_training") == 1) { + if (ctx.Attr("is_training")) { ctx.Output("Mask")->Resize(dims); } ctx.ShareLoD("X", /*->*/ "Out"); @@ -49,8 +46,7 @@ class DropoutOpMaker : public framework::OpProtoAndCheckerMaker { : OpProtoAndCheckerMaker(proto, op_checker) { AddAttr("dropout_prob", "Probability of setting units to zero.") .SetDefault(.5f); - // TODO(xinghai-sun): use bool for is_training after bool is supported. - AddAttr("is_training", "Whether in training phase.").SetDefault(1); + AddAttr("is_training", "Whether in training phase.").SetDefault(true); AddAttr("seed", "Dropout random seed.").SetDefault(0); AddInput("X", "The input of dropout op."); AddOutput("Out", "The output of dropout op."); @@ -59,7 +55,7 @@ class DropoutOpMaker : public framework::OpProtoAndCheckerMaker { AddComment(R"DOC( Dropout Operator. -"Dropout" refers to randomly dropping out units in a nerual network. It is a +'Dropout' refers to randomly dropping out units in a nerual network. It is a regularization technique for reducing overfitting by preventing neuron co-adaption during training. The dropout operator randomly set (according to the given dropout probability) the outputs of some units to zero, while others @@ -75,8 +71,8 @@ class DropoutOpGrad : public framework::OperatorWithKernel { protected: void InferShape(const framework::InferShapeContext &ctx) const override { - PADDLE_ENFORCE_EQ(ctx.Attr("is_training"), 1, - "GradOp is only callable when is_training is true"); + PADDLE_ENFORCE(ctx.Attr("is_training"), + "GradOp is only callable when is_training is true"); PADDLE_ENFORCE_NOT_NULL(ctx.InputVar("X"), "Input(X) must not be null."); PADDLE_ENFORCE_NOT_NULL(ctx.InputVar("Mask"), "Mask must not be null."); @@ -85,9 +81,6 @@ class DropoutOpGrad : public framework::OperatorWithKernel { PADDLE_ENFORCE_GE(ctx.Attr("dropout_prob"), 0); PADDLE_ENFORCE_LE(ctx.Attr("dropout_prob"), 1); - // TODO(xinghai-sun): remove this check after swtiching to bool - PADDLE_ENFORCE(ctx.Attr("is_training") == 0 || - ctx.Attr("is_training") == 1); auto x_dims = ctx.Input("X")->dims(); auto out_dims = ctx.Input(framework::GradVarName("Out"))->dims(); PADDLE_ENFORCE_EQ(x_dims, out_dims, diff --git a/paddle/operators/dropout_op.cu b/paddle/operators/dropout_op.cu index 186237fb238add37f32403309a0f7e8a9846d335..a04e4a22cc09d4e8106a528e490ccf8e90681c08 100644 --- a/paddle/operators/dropout_op.cu +++ b/paddle/operators/dropout_op.cu @@ -59,7 +59,7 @@ class GPUDropoutKernel : public framework::OpKernel { auto Y = EigenMatrix::Reshape(*y, 1); auto place = context.GetEigenDevice(); - if (context.Attr("is_training") == 1) { + if (context.Attr("is_training")) { auto* mask = context.Output("Mask"); auto* mask_data = mask->mutable_data(context.GetPlace()); int size = framework::product(mask->dims()); diff --git a/paddle/operators/dropout_op.h b/paddle/operators/dropout_op.h index 82eafee0e0e7db7b4b4ae5405f37146d061aefd5..d57f64afcb3558aeea6aed23fae06866e9af874a 100644 --- a/paddle/operators/dropout_op.h +++ b/paddle/operators/dropout_op.h @@ -35,7 +35,7 @@ class CPUDropoutKernel : public framework::OpKernel { auto* y_data = y->mutable_data(context.GetPlace()); AttrType dropout_prob = context.Attr("dropout_prob"); - if (context.Attr("is_training") == 1) { + if (context.Attr("is_training")) { auto* mask = context.Output("Mask"); auto* mask_data = mask->mutable_data(context.GetPlace()); int seed = context.Attr("seed"); @@ -65,8 +65,8 @@ template class DropoutGradKernel : public framework::OpKernel { public: void Compute(const framework::ExecutionContext& context) const override { - PADDLE_ENFORCE_EQ(context.Attr("is_training"), 1, - "GradOp is only callable when is_training is true"); + PADDLE_ENFORCE(context.Attr("is_training"), + "GradOp is only callable when is_training is true"); auto* grad_x = context.Output(framework::GradVarName("X")); auto* grad_y = context.Input(framework::GradVarName("Out")); diff --git a/python/paddle/v2/framework/op.py b/python/paddle/v2/framework/op.py index 6cca41e43b38b8cccb65ff9b347ef226dddecd4d..9086a5cc3452b178ec37fe6a3e358eaa4c5d606b 100644 --- a/python/paddle/v2/framework/op.py +++ b/python/paddle/v2/framework/op.py @@ -89,12 +89,16 @@ class OpDescCreationMethod(object): new_attr.f = user_defined_attr elif attr.type == framework_pb2.STRING: new_attr.s = user_defined_attr + elif attr.type == framework_pb2.BOOLEAN: + new_attr.b = user_defined_attr elif attr.type == framework_pb2.INTS: new_attr.ints.extend(user_defined_attr) elif attr.type == framework_pb2.FLOATS: new_attr.floats.extend(user_defined_attr) elif attr.type == framework_pb2.STRINGS: new_attr.strings.extend(user_defined_attr) + elif attr.type == framework_pb2.BOOLEANS: + new_attr.bools.extend(user_defined_attr) elif attr.type == framework_pb2.INT_PAIRS: for p in user_defined_attr: pair = new_attr.int_pairs.add() diff --git a/python/paddle/v2/framework/tests/test_cos_sim_op.py b/python/paddle/v2/framework/tests/test_cos_sim_op.py index d314ce391ea2f10a8bd77c24e84fa3e1eebb6c73..47557ccb41d1e835b5d04d1b94f54dfc7aa2855a 100644 --- a/python/paddle/v2/framework/tests/test_cos_sim_op.py +++ b/python/paddle/v2/framework/tests/test_cos_sim_op.py @@ -24,15 +24,15 @@ class TestCosSimOp(OpTest): self.check_output() def test_check_grad_normal(self): - self.check_grad(['X', 'Y'], 'Out', max_relative_error=0.05) + self.check_grad(['X', 'Y'], 'Out', max_relative_error=0.06) def test_check_grad_ingore_x(self): self.check_grad( - ['Y'], 'Out', max_relative_error=0.05, no_grad_set=set("X")) + ['Y'], 'Out', max_relative_error=0.06, no_grad_set=set("X")) def test_check_grad_ingore_y(self): self.check_grad( - ['X'], 'Out', max_relative_error=0.05, no_grad_set=set('Y')) + ['X'], 'Out', max_relative_error=0.06, no_grad_set=set('Y')) class TestCosSimOp2(TestCosSimOp): diff --git a/python/paddle/v2/framework/tests/test_cross_entropy_op.py b/python/paddle/v2/framework/tests/test_cross_entropy_op.py index 0206ca064be87afe204aa99021979b7ddc3c5d63..f10db783225c07be9ffde25267fdfe096e97ecac 100644 --- a/python/paddle/v2/framework/tests/test_cross_entropy_op.py +++ b/python/paddle/v2/framework/tests/test_cross_entropy_op.py @@ -19,7 +19,7 @@ class TestCrossEntropyOp1(OpTest): dtype="float32") self.inputs = {"X": X, "Label": label} self.outputs = {"Y": cross_entropy} - self.attrs = {'soft_label': 0} + self.attrs = {'soft_label': False} def test_check_output(self): self.check_output() @@ -45,7 +45,7 @@ class TestCrossEntropyOp2(OpTest): axis=1, keepdims=True).astype("float32") self.inputs = {'X': X, 'Label': label} self.outputs = {'Y': cross_entropy} - self.attrs = {'soft_label': 1} + self.attrs = {'soft_label': True} def test_check_output(self): self.check_output() @@ -76,7 +76,7 @@ class TestCrossEntropyOp3(OpTest): axis=1, keepdims=True).astype("float32") self.inputs = {'X': X, 'Label': label} self.outputs = {'Y': cross_entropy} - self.attrs = {'soft_label': 1} + self.attrs = {'soft_label': True} def test_check_output(self): self.check_output() diff --git a/python/paddle/v2/framework/tests/test_dropout_op.py b/python/paddle/v2/framework/tests/test_dropout_op.py index 3638fee1a1c26195791bc1f5a46dd749da0aee95..29fc702791184aaacf335e13bcc6d03082bb49a6 100644 --- a/python/paddle/v2/framework/tests/test_dropout_op.py +++ b/python/paddle/v2/framework/tests/test_dropout_op.py @@ -7,7 +7,7 @@ class TestDropoutOp(OpTest): def setUp(self): self.op_type = "dropout" self.inputs = {'X': np.random.random((32, 64)).astype("float32")} - self.attrs = {'dropout_prob': 0.0, 'is_training': 1} + self.attrs = {'dropout_prob': 0.0, 'is_training': True} self.outputs = {'Out': self.inputs['X'], 'Mask': np.ones((32, 64))} def test_check_output(self): @@ -21,7 +21,7 @@ class TestDropoutOp2(TestDropoutOp): def setUp(self): self.op_type = "dropout" self.inputs = {'X': np.random.random((32, 64)).astype("float32")} - self.attrs = {'dropout_prob': 1.0, 'is_training': 1} + self.attrs = {'dropout_prob': 1.0, 'is_training': True} self.outputs = {'Out': np.zeros((32, 64)), 'Mask': np.zeros((32, 64))} @@ -29,7 +29,7 @@ class TestDropoutOp3(TestDropoutOp): def setUp(self): self.op_type = "dropout" self.inputs = {'X': np.random.random((32, 64, 2)).astype("float32")} - self.attrs = {'dropout_prob': 0.0, 'is_training': 1} + self.attrs = {'dropout_prob': 0.0, 'is_training': True} self.outputs = {'Out': self.inputs['X'], 'Mask': np.ones((32, 64, 2))} @@ -37,7 +37,7 @@ class TestDropoutOp4(OpTest): def setUp(self): self.op_type = "dropout" self.inputs = {'X': np.random.random((32, 64)).astype("float32")} - self.attrs = {'dropout_prob': 0.35, 'is_training': 0} + self.attrs = {'dropout_prob': 0.35, 'is_training': False} self.outputs = {'Out': self.inputs['X'] * self.attrs['dropout_prob']} def test_check_output(self): @@ -48,7 +48,7 @@ class TestDropoutOp5(OpTest): def setUp(self): self.op_type = "dropout" self.inputs = {'X': np.random.random((32, 64, 3)).astype("float32")} - self.attrs = {'dropout_prob': 0.75, 'is_training': 0} + self.attrs = {'dropout_prob': 0.75, 'is_training': False} self.outputs = {'Out': self.inputs['X'] * self.attrs['dropout_prob']} def test_check_output(self):