Skip to content

Commit b368f55

Browse files
Add support for the quantized RESIZE_BILINEAR operator to relay TFLite frontend
Change-Id: I46008e5b7edc49d32847acd6d166374a8d85058f
1 parent cc79e8f commit b368f55

File tree

2 files changed

+64
-13
lines changed

2 files changed

+64
-13
lines changed

python/tvm/relay/frontend/tflite.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,13 +597,18 @@ def _convert_resize(self, method, op):
597597
input_tensor = input_tensors[0]
598598
in_expr = self.get_expr(input_tensor.tensor_idx)
599599

600+
output_tensors = self.get_output_tensors(op)
601+
assert len(output_tensors) == 1, "output tensors length should be 1"
602+
output_tensor = output_tensors[0]
603+
600604
# size - 1-D int32 Tensor of 2 elements: new_height, new_width
601605
target_size = tuple(self.get_tensor_value(input_tensors[1]))
602606

603607
# Options - align_corners (bool)
604608
resize_options = None
605609
align_corners = False
606-
if method == "bilinear":
610+
bilinear_method = method == "bilinear"
611+
if bilinear_method:
607612
assert op.BuiltinOptionsType() == BuiltinOptions.ResizeBilinearOptions
608613
resize_options = ResizeBilinearOptions()
609614
elif tflite_ver >= 1130:
@@ -617,9 +622,13 @@ def _convert_resize(self, method, op):
617622

618623
# Use layout NHWC
619624
coord_trans = "align_corners" if align_corners else "asymmetric"
625+
if bilinear_method and input_tensor.qnn_params:
626+
in_expr = self.dequantize(in_expr, input_tensor)
620627
out = _op.image.resize(
621628
in_expr, target_size, "NHWC", method, coordinate_transformation_mode=coord_trans
622629
)
630+
if bilinear_method and output_tensor.qnn_params:
631+
out = self.quantize(out, output_tensor)
623632
return out
624633

625634
def convert_resize_bilinear(self, op):

tests/python/frontend/tflite/test_forward.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,32 +1351,74 @@ def test_forward_reshape():
13511351
# ------
13521352

13531353

1354-
def _test_resize(tf_resize_op, data, align_corners):
1354+
def _test_resize(tf_resize_op, images_data, size_data, align_corners, quantized=False):
13551355
""" One iteration of Resize """
1356-
1357-
assert len(data) == 2
1358-
13591356
# Test with tensor and constant
13601357
with tf.Graph().as_default():
1361-
images_tensor = array_ops.placeholder(shape=data[0].shape, dtype=data[0].dtype, name="in")
1362-
size = ops.convert_to_tensor(data[1], dtype=data[1].dtype)
1363-
out_tensor = tf_resize_op(images=images_tensor, size=size, align_corners=align_corners)
1364-
compare_tflite_with_tvm([data[0]], ["in:0"], [images_tensor], [out_tensor])
1358+
images_tensor = array_ops.placeholder(shape=images_data.shape, dtype="float32", name="in")
1359+
size = ops.convert_to_tensor(size_data, dtype=size_data.dtype)
1360+
1361+
if quantized:
1362+
images_tensor_q = tf.quantization.fake_quant_with_min_max_args(
1363+
images_tensor, min=-3, max=2, name="in"
1364+
)
1365+
input_range = {"in": (-3, 2)}
1366+
out_tensor = tf_resize_op(
1367+
images=images_tensor_q, size=size, align_corners=align_corners
1368+
)
1369+
out_tensor = tf.quantization.fake_quant_with_min_max_args(
1370+
out_tensor, min=-3, max=2, name="out_tensor"
1371+
)
1372+
1373+
compare_tflite_with_tvm(
1374+
[images_data],
1375+
["in:0"],
1376+
[images_tensor],
1377+
[out_tensor],
1378+
quantized=True,
1379+
input_range=input_range,
1380+
)
1381+
else:
1382+
out_tensor = tf_resize_op(images=images_tensor, size=size, align_corners=align_corners)
1383+
compare_tflite_with_tvm([images_data], ["in:0"], [images_tensor], [out_tensor])
13651384

13661385

13671386
def test_all_resize():
13681387
""" Resize """
1369-
data = [np.random.rand(1, 16, 16, 3).astype("float32"), np.array([8, 8], dtype=np.int32)]
1388+
images_data = np.random.uniform(0, 255, (1, 16, 16, 3))
1389+
images_data_float32 = images_data.astype(np.float32)
1390+
images_data_uint8 = images_data.astype(np.uint8)
1391+
size_data = np.array([8, 8]).astype("int32")
13701392
### RESIZE_BILINEAR
1371-
_test_resize(tf.image.resize_bilinear, data, align_corners=False)
1372-
_test_resize(tf.image.resize_bilinear, data, align_corners=True)
1393+
_test_resize(
1394+
tf.image.resize_bilinear,
1395+
images_data_float32,
1396+
size_data,
1397+
align_corners=False,
1398+
quantized=False,
1399+
)
1400+
_test_resize(
1401+
tf.image.resize_bilinear,
1402+
images_data_float32,
1403+
size_data,
1404+
align_corners=True,
1405+
quantized=False,
1406+
)
1407+
_test_resize(
1408+
tf.image.resize_bilinear, images_data_uint8, size_data, align_corners=False, quantized=True
1409+
)
1410+
_test_resize(
1411+
tf.image.resize_bilinear, images_data_uint8, size_data, align_corners=True, quantized=True
1412+
)
13731413
### RESIZE_NEAREST_NEIGHBOR (was added in v1.13)
13741414
# According to topi resize.h
13751415
# Align corners not supported for nearest neighbour
13761416
from tflite.BuiltinOperator import BuiltinOperator
13771417

13781418
if "RESIZE_NEAREST_NEIGHBOR" in dir(BuiltinOperator()):
1379-
_test_resize(tf.image.resize_nearest_neighbor, data, align_corners=False)
1419+
_test_resize(
1420+
tf.image.resize_nearest_neighbor, images_data_float32, size_data, align_corners=False
1421+
)
13801422

13811423

13821424
#######################################################################

0 commit comments

Comments
 (0)