Skip to content

Commit 935a7ad

Browse files
Add support for the quantized RESIZE_BILINEAR operator to relay TFLite frontend (#7866)
Change-Id: I46008e5b7edc49d32847acd6d166374a8d85058g
1 parent 8bd857d commit 935a7ad

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
@@ -1516,32 +1516,74 @@ def test_forward_reshape():
15161516
# ------
15171517

15181518

1519-
def _test_resize(tf_resize_op, data, align_corners):
1519+
def _test_resize(tf_resize_op, images_data, size_data, align_corners, quantized=False):
15201520
""" One iteration of Resize """
1521-
1522-
assert len(data) == 2
1523-
15241521
# Test with tensor and constant
15251522
with tf.Graph().as_default():
1526-
images_tensor = array_ops.placeholder(shape=data[0].shape, dtype=data[0].dtype, name="in")
1527-
size = ops.convert_to_tensor(data[1], dtype=data[1].dtype)
1528-
out_tensor = tf_resize_op(images=images_tensor, size=size, align_corners=align_corners)
1529-
compare_tflite_with_tvm([data[0]], ["in:0"], [images_tensor], [out_tensor])
1523+
images_tensor = array_ops.placeholder(shape=images_data.shape, dtype="float32", name="in")
1524+
size = ops.convert_to_tensor(size_data, dtype=size_data.dtype)
1525+
1526+
if quantized:
1527+
images_tensor_q = tf.quantization.fake_quant_with_min_max_args(
1528+
images_tensor, min=-3, max=2, name="in"
1529+
)
1530+
input_range = {"in": (-3, 2)}
1531+
out_tensor = tf_resize_op(
1532+
images=images_tensor_q, size=size, align_corners=align_corners
1533+
)
1534+
out_tensor = tf.quantization.fake_quant_with_min_max_args(
1535+
out_tensor, min=-3, max=2, name="out_tensor"
1536+
)
1537+
1538+
compare_tflite_with_tvm(
1539+
[images_data],
1540+
["in:0"],
1541+
[images_tensor],
1542+
[out_tensor],
1543+
quantized=True,
1544+
input_range=input_range,
1545+
)
1546+
else:
1547+
out_tensor = tf_resize_op(images=images_tensor, size=size, align_corners=align_corners)
1548+
compare_tflite_with_tvm([images_data], ["in:0"], [images_tensor], [out_tensor])
15301549

15311550

15321551
def test_all_resize():
15331552
""" Resize """
1534-
data = [np.random.rand(1, 16, 16, 3).astype("float32"), np.array([8, 8], dtype=np.int32)]
1553+
images_data = np.random.uniform(0, 255, (1, 16, 16, 3))
1554+
images_data_float32 = images_data.astype(np.float32)
1555+
images_data_uint8 = images_data.astype(np.uint8)
1556+
size_data = np.array([8, 8]).astype("int32")
15351557
### RESIZE_BILINEAR
1536-
_test_resize(tf.image.resize_bilinear, data, align_corners=False)
1537-
_test_resize(tf.image.resize_bilinear, data, align_corners=True)
1558+
_test_resize(
1559+
tf.image.resize_bilinear,
1560+
images_data_float32,
1561+
size_data,
1562+
align_corners=False,
1563+
quantized=False,
1564+
)
1565+
_test_resize(
1566+
tf.image.resize_bilinear,
1567+
images_data_float32,
1568+
size_data,
1569+
align_corners=True,
1570+
quantized=False,
1571+
)
1572+
_test_resize(
1573+
tf.image.resize_bilinear, images_data_uint8, size_data, align_corners=False, quantized=True
1574+
)
1575+
_test_resize(
1576+
tf.image.resize_bilinear, images_data_uint8, size_data, align_corners=True, quantized=True
1577+
)
15381578
### RESIZE_NEAREST_NEIGHBOR (was added in v1.13)
15391579
# According to topi resize.h
15401580
# Align corners not supported for nearest neighbour
15411581
from tflite.BuiltinOperator import BuiltinOperator
15421582

15431583
if "RESIZE_NEAREST_NEIGHBOR" in dir(BuiltinOperator()):
1544-
_test_resize(tf.image.resize_nearest_neighbor, data, align_corners=False)
1584+
_test_resize(
1585+
tf.image.resize_nearest_neighbor, images_data_float32, size_data, align_corners=False
1586+
)
15451587

15461588

15471589
#######################################################################

0 commit comments

Comments
 (0)