add Conv1d ops

pull/3198/head
jiangjinsheng 5 years ago
parent ba393c83a9
commit 7f9bbfd338

File diff suppressed because it is too large Load Diff

@ -780,7 +780,9 @@ class Conv2D(PrimitiveWithInfer):
mode (int): 0 Math convolutiuon, 1 cross-correlation convolution ,
2 deconvolution, 3 depthwise convolution. Default: 1.
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.
dilation (Union(int, tuple[int])): Specify the space to use between kernel elements. Default: 1.
group (int): Split input into groups. Default: 1.
@ -820,11 +822,19 @@ class Conv2D(PrimitiveWithInfer):
self.add_prim_attr('stride', self.stride)
self.dilation = _check_positive_int_or_tuple('dilation', dilation, self.name, allow_four=True, ret_four=True)
self.add_prim_attr('dilation', self.dilation)
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 = 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':
validator.check_integer('pad', self.pad, 0, Rel.GE, self.name)
for item in pad:
validator.check_integer('pad item', item, 0, Rel.GE, self.name)
self.mode = validator.check_integer('mode', mode, 1, Rel.EQ, self.name)
self.add_prim_attr('data_format', "NCHW")
@ -862,11 +872,11 @@ class Conv2D(PrimitiveWithInfer):
pad_left = math.floor(pad_needed_w / 2)
pad_right = pad_needed_w - pad_left
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
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
h_out = math.floor(h_out)
w_out = math.floor(w_out)
@ -1277,7 +1287,9 @@ class Conv2DBackpropInput(PrimitiveWithInfer):
out_channel (int): The dimensionality of the output space.
kernel_size (Union[int, tuple[int]]): The size of the convolution window.
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.
mode (int): 0 Math convolutiuon, 1 cross-correlation convolution ,
2 deconvolution, 3 depthwise convolution. Default: 1.
stride (Union[int. tuple[int]]): The stride to apply conv filter. Default: 1.
@ -1314,9 +1326,21 @@ class Conv2DBackpropInput(PrimitiveWithInfer):
self.add_prim_attr('stride', self.stride)
self.dilation = _check_positive_int_or_tuple('dilation', dilation, self.name, allow_four=True, ret_four=True)
self.add_prim_attr('dilation', self.dilation)
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
self.pad = pad
else:
validator.check_integer('pad size', len(pad), 4, Rel.EQ, 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)
pad_mode = pad_mode.upper()
self.add_prim_attr('pad_mode', pad_mode)
self.mode = validator.check_integer('mode', mode, 1, Rel.EQ, self.name)
@ -1358,7 +1382,7 @@ class Conv2DBackpropInput(PrimitiveWithInfer):
pad_right = pad_needed_w - pad_left
pad_list = (pad_top, pad_bottom, pad_left, pad_right)
elif self.pad_mode == 'PAD':
pad_list = (self.pad,) * 4
pad_list = self.pad
self.add_prim_attr('pad_list', pad_list)
out = {
'value': None,

@ -22,11 +22,22 @@ from mindspore.ops.vm_impl_registry import vm_impl_registry as vm_impl_getters
def im2col(img, filter_h, filter_w, stride=1, pad=0, dilation=1):
"""Rearranges an image to row vector"""
if isinstance(pad, int):
pad_top = pad
pad_bottom = pad
pad_left = pad
pad_right = pad
elif isinstance(pad, tuple) and len(pad) == 4:
pad_top, pad_bottom, pad_left, pad_right = pad
else:
raise ValueError(f"The \'pad\' should be an int number or "
f"a tuple of two or four int numbers, but got {pad}")
batch_num, channel, height, width = img.shape
out_h = (height + 2 * pad - filter_h - (filter_h - 1) * (dilation[2] - 1)) // stride[2] + 1
out_w = (width + 2 * pad - filter_w - (filter_w - 1) * (dilation[3] - 1)) // stride[3] + 1
out_h = (height + pad_top + pad_bottom - filter_h - (filter_h - 1) * (dilation[2] - 1)) // stride[2] + 1
out_w = (width + pad_left + pad_right - filter_w - (filter_w - 1) * (dilation[3] - 1)) // stride[3] + 1
img = np.pad(img, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant')
img = np.pad(img, [(0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)], 'constant')
col = np.zeros((batch_num, channel, filter_h, filter_w, out_h, out_w)).astype(img.dtype)
for y in range(filter_h):
@ -43,10 +54,21 @@ def im2col(img, filter_h, filter_w, stride=1, pad=0, dilation=1):
def conv2d(x, weight, bias=None, stride=1, pad=0,
dilation=1, groups=1, padding_mode='zeros'):
"""Convolution 2D"""
if isinstance(pad, int):
pad_top = pad
pad_bottom = pad
pad_left = pad
pad_right = pad
elif isinstance(pad, tuple) and len(pad) == 4:
pad_top, pad_bottom, pad_left, pad_right = pad
else:
raise ValueError(f"The \'pad\' should be an int number or "
f"a tuple of two or four int numbers, but got {pad}")
batch_num, _, x_h, x_w = x.shape
filter_num, _, filter_h, filter_w = weight.shape
out_h = 1 + int((x_h + 2 * pad - filter_h - (filter_h - 1) * (dilation[2] - 1)) / stride[2])
out_w = 1 + int((x_w + 2 * pad - filter_w - (filter_w - 1) * (dilation[3] - 1)) / stride[3])
out_h = 1 + int((x_h + pad_top + pad_bottom - filter_h - (filter_h - 1) * (dilation[2] - 1)) / stride[2])
out_w = 1 + int((x_w + pad_left + pad_right - filter_w - (filter_w - 1) * (dilation[3] - 1)) / stride[3])
col = im2col(x, filter_h, filter_w, stride, pad, dilation)
col_w = np.reshape(weight, (filter_num, -1)).T
out = np.dot(col, col_w)

@ -169,16 +169,32 @@ def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):
raise ValueError(f"The \'stride\' should be an int number or "
f"a tuple of two or four int numbers, but got {stride}")
if isinstance(pad, int):
pad_top = pad
pad_bottom = pad
pad_left = pad
pad_right = pad
elif isinstance(pad, tuple) and len(pad) == 2:
pad_top = pad[0]
pad_bottom = pad[0]
pad_left = pad[1]
pad_right = pad[1]
elif isinstance(pad, tuple) and len(pad) == 4:
pad_top, pad_bottom, pad_left, pad_right = pad
else:
raise ValueError(f"The \'pad\' should be an int number or "
f"a tuple of two or four int numbers, but got {pad}")
batch_num, channel, height, width = input_shape
out_h = (height + 2 * pad - filter_h) // stride_h + 1
out_w = (width + 2 * pad - filter_w) // stride_w + 1
out_h = (height + pad_top + pad_bottom - filter_h) // stride_h + 1
out_w = (width + pad_left + pad_right - filter_w) // stride_w + 1
col = col.reshape(batch_num, out_h, out_w, channel, filter_h, filter_w) \
.transpose(0, 3, 4, 5, 1, 2)
img = np.zeros((batch_num,
channel,
height + 2 * pad + stride_h - 1,
width + 2 * pad + stride_w - 1)) \
height + pad_top + pad_bottom + stride_h - 1,
width + pad_left + pad_right + stride_w - 1)) \
.astype(col.dtype)
for y in range(filter_h):
y_max = y + stride_h * out_h
@ -186,7 +202,7 @@ def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):
x_max = x + stride_h * out_w
img[:, :, y:y_max:stride_h, x:x_max:stride_h] += col[:, :, y, x, :, :]
return img[:, :, pad:height + pad, pad:width + pad]
return img[:, :, pad_top:height + pad_bottom, pad_left:width + pad_right]
def convolve(x, w, b=None, pad_mode="valid"):
@ -243,10 +259,21 @@ def conv2d(x, weight, bias=None, stride=1, pad=0,
dilation_h = dilation[0]
dilation_w = dilation[1]
if isinstance(pad, int):
pad_top = pad
pad_bottom = pad
pad_left = pad
pad_right = pad
elif isinstance(pad, tuple) and len(pad) == 4:
pad_top, pad_bottom, pad_left, pad_right = pad
else:
raise ValueError(f"The \'pad\' should be an int number or "
f"a tuple of two or four int numbers, but got {pad}")
batch_num, _, x_h, x_w = x.shape
filter_num, _, filter_h, filter_w = weight.shape
out_h = 1 + int((x_h + 2 * pad - filter_h - (filter_h - 1) * (dilation_h - 1)) / stride_h)
out_w = 1 + int((x_w + 2 * pad - filter_w - (filter_w - 1) * (dilation_w - 1)) / stride_w)
out_h = 1 + int((x_h + pad_top + pad_bottom - filter_h - (filter_h - 1) * (dilation_h - 1)) / stride_h)
out_w = 1 + int((x_w + pad_left + pad_right - filter_w - (filter_w - 1) * (dilation_w - 1)) / stride_w)
col = im2col(x, filter_h, filter_w, stride, pad, dilation)
col_w = np.reshape(weight, (filter_num, -1)).T
out = np.dot(col, col_w)
@ -348,11 +375,22 @@ def im2col(img, filter_h, filter_w, stride=1, pad=0, dilation=1):
raise ValueError(f"The \'dilation\' should be an int number or "
f"a tuple of two or four int numbers, but got {dilation}")
if isinstance(pad, int):
pad_top = pad
pad_bottom = pad
pad_left = pad
pad_right = pad
elif isinstance(pad, tuple) and len(pad) == 4:
pad_top, pad_bottom, pad_left, pad_right = pad
else:
raise ValueError(f"The \'pad\' should be an int number or "
f"a tuple of two or four int numbers, but got {pad}")
batch_num, channel, height, width = img.shape
out_h = (height + 2 * pad - filter_h - (filter_h - 1) * (dilation_h - 1)) // stride_h + 1
out_w = (width + 2 * pad - filter_w - (filter_w - 1) * (dilation_w - 1)) // stride_w + 1
out_h = (height + pad_top + pad_bottom - filter_h - (filter_h - 1) * (dilation_h - 1)) // stride_h + 1
out_w = (width + pad_left + pad_right - filter_w - (filter_w - 1) * (dilation_w - 1)) // stride_w + 1
img = np.pad(img, [(0, 0), (0, 0), (pad, pad), (pad, pad)], 'constant')
img = np.pad(img, [(0, 0), (0, 0), (pad_top, pad_bottom), (pad_left, pad_right)], 'constant')
col = np.zeros((batch_num, channel, filter_h, filter_w, out_h, out_w)).astype(img.dtype)
for y in range(filter_h):

Loading…
Cancel
Save