未验证 提交 c4dbeca3 编写于 作者: W wangguanzhong 提交者: GitHub

enhance error message for conv (#33119)

* enhance error message for conv

* fix ci coverage
上级 f61e6ee0
...@@ -73,7 +73,17 @@ std::vector<int64_t> ConvOp::ComputeOutputShape( ...@@ -73,7 +73,17 @@ std::vector<int64_t> ConvOp::ComputeOutputShape(
"the filter's dimension is %d.", "the filter's dimension is %d.",
in_dims, in_dims.size(), filter_dims, filter_dims.size())); in_dims, in_dims.size(), filter_dims, filter_dims.size()));
int in_sub_stride_size = in_dims.size() - strides.size(); int stride_size = strides.size();
for (int i = 0; i < stride_size; ++i) {
PADDLE_ENFORCE_GT(
strides[i], 0,
platform::errors::InvalidArgument(
"The stride of Op(Conv) should be larget than 0, but received "
"stride is %d.",
strides[i]));
}
int in_sub_stride_size = in_dims.size() - stride_size;
PADDLE_ENFORCE_EQ( PADDLE_ENFORCE_EQ(
in_dims.size(), strides.size() + 2U, in_dims.size(), strides.size() + 2U,
platform::errors::InvalidArgument( platform::errors::InvalidArgument(
......
...@@ -66,7 +66,19 @@ void ConvTransposeOp::InferShape(framework::InferShapeContext* ctx) const { ...@@ -66,7 +66,19 @@ void ConvTransposeOp::InferShape(framework::InferShapeContext* ctx) const {
"input is [%s], the dimension size of input is [%d], the shape " "input is [%s], the dimension size of input is [%d], the shape "
"of filter is [%s], the dimension size of filter is [%d]. ", "of filter is [%s], the dimension size of filter is [%d]. ",
in_dims, in_dims.size(), filter_dims, filter_dims.size())); in_dims, in_dims.size(), filter_dims, filter_dims.size()));
int in_sub_stride_size = in_dims.size() - strides.size();
int stride_size = strides.size();
for (int i = 0; i < stride_size; ++i) {
PADDLE_ENFORCE_GT(
strides[i], 0,
platform::errors::InvalidArgument(
"The stride of Op(Conv) should be larget than 0, but received "
"stride is %d.",
strides[i]));
}
int in_sub_stride_size = in_dims.size() - stride_size;
PADDLE_ENFORCE_EQ( PADDLE_ENFORCE_EQ(
in_dims.size() - strides.size(), 2U, in_dims.size() - strides.size(), 2U,
platform::errors::InvalidArgument( platform::errors::InvalidArgument(
......
...@@ -1502,6 +1502,9 @@ def conv2d(input, ...@@ -1502,6 +1502,9 @@ def conv2d(input,
check_variable_and_dtype(input, 'input', ['float16', 'float32', 'float64'], check_variable_and_dtype(input, 'input', ['float16', 'float32', 'float64'],
'conv2d') 'conv2d')
if len(input.shape) != 4:
raise ValueError("Input size should be 4, "
"but received {}".format(len(input.shape)))
num_channels = input.shape[1] num_channels = input.shape[1]
if not isinstance(use_cudnn, bool): if not isinstance(use_cudnn, bool):
raise ValueError("Attr(use_cudnn) should be True or False. Received " raise ValueError("Attr(use_cudnn) should be True or False. Received "
...@@ -1520,6 +1523,20 @@ def conv2d(input, ...@@ -1520,6 +1523,20 @@ def conv2d(input,
"Received: %s." % (str(input.shape), str(num_channels))) "Received: %s." % (str(input.shape), str(num_channels)))
assert param_attr is not False, "param_attr should not be False here." assert param_attr is not False, "param_attr should not be False here."
if groups is None:
num_filter_channels = num_channels
elif groups <= 0:
raise ValueError("the groups of input must be greater than 0, "
"but received the groups of input is {}".format(
groups))
else:
if num_channels % groups != 0:
raise ValueError(
"the channel of input must be divisible by groups,"
"received: the channel of input is {}, the shape of input is {}"
", the groups is {}".format(num_channels, input.shape, groups))
num_filter_channels = num_channels // groups
l_type = 'conv2d' l_type = 'conv2d'
if (num_channels == groups and num_filters % num_channels == 0 and if (num_channels == groups and num_filters % num_channels == 0 and
not use_cudnn): not use_cudnn):
...@@ -1532,16 +1549,6 @@ def conv2d(input, ...@@ -1532,16 +1549,6 @@ def conv2d(input,
helper = LayerHelper(l_type, **locals()) helper = LayerHelper(l_type, **locals())
dtype = helper.input_dtype() dtype = helper.input_dtype()
if groups is None:
num_filter_channels = num_channels
else:
if num_channels % groups != 0:
raise ValueError(
"the channel of input must be divisible by groups,"
"received: the channel of input is {}, the shape of input is {}"
", the groups is {}".format(num_channels, input.shape, groups))
num_filter_channels = num_channels // groups
filter_size = utils.convert_to_list(filter_size, 2, 'filter_size') filter_size = utils.convert_to_list(filter_size, 2, 'filter_size')
stride = utils.convert_to_list(stride, 2, 'stride') stride = utils.convert_to_list(stride, 2, 'stride')
dilation = utils.convert_to_list(dilation, 2, 'dilation') dilation = utils.convert_to_list(dilation, 2, 'dilation')
...@@ -1597,6 +1604,11 @@ def conv2d(input, ...@@ -1597,6 +1604,11 @@ def conv2d(input,
def _get_default_param_initializer(): def _get_default_param_initializer():
filter_elem_num = filter_size[0] * filter_size[1] * num_channels filter_elem_num = filter_size[0] * filter_size[1] * num_channels
if filter_elem_num <= 0:
raise ValueError(
"Invalid filter number, excepted number is larger than 0, but"
" received {}, please check the input shape and "
"filter size.".format(filter_elem_num))
std = (2.0 / filter_elem_num)**0.5 std = (2.0 / filter_elem_num)**0.5
return Normal(0.0, std, 0) return Normal(0.0, std, 0)
...@@ -1878,6 +1890,12 @@ def conv3d(input, ...@@ -1878,6 +1890,12 @@ def conv3d(input,
def _get_default_param_initializer(): def _get_default_param_initializer():
filter_elem_num = filter_size[0] * filter_size[1] * filter_size[ filter_elem_num = filter_size[0] * filter_size[1] * filter_size[
2] * num_channels 2] * num_channels
if filter_elem_num <= 0:
raise ValueError(
"Invalid filter number, excepted number is larger than 0, but"
" received {}, please check the input shape and "
"filter size.".format(filter_elem_num))
std = (2.0 / filter_elem_num)**0.5 std = (2.0 / filter_elem_num)**0.5
return Normal(0.0, std, 0) return Normal(0.0, std, 0)
...@@ -14412,6 +14430,11 @@ def deformable_conv(input, ...@@ -14412,6 +14430,11 @@ def deformable_conv(input,
def _get_default_param_initializer(): def _get_default_param_initializer():
filter_elem_num = filter_size[0] * filter_size[1] * num_channels filter_elem_num = filter_size[0] * filter_size[1] * num_channels
if filter_elem_num <= 0:
raise ValueError(
"Invalid filter number, excepted number is larger than 0, but"
" received {}, please check the input shape and "
"filter size.".format(filter_elem_num))
std = (2.0 / filter_elem_num)**0.5 std = (2.0 / filter_elem_num)**0.5
return Normal(0.0, std, 0) return Normal(0.0, std, 0)
......
...@@ -268,6 +268,12 @@ def add_error_cases(suite): ...@@ -268,6 +268,12 @@ def add_error_cases(suite):
suite.addTest( suite.addTest(
Conv2DErrorTestCase( Conv2DErrorTestCase(
methodName='runTest', num_channels=5, groups=2)) methodName='runTest', num_channels=5, groups=2))
suite.addTest(
Conv2DErrorTestCase(
methodName='runTest', num_channels=5, groups=2, stride=0))
suite.addTest(
Conv2DErrorTestCase(
methodName='runTest', num_channels=5, groups=2, padding=[-1, -1]))
def load_tests(loader, standard_tests, pattern): def load_tests(loader, standard_tests, pattern):
......
...@@ -1475,6 +1475,73 @@ class TestConv2DAPI_Error(unittest.TestCase): ...@@ -1475,6 +1475,73 @@ class TestConv2DAPI_Error(unittest.TestCase):
self.assertRaises(ValueError, run_7) self.assertRaises(ValueError, run_7)
# ValueError: filter num
def run_8():
fluid.layers.conv2d(
input=input,
num_filters=0,
filter_size=0,
stride=0,
padding=0,
dilation=0,
groups=1,
use_cudnn=False,
data_format="NCHW")
self.assertRaises(ValueError, run_8)
# ValueError: groups
def run_9():
fluid.layers.conv2d(
input=input,
num_filters=0,
filter_size=0,
stride=0,
padding=0,
dilation=0,
groups=0,
use_cudnn=False,
data_format="NCHW")
self.assertRaises(ValueError, run_9)
# ValueError: stride
def run_10():
fluid.layers.conv2d(
input=input,
num_filters=1,
filter_size=1,
stride=0,
padding=0,
dilation=0,
groups=1,
use_cudnn=False,
data_format="NCHW")
self.assertRaises(ValueError, run_10)
def test_api_with_error_input(self):
input = fluid.layers.data(
name="error_input",
shape=[1],
append_batch_size=False,
dtype="float32")
# ValueError: cudnn
def run_1():
fluid.layers.conv2d(
input=input,
num_filters=0,
filter_size=0,
stride=0,
padding=0,
dilation=0,
groups=0,
use_cudnn=False,
data_format="NCHW")
self.assertRaises(ValueError, run_1)
# --------- test environment variable ------ # --------- test environment variable ------
@unittest.skipIf( @unittest.skipIf(
......
...@@ -221,6 +221,9 @@ def add_error_cases(suite): ...@@ -221,6 +221,9 @@ def add_error_cases(suite):
suite.addTest( suite.addTest(
Conv3DErrorTestCase( Conv3DErrorTestCase(
methodName='runTest', num_channels=5, groups=2)) methodName='runTest', num_channels=5, groups=2))
suite.addTest(
Conv3DErrorTestCase(
methodName='runTest', num_channels=5, groups=2, padding=[-1, 1, 3]))
def load_tests(loader, standard_tests, pattern): def load_tests(loader, standard_tests, pattern):
......
...@@ -984,6 +984,21 @@ class TestConv3DAPI_Error(unittest.TestCase): ...@@ -984,6 +984,21 @@ class TestConv3DAPI_Error(unittest.TestCase):
self.assertRaises(ValueError, run_7) self.assertRaises(ValueError, run_7)
# ValueError: filter num
def run_8():
fluid.layers.conv3d(
input=input,
num_filters=0,
filter_size=0,
stride=0,
padding=0,
dilation=0,
groups=1,
use_cudnn=False,
data_format="NDHWC")
self.assertRaises(ValueError, run_8)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -238,6 +238,9 @@ def add_error_cases(suite): ...@@ -238,6 +238,9 @@ def add_error_cases(suite):
suite.addTest( suite.addTest(
Conv3DTransposeErrorTestCase( Conv3DTransposeErrorTestCase(
methodName='runTest', output_size="not_valid")) methodName='runTest', output_size="not_valid"))
suite.addTest(
Conv3DTransposeErrorTestCase(
methodName='runTest', num_channels=5, groups=2, padding=[-1, 1, 3]))
def load_tests(loader, standard_tests, pattern): def load_tests(loader, standard_tests, pattern):
......
...@@ -285,6 +285,19 @@ class TestModulatedDeformableConvInvalidInput(unittest.TestCase): ...@@ -285,6 +285,19 @@ class TestModulatedDeformableConvInvalidInput(unittest.TestCase):
self.assertRaises(TypeError, test_invalid_offset) self.assertRaises(TypeError, test_invalid_offset)
def test_invalid_filter():
paddle.enable_static()
input = fluid.data(
name='input_filter', shape=[None, 3, 32, 32], dtype='float32')
offset = fluid.data(
name='offset_filter', shape=[None, 3, 32, 32], dtype='float32')
mask = fluid.data(
name='mask_filter', shape=[None, 3, 32, 32], dtype='float32')
loss = fluid.layers.deformable_conv(
input, offset, mask, num_filters=4, filter_size=0)
self.assertRaises(ValueError, test_invalid_filter)
class TestDeformConv2DAPI(unittest.TestCase): class TestDeformConv2DAPI(unittest.TestCase):
def test_api(self): def test_api(self):
......
...@@ -85,6 +85,10 @@ def _update_padding_nd(padding, channel_last, num_dims): ...@@ -85,6 +85,10 @@ def _update_padding_nd(padding, channel_last, num_dims):
else: else:
padding_algorithm = "EXPLICIT" padding_algorithm = "EXPLICIT"
padding = utils.convert_to_list(padding, num_dims, 'padding') padding = utils.convert_to_list(padding, num_dims, 'padding')
if not all([p >= 0 for p in padding]):
raise ValueError(
"Invalid padding, all value should be larger than or equal to 0, but received: {}".
format(padding))
return padding, padding_algorithm return padding, padding_algorithm
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册