Skip to content

Commit c40305a

Browse files
authored
switch to the explicit padding if the input shape is available. (#198)
* switch to the explicit padding if the input shape is available. * upgrade the version. * fix for the nchw mode. * output_padding could be None.
1 parent 4b0c0f1 commit c40305a

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
# setup.py intermediates
1111
.eggs
1212
*.egg-info/
13-
dist
13+
dist/
14+
build/
1415

1516
# PyCharm files
1617
.idea

onnxmltools/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
This framework converts any machine learned model into onnx format
1010
which is a common language to describe any machine learned model.
1111
"""
12-
__version__ = "1.3.0"
12+
__version__ = "1.3.1"
1313
__author__ = "Microsoft"
1414
__producer__ = "OnnxMLTools"
1515
__producer_version__ = __version__

onnxmltools/convert/keras/operator_converters/Conv.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,23 @@
1515
from .Dense import _activation_map
1616

1717

18+
def _calc_explicit_padding(input_size, output_shape, output_padding, kernel_shape, stride, dilation, perm):
19+
to_nchw = lambda x, perm: [x[perm[n_]] for n_ in range(len(x))]
20+
input_size = to_nchw(input_size, perm)[2:]
21+
output_shape = to_nchw(output_shape, perm)[2:]
22+
23+
spatial = len(kernel_shape)
24+
total_padding = []
25+
pads = [None] * 2 * spatial
26+
for i in range(spatial):
27+
total_padding[i:] = [stride[i] * (output_shape[i] - 1) +
28+
output_padding[i] + kernel_shape[i] * dilation[i] - input_size[i]]
29+
pads[i] = total_padding[i] // 2
30+
pads[i + spatial] = total_padding[i] - (total_padding[i] // 2)
31+
32+
return pads
33+
34+
1835
def convert_keras_conv_core(scope, operator, container, is_transpose, n_dims, input_perm_axes,
1936
output_perm_axes, weight_perm_axes):
2037
op = operator.raw_operator
@@ -69,22 +86,27 @@ def convert_keras_conv_core(scope, operator, container, is_transpose, n_dims, in
6986
attrs['dilations'] = list(op.dilation_rate)
7087
attrs['strides'] = list(op.strides)
7188
attrs['kernel_shape'] = op.kernel_size
72-
# Fix this...
7389
attrs['group'] = group
7490

7591
if op.padding == 'valid':
7692
attrs['auto_pad'] = 'VALID'
7793
elif op.padding == 'same':
78-
if is_transpose: # bypass onnx engine issue on convtranpose support.
79-
attrs['auto_pad'] = 'SAME_LOWER'
80-
shape = [-1 if i is None else i for i in op.output_shape]
81-
if channels_first:
82-
attrs['output_shape'] = shape
94+
if op.input_shape.count(None) > 1:
95+
if is_transpose:
96+
attrs['auto_pad'] = 'SAME_LOWER' # the controversial def in onnx spec.
8397
else:
84-
attrs['output_shape'] = shape[0:1] + shape[-1:] + shape[1:-1]
85-
98+
attrs['auto_pad'] = 'SAME_UPPER'
8699
else:
87-
attrs['auto_pad'] = 'SAME_LOWER'
100+
output_padding = [0] * len(op.kernel_size)
101+
if hasattr(op, 'output_padding') and op.output_padding is not None:
102+
output_padding = op.output_padding
103+
attrs['pads'] = _calc_explicit_padding(op.output_shape if is_transpose else op.input_shape,
104+
op.input_shape if is_transpose else op.output_shape,
105+
output_padding,
106+
op.kernel_size,
107+
op.strides,
108+
op.dilation_rate,
109+
list(range(len(op.input_shape))) if channels_first else input_perm_axes)
88110
else:
89111
raise RuntimeError("Unsupported padding type '{}'".format(op.padding))
90112

0 commit comments

Comments
 (0)