| @@ -68,6 +68,7 @@ class _Conv(Cell): | |||||
| self.group = check_int_positive(group) | self.group = check_int_positive(group) | ||||
| self.has_bias = has_bias | self.has_bias = has_bias | ||||
| if (not isinstance(kernel_size[0], int)) or (not isinstance(kernel_size[1], int)) or \ | if (not isinstance(kernel_size[0], int)) or (not isinstance(kernel_size[1], int)) or \ | ||||
| isinstance(kernel_size[0], bool) or isinstance(kernel_size[1], bool) or \ | |||||
| kernel_size[0] < 1 or kernel_size[1] < 1: | kernel_size[0] < 1 or kernel_size[1] < 1: | ||||
| raise ValueError("Attr 'kernel_size' of 'Conv2D' Op passed " | raise ValueError("Attr 'kernel_size' of 'Conv2D' Op passed " | ||||
| + str(self.kernel_size) + ", should be a int or tuple and equal to or greater than 1.") | + str(self.kernel_size) + ", should be a int or tuple and equal to or greater than 1.") | ||||
| @@ -76,9 +77,9 @@ class _Conv(Cell): | |||||
| raise ValueError("Attr 'stride' of 'Conv2D' Op passed " | raise ValueError("Attr 'stride' of 'Conv2D' Op passed " | ||||
| + str(self.stride) + ", should be a int or tuple and equal to or greater than 1.") | + str(self.stride) + ", should be a int or tuple and equal to or greater than 1.") | ||||
| if (not isinstance(dilation[0], int)) or (not isinstance(dilation[1], int)) or \ | if (not isinstance(dilation[0], int)) or (not isinstance(dilation[1], int)) or \ | ||||
| dilation[0] < 1 or dilation[1] < 1: | |||||
| isinstance(dilation[0], bool) or isinstance(dilation[1], bool) or dilation[0] < 1 or dilation[1] < 1: | |||||
| raise ValueError("Attr 'dilation' of 'Conv2D' Op passed " | raise ValueError("Attr 'dilation' of 'Conv2D' Op passed " | ||||
| + str(self.dilation) + ", should equal to or greater than 1.") | |||||
| + str(self.dilation) + ", should be a int or tuple and equal to or greater than 1.") | |||||
| if in_channels % group != 0: | if in_channels % group != 0: | ||||
| raise ValueError("Attr 'in_channels' of 'Conv2D' Op must be divisible by " | raise ValueError("Attr 'in_channels' of 'Conv2D' Op must be divisible by " | ||||
| "attr 'group' of 'Conv2D' Op.") | "attr 'group' of 'Conv2D' Op.") | ||||
| @@ -845,7 +846,10 @@ class DepthwiseConv2d(Cell): | |||||
| - pad: Implicit paddings on both sides of the input. The number of `padding` will be padded to the input | - pad: Implicit paddings on both sides of the input. The number of `padding` will be padded to the input | ||||
| Tensor borders. `padding` should be greater than or equal to 0. | Tensor borders. `padding` should be greater than or equal to 0. | ||||
| padding (int): Implicit paddings on both sides of the input. Default: 0. | |||||
| padding (Union[int, tuple[int]]): Implicit paddings on both sides of the input. If `padding` is one integer, | |||||
| the padding of top, bottom, left and right is the same, equal to padding. If `padding` is a tuple | |||||
| with four integers, the padding of top, bottom, left and right will be equal to padding[0], | |||||
| padding[1], padding[2], and padding[3] accordingly. Default: 0. | |||||
| dilation (Union[int, tuple[int]]): The data type is int or a tuple of 2 integers. Specifies the dilation rate | dilation (Union[int, tuple[int]]): The data type is int or a tuple of 2 integers. Specifies the dilation rate | ||||
| to use for dilated convolution. If set to be :math:`k > 1`, there will | to use for dilated convolution. If set to be :math:`k > 1`, there will | ||||
| be :math:`k - 1` pixels skipped for each sampling location. Its value should | be :math:`k - 1` pixels skipped for each sampling location. Its value should | ||||
| @@ -892,11 +896,14 @@ class DepthwiseConv2d(Cell): | |||||
| self.in_channels = check_int_positive(in_channels) | self.in_channels = check_int_positive(in_channels) | ||||
| self.out_channels = check_int_positive(out_channels) | self.out_channels = check_int_positive(out_channels) | ||||
| self.pad_mode = pad_mode | self.pad_mode = pad_mode | ||||
| self.padding = padding | |||||
| self.dilation = dilation | self.dilation = dilation | ||||
| self.has_bias = has_bias | self.has_bias = has_bias | ||||
| self.weight_init = weight_init | self.weight_init = weight_init | ||||
| self.bias_init = bias_init | self.bias_init = bias_init | ||||
| Validator.check_value_type('padding', padding, (int, tuple), self.cls_name) | |||||
| if isinstance(padding, tuple): | |||||
| Validator.check_integer('padding size', len(padding), 4, Rel.EQ, self.cls_name) | |||||
| self.padding = padding | |||||
| self.conv = P.DepthwiseConv2dNative(channel_multiplier=1, | self.conv = P.DepthwiseConv2dNative(channel_multiplier=1, | ||||
| kernel_size=self.kernel_size, | kernel_size=self.kernel_size, | ||||
| pad_mode=self.pad_mode, | pad_mode=self.pad_mode, | ||||
| @@ -983,7 +983,9 @@ class DepthwiseConv2dNative(PrimitiveWithInfer): | |||||
| mode (int): 0 Math convolution, 1 cross-correlation convolution , | mode (int): 0 Math convolution, 1 cross-correlation convolution , | ||||
| 2 deconvolution, 3 depthwise convolution. Default: 3. | 2 deconvolution, 3 depthwise convolution. Default: 3. | ||||
| pad_mode (str): "valid", "same", "pad" the mode to fill padding. Default: "valid". | pad_mode (str): "valid", "same", "pad" the mode to fill padding. Default: "valid". | ||||
| pad (int): The pad value to fill. Default: 0. | |||||
| pad (Union[int, tuple[int]]): The pad value to fill. Default: 0. If `pad` is one integer, the padding of | |||||
| top, bottom, left and right is same, equal to pad. If `pad` is tuple with four integer, the padding | |||||
| of top, bottom, left and right equal to pad[0], pad[1], pad[2], pad[3] with corresponding. | |||||
| stride (Union[int, tuple[int]]): The stride to apply conv filter. Default: 1. | stride (Union[int, tuple[int]]): The stride to apply conv filter. Default: 1. | ||||
| dilation (Union[int, tuple[int]]): Specifies the dilation rate to use for dilated convolution. Default: 1. | dilation (Union[int, tuple[int]]): Specifies the dilation rate to use for dilated convolution. Default: 1. | ||||
| group (int): Splits input into groups. Default: 1. | group (int): Splits input into groups. Default: 1. | ||||
| @@ -1028,9 +1030,18 @@ class DepthwiseConv2dNative(PrimitiveWithInfer): | |||||
| raise ValueError("The height and width of dilation should be equal," | raise ValueError("The height and width of dilation should be equal," | ||||
| f"but got height:{self.dilation[0]}, width:{self.dilation[1]}") | f"but got height:{self.dilation[0]}, width:{self.dilation[1]}") | ||||
| self.add_prim_attr('dilation', (1, 1, self.dilation[0], self.dilation[1])) | self.add_prim_attr('dilation', (1, 1, self.dilation[0], self.dilation[1])) | ||||
| validator.check_value_type('pad', pad, (int,), self.name) | |||||
| validator.check_value_type('pad', pad, (int, tuple), self.name) | |||||
| if isinstance(pad, int): | |||||
| pad = (pad,) * 4 | |||||
| else: | |||||
| validator.check_integer('pad size', len(pad), 4, Rel.EQ, self.name) | |||||
| self.padding = pad | |||||
| self.pad_mode = validator.check_string('pad_mode', pad_mode, ['valid', 'same', 'pad'], self.name) | self.pad_mode = validator.check_string('pad_mode', pad_mode, ['valid', 'same', 'pad'], self.name) | ||||
| self.pad = validator.check_pad_value_by_mode(pad_mode, pad, self.name) | |||||
| if pad_mode != 'pad' and pad != (0, 0, 0, 0): | |||||
| raise ValueError(f"For '{self.name}', padding must be zero when pad_mode is '{pad_mode}'.") | |||||
| if self.pad_mode == 'pad': | |||||
| for item in pad: | |||||
| validator.check_integer('pad item', item, 0, Rel.GE, self.name) | |||||
| self.mode = validator.check_integer("mode", mode, 3, Rel.EQ, self.name) | self.mode = validator.check_integer("mode", mode, 3, Rel.EQ, self.name) | ||||
| self.add_prim_attr('data_format', "NCHW") | self.add_prim_attr('data_format', "NCHW") | ||||
| self.channel_multiplier = validator.check_integer("channel_multiplier", channel_multiplier, 0, Rel.GT, | self.channel_multiplier = validator.check_integer("channel_multiplier", channel_multiplier, 0, Rel.GT, | ||||
| @@ -1065,11 +1076,11 @@ class DepthwiseConv2dNative(PrimitiveWithInfer): | |||||
| pad_left = math.floor(pad_needed_w / 2) | pad_left = math.floor(pad_needed_w / 2) | ||||
| pad_right = pad_needed_w - pad_left | pad_right = pad_needed_w - pad_left | ||||
| elif self.pad_mode == 'pad': | elif self.pad_mode == 'pad': | ||||
| pad_top, pad_bottom, pad_left, pad_right = self.pad, self.pad, self.pad, self.pad | |||||
| pad_top, pad_bottom, pad_left, pad_right = self.padding | |||||
| h_out = 1 + (x_shape[2] + 2 * self.pad - kernel_size_h - (kernel_size_h - 1) * (dilation_h - 1)) \ | |||||
| h_out = 1 + (x_shape[2] + pad_top + pad_bottom - kernel_size_h - (kernel_size_h - 1) * (dilation_h - 1)) \ | |||||
| / stride_h | / stride_h | ||||
| w_out = 1 + (x_shape[3] + 2 * self.pad - kernel_size_w - (kernel_size_w - 1) * (dilation_w - 1)) \ | |||||
| w_out = 1 + (x_shape[3] + pad_left + pad_right - kernel_size_w - (kernel_size_w - 1) * (dilation_w - 1)) \ | |||||
| / stride_w | / stride_w | ||||
| h_out = math.floor(h_out) | h_out = math.floor(h_out) | ||||
| w_out = math.floor(w_out) | w_out = math.floor(w_out) | ||||