Example #1
0
def max_pool_handler(converter: TensorFlowConverter, tf_op: "tf.Operation"):
    x = converter.get_variable(tf_op.inputs[0])
    data_format = tf_op.get_attr("data_format")
    check_data_format(x, data_format)

    ksize = tuple(tf_op.get_attr("ksize"))  # type: Tuple[int,...]
    assert ksize[x.order.axes_dict[Axis.N]] == 1
    assert ksize[x.order.axes_dict[Axis.C]] == 1
    ksize = (ksize[x.order.axes_dict[Axis.H]],
             ksize[x.order.axes_dict[Axis.W]])

    stride = tuple(tf_op.get_attr("strides"))  # type: Tuple[int,...]
    assert stride[x.order.axes_dict[Axis.N]] == 1
    assert stride[x.order.axes_dict[Axis.C]] == 1
    stride = (stride[x.order.axes_dict[Axis.H]],
              stride[x.order.axes_dict[Axis.W]])

    x, padding = convolution_handler_preprocess(
        x,
        ksize=ksize,
        padding=tf_op.get_attr("padding"),
        dilation_rate=(1, 1),
        data_format=data_format)

    y, = MaxPooling2D(None,
                      ksize=ksize,
                      stride=stride,
                      padding=padding,
                      cover_all=False)(x)
    converter.set_variable(tf_op.outputs[0], y)
Example #2
0
def test_irregular_size():
    vx = np.random.rand(2, 4, 6, 8)
    vy = np.empty((2, 4, 5, 8))
    KH, KW = (3, 4)
    SH, SW = (1, 2)
    PH, PW = (1, 3)

    for n, h2, w2, c in itertools.product(range(vy.shape[0]),
                                          range(vy.shape[1]),
                                          range(vy.shape[2]),
                                          range(vy.shape[3])):
        v = -float("inf")
        for (kh, kw) in itertools.product(range(KH), range(KW)):
            h1 = (h2 * SH - PH) + kh
            w1 = (w2 * SW - PW) + kw

            v = max(v, 0 if (h1 < 0 or h1 >= 4 or w1 < 0 or w1 >= 6) else vx[n, h1, w1, c])

        vy[n, h2, w2, c] = v

    x = Variable(vx.shape, order=OrderNHWC)
    y, = MaxPooling2D(None, ksize=(KH, KW), stride=(SH, SW), padding=(PH, PW))(x)

    generate_kernel_test_case(
        description=f"Max Pooling with irregular window size",
        backend=["webgpu", "webgl", "webassembly", "fallback"],
        graph=Graph([x], [y]),
        inputs={x: vx},
        expected={y: vy}
    )
Example #3
0
def max_pool_handler(converter: TensorFlowConverter, tf_op: "tf.Operation"):
    # padding: https://www.tensorflow.org/api_guides/python/nn#Notes_on_SAME_Convolution_Padding

    x = converter.get_variable(tf_op.inputs[0])  # NHWC
    assert tf_op.get_attr("data_format") == b"NHWC"
    unify_order(x.order, OrderNHWC)
    ksize_nhwc = tf_op.get_attr("ksize")  # type: List[int]
    assert ksize_nhwc[0] == 1
    assert ksize_nhwc[3] == 1
    ksize = (ksize_nhwc[1], ksize_nhwc[2])

    stride_nhwc = tf_op.get_attr("strides")  # type: List[int]
    assert stride_nhwc[0] == 1
    assert stride_nhwc[3] == 1
    stride_hw = stride_nhwc[1:3]
    padding_name = tf_op.get_attr("padding")  # type: str
    if padding_name == b"SAME":
        padding = (padding_same(x.shape_dict[Axis.H], ksize[0], stride_hw[0]),
                   padding_same(x.shape_dict[Axis.W], ksize[1], stride_hw[1]))
    elif padding_name == b"VALID":
        padding = (0, 0)
    else:
        raise NotImplementedError(
            f"[TensorFlowConverter] MaxPool: padding '{padding_name}' is not supported yet."
        )

    y, = MaxPooling2D(None, ksize=ksize, stride=stride_hw, padding=padding)(x)
    converter.set_variable(tf_op.outputs[0], y)
Example #4
0
def _convert_max_pooling1d(converter: KerasConverter,
                           k_op: "keras.layers.MaxPooling1D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])

    # FIXME: More effective implementation
    y, = Reshape(None,
                 in_order=x.order,
                 out_order=OrderNHWC,
                 out_shape=[x.shape[0], x.shape[1], 1, x.shape[2]])(x)

    if k_op.padding == "valid":
        padding = (0, 0)

    elif k_op.padding == "same":
        padding = (k_op.pool_size[0] // 2, 0)

    else:
        raise NotImplementedError(f"Unknown padding: {k_op.padding}")

    y, = MaxPooling2D(None,
                      ksize=(k_op.pool_size[0], 1),
                      stride=(1, 1),
                      padding=padding)(y)
    z, = Reshape(None,
                 in_order=y.order,
                 out_order=OrderNTC,
                 out_shape=[y.shape[0], y.shape[1], y.shape[3]])(y)

    converter.set_variable(converter.get_output_tensor(k_op)[0], z)
Example #5
0
    def convert_layer_maxpooling2d(self, layer_config: Dict[str, object], inputs: List[Variable]) -> List[Variable]:
        """
        Example:
          {'class_name': 'MaxPooling2D',
   'config': {'data_format': 'channels_last',
    'name': 'max_pooling2d_1',
    'padding': 'valid',
    'pool_size': [2, 2],
    'strides': [2, 2],
    'trainable': True}},

        :param layer_config: 
        :param inputs: 
        :return: 
        """
        assert len(inputs) == 1
        input = inputs[0]
        name: str = layer_config["name"]
        ksize: Tuple[int, int] = tuple(layer_config["pool_size"])
        stride: Tuple[int, int] = tuple(layer_config["strides"])
        padding_keras: str = layer_config["padding"]  # valid or same
        if padding_keras == "valid":
            padding = (0, 0)
        elif padding_keras == "same":
            padding = (ksize[0] // 2, ksize[1] // 2)
        else:
            raise ValueError("Unknown padding")

        max_pooling_2d_opr = MaxPooling2D(name,
                                          ksize=ksize,
                                          stride=stride,
                                          padding=padding)
        y, = max_pooling_2d_opr(input)

        return [y]
Example #6
0
def _convert_max_pooling2d(converter: KerasConverter,
                           k_op: "keras.layers.MaxPooling2D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])

    if k_op.data_format == "channels_first":
        assert x.order == OrderNCHW

    elif k_op.data_format == "channels_last":
        assert x.order == OrderNHWC

    else:
        raise ValueError(
            f"[KerasConverter] Unknown data format: {k_op.data_format}")

    ksize = tuple(k_op.pool_size)
    stride = tuple(k_op.strides)
    if k_op.padding == "valid":
        padding = (0, 0)

    elif k_op.padding == "same":
        padding = (ksize[0] // 2, ksize[1] // 2)

    else:
        raise ValueError(f"[KerasConverter] Unknown padding: {k_op.padding}")

    y, = MaxPooling2D(None, ksize=ksize, stride=stride, padding=padding)(x)
    converter.set_variable(converter.get_output_tensor(k_op)[0], y)
Example #7
0
def template(x_order=OrderNHWC, y_order=OrderNHWC, description: str = ""):
    vx = np.random.rand(2, 4, 6, 8)
    vy = np.empty((2, 2, 3, 8))
    KH, KW = (2, 2)
    SH, SW = (2, 2)
    PH, PW = (0, 0)

    for n, h2, w2, c in itertools.product(range(vy.shape[0]),
                                          range(vy.shape[1]),
                                          range(vy.shape[2]),
                                          range(vy.shape[3])):
        v = -float("inf")
        for (kh, kw) in itertools.product(range(KH), range(KW)):
            h1 = (h2 * SH - PH) + kh
            w1 = (w2 * SW - PW) + kw

            v = max(v, 0 if (h1 < 0 or h1 >= 4 or w1 < 0 or w1 >= 6) else vx[n, h1, w1, c])

        vy[n, h2, w2, c] = v

    x = Variable(vx.shape, order=x_order)
    y, = MaxPooling2D(None, ksize=(KH, KW), stride=(SH, SW), padding=(PH, PW))(x)
    y.change_order(y_order)

    generate_kernel_test_case(
        description=f"Max Pooling {description}",
        backend=["webgpu", "webgl", "webassembly", "fallback"],
        graph=Graph([x], [y]),
        inputs={x: np.transpose(vx, [OrderNHWC.axes_dict[a] for a in x.order.axes])},
        expected={y: np.transpose(vy, [OrderNHWC.axes_dict[a] for a in y.order.axes])},
    )
Example #8
0
def test_general():
    vx = np.random.rand(2, 4, 6, 8)
    vy = np.empty((2, 3, 4, 8))

    for n, h2, w2, c in itertools.product(range(vy.shape[0]),
                                          range(vy.shape[1]),
                                          range(vy.shape[2]),
                                          range(vy.shape[3])):
        v = -float("Infinity")
        for (kh, kw) in itertools.product(range(3), range(3)):
            h1 = (h2 * 2 - 1) + kh
            w1 = (w2 * 2 - 1) + kw

            v = max(
                v, 0 if
                (h1 < 0 or h1 >= 4 or w1 < 0 or w1 >= 6) else vx[n, h1, w1, c])

        vy[n, h2, w2, c] = v

    x = Variable(vx.shape, order=OrderNHWC)
    y, = MaxPooling2D(None, ksize=3, padding=1, stride=2)(x)

    generate_kernel_test_case(description=f"Max Pooling",
                              backend=["webgpu", "webassembly", "fallback"],
                              graph=Graph([x], [y]),
                              inputs={x: vx},
                              expected={y: vy})
Example #9
0
def _convert_max_pool(converter: ONNXConverter, onnx_op: INodeProto):
    x = converter.get_variable(onnx_op.input[0])
    x.order.unify(OrderNCHW)

    attrs = attribute_dict(onnx_op)
    ksize = list(attrs["kernel_shape"].ints)
    dilations = list(attrs["dilations"].ints)
    if any(d != 1 for d in dilations):
        raise NotImplementedError(
            "[ONNXConverter] MaxPool is supported only when dilations are 1.")

    stride = list(attrs["strides"].ints)

    pad = list(attrs["pads"].ints)
    if len(pad) == 2:
        # NOTE:
        # In PyTorch, pads is generated as tuple of 2 integers, but ONNX spec says that pads contains 2*N integers where N is the number of
        # padded dimension. It's maybe PyTorch's bug.
        pass

    else:
        if any(pad[2 * i] != pad[2 * i + 1] for i in range(len(pad) // 2)):
            raise NotImplementedError(
                "[ONNXConverter] odd-size padding is not supported.")
        pad = [pad[0], pad[2]]

    y, = MaxPooling2D(None, ksize=ksize, stride=stride, padding=pad)(x)
    converter.set_variable(onnx_op.output[0], y)
Example #10
0
def _convert_max_pool(converter: ONNXConverter, onnx_op: INodeProto):
    x = converter.get_variable(onnx_op.input[0])
    x.order.unify(OrderNCHW)

    attrs = attribute_dict(onnx_op)
    ksize = list(attrs["kernel_shape"].ints)
    stride = list(attrs["strides"].ints)

    pad = list(attrs["pads"].ints)
    if len(pad) == 2:
        # NOTE:
        # In PyTorch, pads is generated as tuple of 2 integers, but ONNX spec says that pads contains 2*N integers where N is the number of
        # padded dimension. It's maybe PyTorch's bug.
        pass

    else:
        if any(pad[2 * i] != pad[2 * i + 1] for i in range(len(pad) // 2)):
            raise NotImplementedError(
                "[ONNXConverter] odd-size padding is not supported.")
        pad = [pad[0], pad[2]]

    # https://github.com/onnx/onnx/blob/master/docs/Operators.md
    # output_spatial_shape[i] = floor((input_spatial_shape[i] + pad_shape[i] - kernel_spatial_shape[i]) / strides_spatial_shape[i] + 1)
    # In PyTorch, nn.MaxPool2d(2) with input size 11 produces output size 5,
    # where kernel_shape=2, pads=0, strides=2 is set as onnx attributes.
    # It corresponds to cover_all=False.
    y, = MaxPooling2D(None,
                      ksize=ksize,
                      stride=stride,
                      padding=pad,
                      cover_all=False)(x)
    converter.set_variable(onnx_op.output[0], y)
Example #11
0
def max_pool_handler(converter: TensorFlowConverter, tf_op: "tf.Operation"):
    x = converter.get_variable(tf_op.inputs[0])
    data_format = tf_op.get_attr("data_format")
    check_data_format(x, data_format)

    ksize = tuple(tf_op.get_attr("ksize"))  # type: Tuple[int,...]
    assert ksize[x.order.axes_dict[Axis.N]] == 1
    assert ksize[x.order.axes_dict[Axis.C]] == 1
    ksize = (ksize[x.order.axes_dict[Axis.H]],
             ksize[x.order.axes_dict[Axis.W]])

    stride = tuple(tf_op.get_attr("strides"))  # type: Tuple[int,...]
    assert stride[x.order.axes_dict[Axis.N]] == 1
    assert stride[x.order.axes_dict[Axis.C]] == 1
    stride = (stride[x.order.axes_dict[Axis.H]],
              stride[x.order.axes_dict[Axis.W]])

    padding = (
        parse_padding(tf_op.get_attr("padding"), ksize[0], 1),
        parse_padding(tf_op.get_attr("padding"), ksize[1], 1),
    )
    x, padding = convert_odd_padding_to_concat(x,
                                               padding=padding,
                                               value=-1.0e10)

    y, = MaxPooling2D(None,
                      ksize=ksize,
                      stride=stride,
                      padding=padding,
                      cover_all=False)(x)
    converter.set_variable(tf_op.outputs[0], y)
Example #12
0
def _convert_global_max_pooling2d(converter: KerasConverter, k_op: "keras.layers.GlobalMaxPooling2D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])
    check_data_format(x, k_op.data_format)

    y, = MaxPooling2D(None, ksize=(x.shape_dict[Axis.H], x.shape_dict[Axis.W]), stride=(1, 1), padding=(0, 0))(x)

    # flatten without changing memory layout
    z = y.reshape([y.shape[0], mul(y.shape[1:])], OrderNC)
    converter.set_variable(converter.get_output_tensor(k_op)[0], z)
Example #13
0
def _convert_global_max_pooling1d(converter: KerasConverter, k_op: "keras.layers.GlobalMaxPooling1D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])

    y = x.reshape([x.shape[0], x.shape[1], 1, x.shape[2]], OrderNHWC)
    y, = MaxPooling2D(None, ksize=(x.shape[1], 1), stride=(1, 1), padding=(0, 0))(y)

    # flatten without changing memory layout
    z = y.reshape([y.shape[0], mul(y.shape[1:])], OrderNC)
    converter.set_variable(converter.get_output_tensor(k_op)[0], z)
Example #14
0
    def __call__(self, inputs: List[Variable]) -> Tuple[Variable]:
        conv_opr = MaxPooling2D(generate_unique_name(self.cfunc.label),
                                ksize=(self.cfunc.kh, self.cfunc.kw),
                                stride=(self.cfunc.sy, self.cfunc.sx),
                                padding=(self.cfunc.ph, self.cfunc.pw))

        opr_out, = conv_opr(inputs[0])
        opr_out.change_order(OrderNCHW)

        return opr_out,
Example #15
0
def _convert_global_max_pooling1d(converter: KerasConverter, k_op: keras.layers.GlobalMaxPooling1D):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])

    # FIXME: More effective implementation
    y, = Reshape(None, in_order=OrderNTC, out_order=OrderNHWC, out_shape=[x.shape[0], x.shape[1], 1, x.shape[2]])(x)
    y, = MaxPooling2D(None, ksize=(x.shape[1], 1), stride=(1, 1), padding=(0, 0))(y)

    # flatten without changing memory layout
    z, = Reshape(None, in_order=y.order, out_order=OrderNC, out_shape=[y.shape[0], mul(y.shape[1:])])(y)
    converter.set_variable(converter.get_output_tensor(k_op)[0], z)
Example #16
0
def _convert_max_pooling1d(converter: KerasConverter, k_op: "keras.layers.MaxPooling1D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])

    y = x.reshape([x.shape[0], x.shape[1], 1, x.shape[2]], OrderNHWC)
    ksize = (k_op.pool_size[0], 1)
    stride = (k_op.strides[0], 1)
    padding = (parse_padding(k_op.padding, ksize[0], 1)[0], 0)

    y, = MaxPooling2D(None, ksize=ksize, stride=stride, padding=padding)(y)
    z = y.reshape([y.shape[0], y.shape[1], y.shape[3]], OrderNTC)

    converter.set_variable(converter.get_output_tensor(k_op)[0], z)
Example #17
0
def _convert_max_pooling2d(converter: KerasConverter,
                           k_op: "keras.layers.MaxPooling2D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])
    check_data_format(x, k_op.data_format)

    ksize = tuple(k_op.pool_size)
    stride = tuple(k_op.strides)
    padding = (parse_padding(k_op.padding, ksize[0],
                             1), parse_padding(k_op.padding, ksize[1], 1))

    y, = MaxPooling2D(None, ksize=ksize, stride=stride, padding=padding)(x)
    converter.set_variable(converter.get_output_tensor(k_op)[0], y)
Example #18
0
def _convert_max_pooling2d(converter: KerasConverter, k_op: "keras.layers.MaxPooling2D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])
    check_data_format(x, k_op.data_format)

    padding = (
        parse_padding(k_op.padding, k_op.pool_size[0], 1),
        parse_padding(k_op.padding, k_op.pool_size[1], 1)
    )
    x, padding = convert_odd_padding_to_concat(x, padding=padding, value=-1.0e10)

    y, = MaxPooling2D(None, ksize=k_op.pool_size, stride=k_op.strides, padding=padding, cover_all=False)(x)
    converter.set_variable(converter.get_output_tensor(k_op)[0], y)
Example #19
0
def _convert_max_pooling2d(converter: ChainerConverter,
                           c_op: "chainer.functions.MaxPooling2D"):
    x = converter.get_variable(c_op.inputs[0])
    x.order.unify(OrderNCHW)

    pool_opr = MaxPooling2D(None,
                            ksize=(c_op.kh, c_op.kw),
                            stride=(c_op.sy, c_op.sx),
                            padding=(c_op.ph, c_op.pw),
                            cover_all=c_op.cover_all)
    y, = pool_opr(x)

    converter.set_variable(c_op.outputs[0](), y)
Example #20
0
def main(k, s, p, n, h1, w1, c1, expected_shape_dict: Dict[Axis, int]):
    orders = [OrderNHWC, OrderHWNC, OrderHWCN, OrderNCHW, OrderCNHW, OrderCHWN]

    for order_x in orders:
        op = MaxPooling2D(None, ksize=k, stride=s, padding=p)

        x = Variable((n, h1, w1, c1), OrderNHWC)
        x.change_order(order_x)

        y, = op(x)

        for axis in y.order.axes:
            assert y.shape_dict[axis] == expected_shape_dict[axis]
Example #21
0
def _convert_max_pooling2d(converter: KerasConverter,
                           k_op: "keras.layers.MaxPooling2D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])
    x, padding = convolution_handler_preprocess(x,
                                                ksize=k_op.pool_size,
                                                padding=k_op.padding,
                                                dilation_rate=(1, 1),
                                                data_format=k_op.data_format)
    y, = MaxPooling2D(None,
                      ksize=k_op.pool_size,
                      stride=k_op.strides,
                      padding=padding,
                      cover_all=False)(x)
    converter.set_variable(converter.get_output_tensor(k_op)[0], y)
Example #22
0
def _convert_max_pooling2d(converter: ChainerConverter, c_op: "chainer.functions.MaxPooling2D"):
    if not c_op.cover_all:
        raise NotImplementedError("'cover_all=False' property in 'MaxPooling2D' is not supported.")

    x = converter.get_variable(c_op.inputs[0])
    unify_order(x.order, OrderNCHW)

    pool_opr = MaxPooling2D(None,
                            ksize=(c_op.kh, c_op.kw),
                            stride=(c_op.sy, c_op.sx),
                            padding=(c_op.ph, c_op.pw))

    y, = pool_opr(x)

    converter.set_variable(c_op.outputs[0](), y)
Example #23
0
def _convert_global_max_pooling2d(converter: KerasConverter, k_op: keras.layers.GlobalMaxPooling2D):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])
    if k_op.data_format == "channels_first":
        assert x.order == OrderNCHW

    elif k_op.data_format == "channels_last":
        assert x.order == OrderNHWC

    else:
        raise ValueError(f"[KerasConverter] Unknown data format: {k_op.data_format}")

    y, = MaxPooling2D(None, ksize=(x.shape_dict[Axis.H], x.shape_dict[Axis.W]), stride=(1, 1), padding=(0, 0))(x)

    # flatten without changing memory layout
    z, = Reshape(None, in_order=y.order, out_order=OrderNC, out_shape=[y.shape[0], mul(y.shape[1:])])(y)
    converter.set_variable(converter.get_output_tensor(k_op)[0], z)
Example #24
0
def _convert_max_pooling2d(converter: ChainerConverter, c_op: "chainer.functions.MaxPooling2D"):
    if not c_op.cover_all:
        raise NotImplementedError("'cover_all=False' property in 'MaxPooling2D' is not supported.")

    x = converter.get_variable(c_op.inputs[0])
    x.order.unify(OrderNCHW)

    pool_opr = MaxPooling2D(None,
                            ksize=(c_op.kh, c_op.kw),
                            stride=(c_op.sy, c_op.sx),
                            padding=(c_op.ph, c_op.pw))
    if c_op.cover_all == False:
        console.warning(
            "[MaxPooling2D] MaxPooling2D in WebDNN is always calculated as cover_all=True mode. "
            "Therefore the result may be difference from chainer's output.")

    y, = pool_opr(x)

    converter.set_variable(c_op.outputs[0](), y)
Example #25
0
def _convert_max_pooling2d(converter: KerasConverter,
                           k_op: "keras.layers.MaxPooling2D"):
    x = converter.get_variable(converter.get_input_tensor(k_op)[0])

    if k_op.data_format == "channels_first":
        x.order.unify(OrderNCHW)

    elif k_op.data_format == "channels_last":
        x.order.unify(OrderNHWC)

    else:
        raise ValueError(
            f"[KerasConverter] Unknown data format: {k_op.data_format}")

    ksize = tuple(k_op.pool_size)
    stride = tuple(k_op.strides)
    if k_op.padding == "valid":
        padding = (0, 0)

    elif k_op.padding == "same":
        # https://www.tensorflow.org/api_guides/python/nn#convolution
        if x.shape_dict[Axis.H] % stride[0] == 0:
            pad_h = max(ksize[0] - stride[0], 0)
        else:
            pad_h = max(ksize[0] - (x.shape_dict[Axis.H] % stride[0]), 0)

        if x.shape_dict[Axis.W] % stride[1] == 0:
            pad_w = max(ksize[1] - stride[1], 0)
        else:
            pad_w = max(ksize[1] - (x.shape_dict[Axis.W] % stride[1]), 0)

        padding = (pad_h // 2, pad_w // 2)

    else:
        raise ValueError(f"[KerasConverter] Unknown padding: {k_op.padding}")

    y, = MaxPooling2D(None, ksize=ksize, stride=stride, padding=padding)(x)
    converter.set_variable(converter.get_output_tensor(k_op)[0], y)