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),
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),
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),
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 ),
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 ),
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 ),
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),
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),
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),
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, ),
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,
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,
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),
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),
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),
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),
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),
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),
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),
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 ),
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),
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,
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),
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 ),
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),
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] ),
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')
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),
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 ),
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, ),