Skip to content

Commit

Permalink
Add support for the quantized RESIZE_BILINEAR operator to relay TFLit…
Browse files Browse the repository at this point in the history
…e frontend (apache#7866)

Change-Id: I46008e5b7edc49d32847acd6d166374a8d85058g
  • Loading branch information
NicolaLancellotti authored and mehrdadh committed Apr 22, 2021
1 parent 4fc8218 commit 9d6df4b
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 13 deletions.
11 changes: 10 additions & 1 deletion python/tvm/relay/frontend/tflite.py
Original file line number Diff line number Diff line change
Expand Up @@ -597,13 +597,18 @@ def _convert_resize(self, method, op):
input_tensor = input_tensors[0]
in_expr = self.get_expr(input_tensor.tensor_idx)

output_tensors = self.get_output_tensors(op)
assert len(output_tensors) == 1, "output tensors length should be 1"
output_tensor = output_tensors[0]

# size - 1-D int32 Tensor of 2 elements: new_height, new_width
target_size = tuple(self.get_tensor_value(input_tensors[1]))

# Options - align_corners (bool)
resize_options = None
align_corners = False
if method == "bilinear":
bilinear_method = method == "bilinear"
if bilinear_method:
assert op.BuiltinOptionsType() == BuiltinOptions.ResizeBilinearOptions
resize_options = ResizeBilinearOptions()
elif tflite_ver >= 1130:
Expand All @@ -617,9 +622,13 @@ def _convert_resize(self, method, op):

# Use layout NHWC
coord_trans = "align_corners" if align_corners else "asymmetric"
if bilinear_method and input_tensor.qnn_params:
in_expr = self.dequantize(in_expr, input_tensor)
out = _op.image.resize(
in_expr, target_size, "NHWC", method, coordinate_transformation_mode=coord_trans
)
if bilinear_method and output_tensor.qnn_params:
out = self.quantize(out, output_tensor)
return out

def convert_resize_bilinear(self, op):
Expand Down
66 changes: 54 additions & 12 deletions tests/python/frontend/tflite/test_forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -1516,32 +1516,74 @@ def test_forward_reshape():
# ------


def _test_resize(tf_resize_op, data, align_corners):
def _test_resize(tf_resize_op, images_data, size_data, align_corners, quantized=False):
""" One iteration of Resize """

assert len(data) == 2

# Test with tensor and constant
with tf.Graph().as_default():
images_tensor = array_ops.placeholder(shape=data[0].shape, dtype=data[0].dtype, name="in")
size = ops.convert_to_tensor(data[1], dtype=data[1].dtype)
out_tensor = tf_resize_op(images=images_tensor, size=size, align_corners=align_corners)
compare_tflite_with_tvm([data[0]], ["in:0"], [images_tensor], [out_tensor])
images_tensor = array_ops.placeholder(shape=images_data.shape, dtype="float32", name="in")
size = ops.convert_to_tensor(size_data, dtype=size_data.dtype)

if quantized:
images_tensor_q = tf.quantization.fake_quant_with_min_max_args(
images_tensor, min=-3, max=2, name="in"
)
input_range = {"in": (-3, 2)}
out_tensor = tf_resize_op(
images=images_tensor_q, size=size, align_corners=align_corners
)
out_tensor = tf.quantization.fake_quant_with_min_max_args(
out_tensor, min=-3, max=2, name="out_tensor"
)

compare_tflite_with_tvm(
[images_data],
["in:0"],
[images_tensor],
[out_tensor],
quantized=True,
input_range=input_range,
)
else:
out_tensor = tf_resize_op(images=images_tensor, size=size, align_corners=align_corners)
compare_tflite_with_tvm([images_data], ["in:0"], [images_tensor], [out_tensor])


def test_all_resize():
""" Resize """
data = [np.random.rand(1, 16, 16, 3).astype("float32"), np.array([8, 8], dtype=np.int32)]
images_data = np.random.uniform(0, 255, (1, 16, 16, 3))
images_data_float32 = images_data.astype(np.float32)
images_data_uint8 = images_data.astype(np.uint8)
size_data = np.array([8, 8]).astype("int32")
### RESIZE_BILINEAR
_test_resize(tf.image.resize_bilinear, data, align_corners=False)
_test_resize(tf.image.resize_bilinear, data, align_corners=True)
_test_resize(
tf.image.resize_bilinear,
images_data_float32,
size_data,
align_corners=False,
quantized=False,
)
_test_resize(
tf.image.resize_bilinear,
images_data_float32,
size_data,
align_corners=True,
quantized=False,
)
_test_resize(
tf.image.resize_bilinear, images_data_uint8, size_data, align_corners=False, quantized=True
)
_test_resize(
tf.image.resize_bilinear, images_data_uint8, size_data, align_corners=True, quantized=True
)
### RESIZE_NEAREST_NEIGHBOR (was added in v1.13)
# According to topi resize.h
# Align corners not supported for nearest neighbour
from tflite.BuiltinOperator import BuiltinOperator

if "RESIZE_NEAREST_NEIGHBOR" in dir(BuiltinOperator()):
_test_resize(tf.image.resize_nearest_neighbor, data, align_corners=False)
_test_resize(
tf.image.resize_nearest_neighbor, images_data_float32, size_data, align_corners=False
)


#######################################################################
Expand Down

0 comments on commit 9d6df4b

Please sign in to comment.