diff --git a/python/tvm/relay/frontend/tflite.py b/python/tvm/relay/frontend/tflite.py index b90802c8dda1..6b14a6f58e60 100644 --- a/python/tvm/relay/frontend/tflite.py +++ b/python/tvm/relay/frontend/tflite.py @@ -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: @@ -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): diff --git a/tests/python/frontend/tflite/test_forward.py b/tests/python/frontend/tflite/test_forward.py index 110d6d1f21fa..43ffc400491a 100644 --- a/tests/python/frontend/tflite/test_forward.py +++ b/tests/python/frontend/tflite/test_forward.py @@ -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 + ) #######################################################################