From 5ca034b65cc39d28406db365dc6e0fcd45c12dca Mon Sep 17 00:00:00 2001 From: Steve Abreu Date: Thu, 12 Oct 2023 08:15:41 +0200 Subject: [PATCH 1/2] remove string padding values --- nir/ir.py | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/nir/ir.py b/nir/ir.py index 30deece..7d8141d 100644 --- a/nir/ir.py +++ b/nir/ir.py @@ -27,7 +27,7 @@ def _parse_shape_argument(x: Types, key: str): def _calculate_conv_output( input_shape: typing.Union[int, typing.Sequence[int]], - padding: typing.Union[int, str, typing.Sequence[int]], + padding: typing.Union[int, typing.Sequence[int]], dilation: typing.Union[int, typing.Sequence[int]], kernel_size: typing.Union[int, typing.Sequence[int]], stride: typing.Union[int, typing.Sequence[int]], @@ -53,23 +53,18 @@ def _calculate_conv_output( ndim = 1 else: ndim = len(input_shape) - if isinstance(padding, str) and padding == 'valid': - padding = [0] * ndim shapes = [] for i in range(ndim): - if isinstance(padding, str) and padding == 'same': - shape = input_shape[i] - else: - shape = np.floor( - ( - _index_tuple(input_shape, i) - + 2 * _index_tuple(padding, i) - - _index_tuple(dilation, i) * (_index_tuple(kernel_size, i) - 1) - - 1 - ) - / _index_tuple(stride, i) - + 1 + shape = np.floor( + ( + _index_tuple(input_shape, i) + + 2 * _index_tuple(padding, i) + - _index_tuple(dilation, i) * (_index_tuple(kernel_size, i) - 1) + - 1 ) + / _index_tuple(stride, i) + + 1 + ) shapes.append(int(shape)) return np.array(shapes) @@ -352,8 +347,8 @@ class Conv1d(NIRNode): :type weight: np.ndarray :param stride: Stride :type stride: int - :param padding: Padding, if string must be 'same' or 'valid' - :type padding: int | str + :param padding: Padding + :type padding: int :param dilation: Dilation :type dilation: int :param groups: Groups @@ -365,14 +360,12 @@ class Conv1d(NIRNode): input_shape: typing.Optional[int] # N weight: np.ndarray # Weight C_out * C_in * N stride: int # Stride - padding: typing.Union[int, str] # Padding + padding: int # Padding dilation: int # Dilation groups: int # Groups bias: np.ndarray # Bias C_out def __post_init__(self): - if isinstance(self.padding, str) and self.padding not in ["same", "valid"]: - raise ValueError(f"padding must be 'same', 'valid', or int, not {self.padding}") if self.input_shape is None: # leave input and output types undefined self.input_type = {"input": None} @@ -407,8 +400,8 @@ class Conv2d(NIRNode): :type weight: np.ndarray :param stride: Stride :type stride: int | int, int - :param padding: Padding, if string must be 'same' or 'valid' - :type padding: int | int, int | str + :param padding: Padding + :type padding: int | int, int :param dilation: Dilation :type dilation: int | int, int :param groups: Groups @@ -421,14 +414,12 @@ class Conv2d(NIRNode): input_shape: typing.Optional[typing.Tuple[int, int]] # N_x, N_y weight: np.ndarray # Weight C_out * C_in * W_x * W_y stride: typing.Union[int, typing.Tuple[int, int]] # Stride - padding: typing.Union[int, typing.Tuple[int, int], str] # Padding + padding: typing.Union[int, typing.Tuple[int, int]] # Padding dilation: typing.Union[int, typing.Tuple[int, int]] # Dilation groups: int # Groups bias: np.ndarray # Bias C_out def __post_init__(self): - if isinstance(self.padding, str) and self.padding not in ["same", "valid"]: - raise ValueError(f"padding must be 'same', 'valid', or int, not {self.padding}") if isinstance(self.padding, int): self.padding = (self.padding, self.padding) if isinstance(self.stride, int): From 68794440537ed7fa3e58606c66cec34499f0b7bd Mon Sep 17 00:00:00 2001 From: Steve Abreu Date: Thu, 12 Oct 2023 11:33:38 +0200 Subject: [PATCH 2/2] move to tensorflow-style padding --- nir/ir.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/nir/ir.py b/nir/ir.py index 7d8141d..ecb81d1 100644 --- a/nir/ir.py +++ b/nir/ir.py @@ -27,7 +27,7 @@ def _parse_shape_argument(x: Types, key: str): def _calculate_conv_output( input_shape: typing.Union[int, typing.Sequence[int]], - padding: typing.Union[int, typing.Sequence[int]], + padding: np.ndarray, dilation: typing.Union[int, typing.Sequence[int]], kernel_size: typing.Union[int, typing.Sequence[int]], stride: typing.Union[int, typing.Sequence[int]], @@ -37,8 +37,8 @@ def _calculate_conv_output( :param input_shape: input shape, either int or (int, int) :type input_shape: int | typing.Sequence[int] - :param padding: padding - :type padding: int | typing.Sequence[int] + :param padding: padding, each dimension has two values + :type padding: integer array, of shape (2,) or (2, 2), etc. :param dilation: dilation :type dilation: int | typing.Sequence[int] :param kernel_size: kernel size @@ -58,7 +58,7 @@ def _calculate_conv_output( shape = np.floor( ( _index_tuple(input_shape, i) - + 2 * _index_tuple(padding, i) + + sum(padding if isinstance(padding[0], (int, np.integer)) else padding[i]) - _index_tuple(dilation, i) * (_index_tuple(kernel_size, i) - 1) - 1 ) @@ -360,12 +360,17 @@ class Conv1d(NIRNode): input_shape: typing.Optional[int] # N weight: np.ndarray # Weight C_out * C_in * N stride: int # Stride - padding: int # Padding + padding: typing.Union[int, typing.Tuple[int, int]] # Padding dilation: int # Dilation groups: int # Groups bias: np.ndarray # Bias C_out def __post_init__(self): + if isinstance(self.padding, int): + self.padding = (self.padding, self.padding) + elif isinstance(self.padding[0], (int, np.integer)): + assert len(self.padding) == 2, "Conv1D Padding must be of length 2" + self.padding = tuple([int(p) for p in self.padding]) if self.input_shape is None: # leave input and output types undefined self.input_type = {"input": None} @@ -401,7 +406,7 @@ class Conv2d(NIRNode): :param stride: Stride :type stride: int | int, int :param padding: Padding - :type padding: int | int, int + :type padding: int | int, int | ((int, int), (int, int)) :param dilation: Dilation :type dilation: int | int, int :param groups: Groups @@ -414,14 +419,20 @@ class Conv2d(NIRNode): input_shape: typing.Optional[typing.Tuple[int, int]] # N_x, N_y weight: np.ndarray # Weight C_out * C_in * W_x * W_y stride: typing.Union[int, typing.Tuple[int, int]] # Stride - padding: typing.Union[int, typing.Tuple[int, int]] # Padding + padding: typing.Union[int, typing.Tuple[int, int], typing.Sequence[typing.Tuple[int, int]]] dilation: typing.Union[int, typing.Tuple[int, int]] # Dilation groups: int # Groups bias: np.ndarray # Bias C_out def __post_init__(self): if isinstance(self.padding, int): - self.padding = (self.padding, self.padding) + self.padding = ((self.padding, self.padding), (self.padding, self.padding)) + elif isinstance(self.padding[0], (int, np.integer)): + assert len(self.padding) == 2, "Conv2D Padding must be of length 2" + self.padding = (self.padding[0], self.padding[0]), (self.padding[1], self.padding[1]) + elif isinstance(self.padding[0][0], (int, np.integer)): + assert all(len(p) == 2 for p in self.padding), "Padding must be a tuple of length 2" + self.padding = tuple([tuple([int(e) for e in p]) for p in self.padding]) if isinstance(self.stride, int): self.stride = (self.stride, self.stride) if isinstance(self.dilation, int):