From e480168fae42737fb904b837f24a378860ba7d14 Mon Sep 17 00:00:00 2001 From: huangjun12 <2399845970@qq.com> Date: Wed, 2 Sep 2020 20:34:58 +0800 Subject: [PATCH] fix dropout bug in backward when input is 1d tensor (#26837) * fix dropout bug in backward when input is 1d tensor, test=develop * add test case and refine error message, test=develop * refine error message, test=develop --- paddle/fluid/operators/dropout_op.h | 10 +++++--- .../fluid/tests/unittests/test_dropout_op.py | 24 +++++++++++++++++++ python/paddle/nn/functional/common.py | 6 ++--- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/paddle/fluid/operators/dropout_op.h b/paddle/fluid/operators/dropout_op.h index 9d9eb4a82a0..161c4282ec2 100644 --- a/paddle/fluid/operators/dropout_op.h +++ b/paddle/fluid/operators/dropout_op.h @@ -29,6 +29,10 @@ template using EigenMatrix = framework::EigenMatrix; +template +using EigenVector = framework::EigenVector; + template class CPUDropoutKernel : public framework::OpKernel { public: @@ -116,9 +120,9 @@ class DropoutGradKernel : public framework::OpKernel { auto* mask = context.Input("Mask"); grad_x->mutable_data(context.GetPlace()); - auto M = EigenMatrix::Reshape(*mask, 1); - auto dX = EigenMatrix::Reshape(*grad_x, 1); - auto dY = EigenMatrix::Reshape(*grad_y, 1); + auto M = EigenVector::Flatten(*mask); + auto dX = EigenVector::Flatten(*grad_x); + auto dY = EigenVector::Flatten(*grad_y); auto& place = *context.template device_context().eigen_device(); diff --git a/python/paddle/fluid/tests/unittests/test_dropout_op.py b/python/paddle/fluid/tests/unittests/test_dropout_op.py index ceec1190279..97137e91aa7 100644 --- a/python/paddle/fluid/tests/unittests/test_dropout_op.py +++ b/python/paddle/fluid/tests/unittests/test_dropout_op.py @@ -40,6 +40,23 @@ class TestDropoutOp(OpTest): self.check_grad(['X'], 'Out') +class TestDropoutOpInput1d(OpTest): + def setUp(self): + self.op_type = "dropout" + self.inputs = {'X': np.random.random((2000)).astype("float32")} + self.attrs = {'dropout_prob': 0.0, 'fix_seed': True, 'is_test': False} + self.outputs = { + 'Out': self.inputs['X'], + 'Mask': np.ones((2000)).astype('uint8') + } + + def test_check_output(self): + self.check_output() + + def test_check_grad_normal(self): + self.check_grad(['X'], 'Out') + + class TestDropoutOp2(TestDropoutOp): def setUp(self): self.op_type = "dropout" @@ -436,6 +453,13 @@ class TestDropoutFAPIError(unittest.TestCase): self.assertRaises(ValueError, test_axis_max) + def test_axis_min(): + # minimum of axis should greater equal than 0 + x2 = fluid.data(name='x2', shape=[3, 4, 5, 6], dtype="float32") + paddle.nn.functional.dropout(x2, axis=[0, -1]) + + self.assertRaises(ValueError, test_axis_min) + def test_axis_len(): # length of axis should not greater than dimensions of x x2 = fluid.data(name='x2', shape=[3, 4, 5, 6], dtype="float32") diff --git a/python/paddle/nn/functional/common.py b/python/paddle/nn/functional/common.py index 623af3277fb..633920dc7e8 100644 --- a/python/paddle/nn/functional/common.py +++ b/python/paddle/nn/functional/common.py @@ -910,12 +910,12 @@ def dropout(x, #get mask shape input_shape = x.shape drop_axes = [axis] if isinstance(axis, int) else axis - if max(drop_axes) > len(input_shape) - 1: - raise ValueError("axis value should less than dimensions of x:{}, but get drop_axes value:{} " \ + if min(drop_axes) < 0 or max(drop_axes) > len(input_shape) - 1: + raise ValueError("axis value should be greater than or equal to 0 and less than dimensions of x:{}, but get axis value:{} " \ .format(len(input_shape), max(drop_axes))) if len(drop_axes) > len(input_shape): raise ValueError( - "length of axis should not greater than dimensions of x:{}, but get length of drop axes: {}". + "length of axis should not be greater than dimensions of x:{}, but get length of axis: {}". format(len(input_shape), len(drop_axes))) mask_shape = [1] * len(input_shape) for i in drop_axes: -- GitLab