Skip to content

Commit

Permalink
[NNVM] Add ONNX upsample converter (#1591)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jokeren authored and tqchen committed Aug 16, 2018
1 parent 11dd933 commit 093dc74
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
19 changes: 19 additions & 0 deletions nnvm/python/nnvm/frontend/onnx.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,24 @@ def _impl(inputs, attr, params):
return _impl


class Upsample(OnnxOpConverter):
""" Operator converter for Upsample (nearest mode).
"""

@classmethod
def _impl_v7(cls, inputs, attr, params):
scales = attr.get('scales')
assert len(scales) == 4 and scales[0] == 1.0 and scales[1] == 1.0 and scales[2] == scales[3]
mode = attr.get('mode')
if mode == b'nearest':
method = "NEAREST_NEIGHBOR"
elif mode == b'linear':
method = "BILINEAR"
else:
raise ValueError("Invalid ONNX upsample mode: {}".format(mode))
return _sym.upsampling(inputs[0], scale=int(scales[-1]), method=method, layout='NCHW')


class Shape(OnnxOpConverter):
""" Operator converter for Shape.
"""
Expand Down Expand Up @@ -540,6 +558,7 @@ def _get_convert_map(opset):
# 'Crop'
# 'Embedding'
# 'Upsample'
'Upsample' : Upsample.get_converter(opset),
'SpatialBN': BatchNorm.get_converter(opset),

# defs/generator
Expand Down
47 changes: 47 additions & 0 deletions nnvm/tests/python/frontend/onnx/test_forward.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import numpy as np
import math
import nnvm
import topi
import topi.testing
import tvm
from tvm.contrib import graph_runtime
from nnvm.testing.config import ctx_list
Expand Down Expand Up @@ -380,6 +382,50 @@ def test_lrn():
verify_lrn((5, 5, 5, 5), 3, 'float32')
verify_lrn((5, 5, 5, 5), 3, 'float32', alpha=0.0002, beta=0.5, bias=2.0)

def _test_upsample_nearest():
scale = 2
in_shape = (1, 1, 3, 3)
out_shape = (1, 1, 3*scale, 3*scale)
y = helper.make_node("Upsample", ['in'], ['out'], mode='nearest', scales=[1.0, 1.0, 2.0, 2.0])

in_array = np.random.uniform(size=in_shape).astype(np.float32)
out_array = topi.testing.upsampling_python(in_array, scale, "NCHW")

graph = helper.make_graph([y],
'upsample_nearest_test',
inputs = [helper.make_tensor_value_info("in", TensorProto.FLOAT, list(in_shape))],
outputs = [helper.make_tensor_value_info("out", TensorProto.FLOAT, list(out_shape))])

model = helper.make_model(graph, producer_name='upsample_nearest_test')

for target, ctx in ctx_list():
tvm_out = get_tvm_output(model, in_array, target, ctx, out_shape, 'float32')
np.testing.assert_allclose(out_array, tvm_out)

def _test_upsample_bilinear():
scale = 2
in_shape = (1, 1, 3, 3)
out_shape = (1, 1, 3*scale, 3*scale)
y = helper.make_node("Upsample", ['in'], ['out'], mode='linear', scales=[1.0, 1.0, 2.0, 2.0])

in_array = np.random.uniform(size=in_shape).astype(np.float32)
out_array = topi.testing.bilinear_resize_python(in_array, (3*scale, 3*scale), "NCHW")

graph = helper.make_graph([y],
'upsample_bilinear_test',
inputs = [helper.make_tensor_value_info("in", TensorProto.FLOAT, list(in_shape))],
outputs = [helper.make_tensor_value_info("out", TensorProto.FLOAT, list(out_shape))])

model = helper.make_model(graph, producer_name='upsample_bilinear_test')

for target, ctx in ctx_list():
tvm_out = get_tvm_output(model, in_array, target, ctx, out_shape, 'float32')
np.testing.assert_allclose(out_array, tvm_out, rtol=1e-5, atol=1e-5)

def test_upsample():
_test_upsample_nearest()
_test_upsample_bilinear()


if __name__ == '__main__':
# verify_super_resolution_example()
Expand All @@ -398,3 +444,4 @@ def test_lrn():
test_matmul()
test_gather()
test_lrn()
test_upsample()

0 comments on commit 093dc74

Please sign in to comment.