Ejemplo n.º 1
0
def convert_Absolute(func, opset_version, input_names,
                     output_names, context, parameters):
    if opset_version == 1:
        return onnx_helper.make_node(
            'Abs', input_names, output_names, consumed_inputs=[1]),
    elif opset_version == 6:
        return onnx_helper.make_node('Abs', input_names, output_names),
Ejemplo n.º 2
0
def convert_SplitAxis(func, opset_version, input_names, output_names, context):
    if func.indices is not None:
        indices_or_sections = func.indices
    else:
        indices_or_sections = func.sections

    total = func.inputs[0].shape[func.axis]
    if hasattr(indices_or_sections, '__iter__'):
        split = []
        prev_i = 0
        for i in indices_or_sections:
            split.append(i - prev_i)
            prev_i = i
        split.append(total - prev_i)
    else:
        length = total // indices_or_sections
        split = [length for _ in range(indices_or_sections)]

    assert len(output_names) == len(split)
    if opset_version == 1:
        return onnx_helper.make_node('Split',
                                     input_names,
                                     output_names,
                                     axis=func.axis,
                                     split=split),
    elif opset_version == 2:
        return onnx_helper.make_node('Split',
                                     input_names,
                                     output_names,
                                     axis=func.axis,
                                     split=split),
Ejemplo n.º 3
0
def convert_Add(func, opset_version, input_names, output_names,
                context, parameters):
    if opset_version == 1:
        return onnx_helper.make_node(
            'Add', input_names, output_names, consumed_inputs=[1, 1]),
    elif opset_version == 6 or opset_version == 7:
        return onnx_helper.make_node('Add', input_names, output_names),
Ejemplo n.º 4
0
def convert_MaxPoolingND(func, opset_version, input_names, num_outputs,
                         parameters):
    pad = list(func.pad[:])
    if func.cover_all:
        # Supports cover_all by setting extra padding
        for p, s, k in zip(pad, func.stride, func.ksize):
            # Raise exception because a virtual pad for cover_all must be
            # smaller than ksize in the current ONNX
            if k <= p + s - 1:
                raise RuntimeError(
                    'Could not correctly export in the current setting'
                    ' (ksize={} pad={} stride={}). Please set pad or stride to'
                    'lower value.'.format(k, p, s))
        pad.extend([p + s - 1 for p, s in zip(pad, func.stride)])
    else:
        pad = pad * 2

    if opset_version == 1:
        return onnx_helper.make_node('MaxPool',
                                     input_names,
                                     num_outputs,
                                     kernel_shape=func.ksize,
                                     pads=pad,
                                     strides=func.stride),
    elif opset_version == 8:
        return onnx_helper.make_node(
            'MaxPool',
            input_names,
            num_outputs,
            kernel_shape=func.ksize,
            pads=pad,
            strides=func.stride,
            storage_order=0,  # row major
        ),
Ejemplo n.º 5
0
def convert_MaxPoolingND(
        func, opset_version, input_names, output_names, context):
    pad = list(func.pad[:])
    if func.cover_all:
        # Supports cover_all by setting extra padding
        # NOTE: onnxruntime may not run when "k <= p + s - 1".
        pad.extend([p + s - 1 for p, s in zip(pad, func.stride)])
    else:
        pad = pad * 2

    if opset_version == 1:
        return onnx_helper.make_node(
            'MaxPool', input_names, output_names,
            kernel_shape=func.ksize,
            pads=pad,
            strides=func.stride
        ),
    elif opset_version == 8:
        return onnx_helper.make_node(
            'MaxPool', input_names, output_names,
            kernel_shape=func.ksize,
            pads=pad,
            strides=func.stride,
            storage_order=0,  # row major
        ),
Ejemplo n.º 6
0
def convert_MaxPooling2D(func, opset_version, input_names, num_outputs,
                         parameters):
    pad = [func.ph, func.pw]
    stride = [func.sy, func.sx]
    ksize = [func.kh, func.kw]
    if func.cover_all:
        # Supports cover_all by setting extra padding
        for p, s, k in zip(pad, stride, ksize):
            if k <= p + s - 1:
                raise RuntimeError(
                    'Could not correctly export in the current setting'
                    ' (ksize={} pad={} stride={}). Please set pad or stride to'
                    'lower value.'.format(k, p, s))
        pad.extend([p + s - 1 for p, s in zip(pad, stride)])
    else:
        pad = pad * 2

    if opset_version == 1:
        return onnx_helper.make_node('MaxPool',
                                     input_names,
                                     num_outputs,
                                     kernel_shape=ksize,
                                     pads=pad,
                                     strides=stride),
    elif opset_version == 8:
        return onnx_helper.make_node(
            'MaxPool',
            input_names,
            num_outputs,
            kernel_shape=ksize,
            pads=pad,
            strides=stride,
            storage_order=0,  # row major
        ),
Ejemplo n.º 7
0
def convert_SplitAxis(func, opset_version, input_names, num_outputs,
                      parameters):
    if func.indices is not None:
        indices_or_sections = func.indices
    else:
        indices_or_sections = func.sections

    if hasattr(indices_or_sections, '__iter__'):
        split = []
        prev_i = 0
        for i in indices_or_sections:
            split.append(i - prev_i)
            prev_i = i
    else:
        length = func.inputs[0].shape[func.axis] // indices_or_sections
        split = [length for _ in range(indices_or_sections)]

    if opset_version == 1:
        return onnx_helper.make_node('Split',
                                     input_names,
                                     num_outputs,
                                     axis=func.axis,
                                     split=split),
    elif opset_version == 2:
        return onnx_helper.make_node('Split',
                                     input_names,
                                     num_outputs,
                                     axis=func.axis,
                                     split=split),
Ejemplo n.º 8
0
def convert_Tanh(func, opset_version, input_names, output_names, context):
    if opset_version == 1:
        return onnx_helper.make_node(
            'Tanh', input_names, output_names,
            consumed_inputs=[1]),
    elif opset_version == 6:
        return onnx_helper.make_node('Tanh', input_names, output_names),
Ejemplo n.º 9
0
def convert_LinearFunction(func, opset_version, input_names, output_names,
                           context, parameters):
    # When the func has bias
    if len(func.inputs) == 2:
        bias_dim = func.inputs[1].shape[0]
        bias = np.zeros((bias_dim, ), dtype=func.inputs[0].dtype)
        bias_param = chainer.Parameter(bias)
        parameters.append(bias_param)
        input_names.append(context.get_name(bias_param))

    if opset_version == 1 or opset_version == 6:
        return onnx_helper.make_node('Gemm',
                                     input_names,
                                     output_names,
                                     alpha=1.0,
                                     beta=1.0,
                                     broadcast=1,
                                     transA=0,
                                     transB=1),
    elif opset_version == 7:
        return onnx_helper.make_node('Gemm',
                                     input_names,
                                     output_names,
                                     alpha=1.0,
                                     beta=1.0,
                                     transA=0,
                                     transB=1),
Ejemplo n.º 10
0
def convert_MaxPooling2D(func, opset_version, input_names, output_names,
                         context):
    pad = [func.ph, func.pw]
    stride = [func.sy, func.sx]
    ksize = [func.kh, func.kw]
    attrs = {}
    if func.cover_all:
        if opset_version < 11:
            # Supports cover_all by setting extra padding
            # NOTE: onnxruntime may not run when "k <= p + s - 1".
            pad.extend([p + s - 1 for p, s in zip(pad, func.stride)])
        else:
            pad = pad * 2
            attrs['ceil_mode'] = 1
    else:
        pad = pad * 2

    if opset_version == 1:
        return onnx_helper.make_node('MaxPool',
                                     input_names,
                                     output_names,
                                     kernel_shape=ksize,
                                     pads=pad,
                                     strides=stride),
    elif opset_version >= 8:
        return onnx_helper.make_node(
            'MaxPool',
            input_names,
            output_names,
            kernel_shape=ksize,
            pads=pad,
            strides=stride,
            storage_order=0,  # row major
            **attrs,
        ),
Ejemplo n.º 11
0
def convert_Convolution2DFunction(func, opset_version, input_names,
                                  output_names, context, parameters):
    if hasattr(func, 'dy') and hasattr(func, 'dx'):
        node = onnx_helper.make_node(
            'Conv',
            input_names,
            output_names,
            dilations=(func.dy, func.dx),
            kernel_shape=func.inputs[1].shape[2:],
            # pads: [x1_begin, x2_begin...x1_end, x2_end,...]
            pads=(func.ph, func.pw, func.ph, func.pw),
            strides=(func.sy, func.sx),
            group=func.groups,
        )
    else:
        node = onnx_helper.make_node(
            'Conv',
            input_names,
            output_names,
            dilations=(1, 1),
            kernel_shape=func.inputs[1].shape[2:],
            pads=(func.ph, func.pw, func.ph, func.pw),
            strides=(func.sy, func.sx),
            group=func.groups,
        )
    return node,
Ejemplo n.º 12
0
def convert_Pad(func, opset_version, input_names, output_names,
                context, parameters):
    if func.mode not in ['constant', 'reflect', 'edge']:
        raise ValueError(
            '{} mode is not supported in ONNX\'s Pad operation'.format(
                func.mode))

    pad_begin = []
    pad_end = []
    pad_bw = func.pad_bw
    if pad_bw.ndim == 1:
        pad_bw = np.tile(pad_bw, (len(func.inputs[0].shape), 1))
    for pp in pad_bw.tolist():
        pad_begin.append(pp[0])
        pad_end.append(pp[1])
    pad = pad_begin + pad_end

    if 'constant_values' in func.keywords:
        values = func.keywords['constant_values']
        if not isinstance(values, int) and len(values) > 1:
            raise ValueError(
                'ONNX doesn\'t support multiple constant values for Pad '
                'operation')
        elif not isinstance(values, int):
            values = float(values[0])
        else:
            values = float(values)

        if opset_version == 1:
            node = onnx_helper.make_node(
                'Pad', input_names, output_names,
                mode=func.mode,
                paddings=pad,
                value=values
            )
        elif opset_version == 2:
            node = onnx_helper.make_node(
                'Pad', input_names, output_names,
                mode=func.mode,
                pads=pad,
                value=values
            )
    else:
        if opset_version == 1:
            node = onnx_helper.make_node(
                'Pad', input_names, output_names,
                mode=func.mode,
                paddings=pad,
                value=0.,
            )
        elif opset_version == 2:
            node = onnx_helper.make_node(
                'Pad', input_names, output_names,
                mode=func.mode,
                pads=pad,
                value=0.,
            )

    return node,
Ejemplo n.º 13
0
def convert_Mul(func, opset_version, input_names, output_names, context):
    if opset_version == 1:
        return onnx_helper.make_node('Mul',
                                     input_names,
                                     output_names,
                                     consumed_inputs=[1, 1]),
    elif opset_version == 6 or opset_version == 7:
        return onnx_helper.make_node('Mul', input_names, output_names),
Ejemplo n.º 14
0
def convert_ReLU(func, opset_version, input_names, num_outputs, parameters):
    if opset_version == 1:
        return onnx_helper.make_node('Relu',
                                     input_names,
                                     num_outputs,
                                     consumed_inputs=[1]),
    elif opset_version == 6:
        return onnx_helper.make_node('Relu', input_names, num_outputs),
Ejemplo n.º 15
0
def convert_Div(func, opset_version, input_names, num_outputs, parameters):
    if opset_version == 1:
        return onnx_helper.make_node('Div',
                                     input_names,
                                     num_outputs,
                                     consumed_inputs=[1, 1]),
    elif opset_version == 6 or opset_version == 7:
        return onnx_helper.make_node('Div', input_names, num_outputs),
Ejemplo n.º 16
0
def convert_Square(func, opset_version, input_names, num_outputs, parameters):
    if opset_version == 1:
        return onnx_helper.make_node('Mul', [input_names[0], input_names[0]],
                                     num_outputs,
                                     consumed_inputs=[1, 1]),
    elif opset_version == 6 or opset_version == 7:
        return onnx_helper.make_node('Mul', [input_names[0], input_names[0]],
                                     num_outputs),
Ejemplo n.º 17
0
def convert_PReLUFunction(
        func, opset_version, input_names, output_names, context):
    if opset_version == 1:
        return onnx_helper.make_node(
            'PRelu', input_names, output_names, consumed_inputs=[1]),
    elif opset_version == 6:
        return onnx_helper.make_node('PRelu', input_names, output_names),
    elif opset_version == 7:
        return onnx_helper.make_node('PRelu', input_names, output_names),
Ejemplo n.º 18
0
def convert_MulConstant(
        func, opset_version, input_names, output_names, context):
    value_name = context.add_const(
        np.array(func.value, dtype=func.inputs[0].dtype), 'value')
    input_names.append(value_name)

    if opset_version == 1:
        return onnx_helper.make_node(
            'Mul', input_names, output_names, consumed_inputs=[1, 1]),
    elif opset_version == 6 or opset_version == 7:
        return onnx_helper.make_node('Mul', input_names, output_names),
Ejemplo n.º 19
0
def convert_Concat(func, opset_version, input_names, num_outputs, parameters):
    if opset_version == 1:
        return onnx_helper.make_node('Concat',
                                     input_names,
                                     num_outputs,
                                     axis=func.axis),
    elif opset_version == 4:
        return onnx_helper.make_node('Concat',
                                     input_names,
                                     num_outputs,
                                     axis=func.axis),
Ejemplo n.º 20
0
def convert_ELU(func, opset_version, input_names, output_names, context):
    if opset_version == 1:
        return onnx_helper.make_node(
            'Elu', input_names, output_names,
            alpha=func.alpha,
        ),
    elif opset_version == 6:
        return onnx_helper.make_node(
            'Elu', input_names, output_names,
            alpha=func.alpha
        ),
Ejemplo n.º 21
0
def convert_Concat(func, opset_version, input_names, output_names, context):
    if opset_version == 1:
        return onnx_helper.make_node('Concat',
                                     input_names,
                                     output_names,
                                     axis=func.axis),
    elif opset_version == 4:
        return onnx_helper.make_node('Concat',
                                     input_names,
                                     output_names,
                                     axis=func.axis),
Ejemplo n.º 22
0
def convert_Transpose(func, opset_version, input_names, output_names, context):

    if func.axes is None:
        node = onnx_helper.make_node('Transpose', input_names, output_names)
    else:
        node = onnx_helper.make_node('Transpose',
                                     input_names,
                                     output_names,
                                     perm=func.axes)

    return node,
Ejemplo n.º 23
0
def convert_DivFromConstant(
        func, opset_version, input_names, output_names, context):
    value_name = context.add_const(
        np.array(func.value, dtype=func.inputs[0].dtype), 'value')
    input_names[:0] = [value_name]

    if opset_version == 1:
        return onnx_helper.make_node(
            'Div', input_names, output_names, consumed_inputs=[1, 1]),
    elif opset_version == 6 or opset_version == 7:
        return onnx_helper.make_node('Div', input_names, output_names),
Ejemplo n.º 24
0
def convert_LeakyReLU(func, opset_version, input_names, output_names, context):
    if opset_version == 1:
        return onnx_helper.make_node(
            'LeakyRelu', input_names, output_names,
            alpha=func.slope,
            consumed_inputs=[1],
        ),
    elif opset_version == 6:
        return onnx_helper.make_node(
            'LeakyRelu', input_names, output_names,
            alpha=func.slope
        ),
Ejemplo n.º 25
0
def convert_MulConstant(func, opset_version, input_names,
                        output_names, context, parameters):
    value = np.array(func.value, dtype=func.inputs[0].dtype)
    value_param = chainer.Parameter(value)
    parameters.append(value_param)
    input_names.append(context.get_name(value_param))

    if opset_version == 1:
        return onnx_helper.make_node(
            'Mul', input_names, output_names, consumed_inputs=[1, 1]),
    elif opset_version == 6 or opset_version == 7:
        return onnx_helper.make_node('Mul', input_names, output_names),
Ejemplo n.º 26
0
def convert_Cast(func, opset_version, input_names, output_names, context):
    typ = func.type if isinstance(func.type, np.dtype) else np.dtype(func.type)
    if opset_version == 1:
        return onnx_helper.make_node(
            'Cast', input_names, output_names,
            to=TENSOR_TYPE_TO_NAME[NP_TYPE_TO_TENSOR_TYPE[typ]]
        ),
    elif opset_version == 6:
        return onnx_helper.make_node(
            'Cast', input_names, output_names,
            to=NP_TYPE_TO_TENSOR_TYPE[typ]
        ),
Ejemplo n.º 27
0
def convert_TransposeSequence(
        func, opset_version, input_names, output_names, context):
    if len(input_names) == 1:
        return onnx_helper.make_node(
            'Split', input_names, output_names, axis=0),
    elif len(output_names) == 1:
        return onnx_helper.make_node(
            'Concat', input_names, output_names, axis=0),
    else:
        raise ValueError(
            'ONNX-Chainer can convert TransposeSequence only when input '
            'or output length is 1')
Ejemplo n.º 28
0
def convert_ResizeImages(func, opset_version, input_names, output_names,
                         context):

    warnings.warn(
        '`resize_images` is mapped to `Upsampling` ONNX op with bilinear '
        'interpolation. '
        'Behavior of bilinear interpolation differs from each implementation. '
        'See the issue https://github.com/chainer/onnx-chainer/issues/147 '
        'for details.', UserWarning)

    outsize = (func.out_H, func.out_W)

    h, w = func.inputs[0].shape[2:]

    # Compute scaling factor.
    # NOTE(syoyo): Despite of its name, `Upsample` onnx op will downsample
    # images when scale value is less than 1.0
    scales = [
        1.0, 1.0,
        float(outsize[0]) / float(h),
        float(outsize[1]) / float(w)
    ]

    if (scales[2] < 1.0e-8) and (scales[3] < 1.0e-8):
        raise ValueError(
            'scaling factor is too small or zero. scales for h = {}, scales '
            'for w = {}'.format(scales[2], scales[3]))

    # resize_images in Chainer only supports bilinear interpolation
    # Actually this will be mapped to 'bilinear' in onnxruntime
    mode = 'linear'
    if opset_version == 7:
        return onnx_helper.make_node('Upsample',
                                     input_names,
                                     output_names,
                                     scales=scales,
                                     mode=mode),

    scales_name = context.add_const(np.array(scales, dtype=np.float32),
                                    'scales')
    if opset_version in [9, 10]:
        input_names.append(scales_name)
        op = 'Upsample' if opset_version == 9 else 'Resize'
        return onnx_helper.make_node(op, input_names, output_names, mode=mode),

    if opset_version == 11:
        roi_name = context.add_const(np.array([]), 'roi')
        input_names.extend([roi_name, scales_name])
        return onnx_helper.make_node('Resize',
                                     input_names,
                                     output_names,
                                     mode=mode),
Ejemplo n.º 29
0
def convert_Selu(func, opset_version, input_names, output_names, context):
    if opset_version == 1:
        return onnx_helper.make_node(
            'Selu', input_names, output_names,
            consumed_inputs=[1],
            alpha=func.alpha,
            gamma=func.scale
        ),
    elif opset_version == 6:
        return onnx_helper.make_node('Selu', input_names, output_names,
                                     alpha=func.alpha,
                                     gamma=func.scale
                                     ),
Ejemplo n.º 30
0
def convert_ClippedReLU(
        func, opset_version, input_names, output_names, context):
    if opset_version == 1:
        return onnx_helper.make_node(
            'Clip', input_names, output_names,
            min=0.0, max=func.cap,
            consumed_inputs=[1]
        ),
    elif opset_version == 6:
        return onnx_helper.make_node(
            'Clip', input_names, output_names,
            min=0.0, max=func.cap,
        ),