[TF FE][GitHub issue] Extend Upsampling2D support for more input types (#21870)

* [TF FE][GitHub issue] Extend Upsampling2D support for more input types

Signed-off-by: Kazantsev, Roman <roman.kazantsev@intel.com>

* Fix output type

Signed-off-by: Kazantsev, Roman <roman.kazantsev@intel.com>

---------

Signed-off-by: Kazantsev, Roman <roman.kazantsev@intel.com>
This commit is contained in:
Roman Kazantsev 2023-12-26 15:59:38 +04:00 committed by GitHub
parent ca8f9afe7f
commit 0c87a19333
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 50 deletions

View File

@ -25,6 +25,7 @@ OutputVector translate_interpolate_op(const NodeContext& node) {
auto size = node.get_input(1);
auto op_name = node.get_name();
auto op_type = node.get_op_type();
auto input_type = images.get_element_type();
// retrieve optional attribute
auto tf_align_corners = node.get_attribute<bool>("align_corners", false);
@ -75,10 +76,21 @@ OutputVector translate_interpolate_op(const NodeContext& node) {
// it always returns FP32 output type so we immediately align input type for it
if (op_type == "ResizeBilinear") {
images = make_shared<v0::Convert>(images, element::f32);
} else if (input_type == element::i16 || input_type == element::u16) {
// OV Interpolate does not support i16 and u16 so it needs to adjust it temporarily
// OV interpolate supports only f32, f16, bf16, i8, u8, i64, i32
images = make_shared<v0::Convert>(images, element::i32);
}
auto interpolate = make_shared<v11::Interpolate>(images, size, axes, interpolate_attrs);
set_node_name(node.get_name(), interpolate);
Output<Node> interpolate = make_shared<v11::Interpolate>(images, size, axes, interpolate_attrs);
// it needs to return original i16 and u16 input_type due to temporal adjustment before
// this is not required for ResizeBilinear case since it always returns f32 by specification
if (op_type != "ResizeBilinear" && (input_type == element::i16 || input_type == element::u16)) {
interpolate = make_shared<v0::Convert>(interpolate, input_type);
}
set_node_name(node.get_name(), interpolate.get_node_shared_ptr());
return {interpolate};
}
} // namespace op

View File

@ -1,20 +1,34 @@
# Copyright (C) 2022 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import numpy as np
import pytest
import tensorflow as tf
from common.tf2_layer_test_class import CommonTF2LayerTest
rng = np.random.default_rng()
class TestKerasUpSampling2D(CommonTF2LayerTest):
def create_keras_upsampling2d_net(self, input_names, input_shapes, input_type, size,
def _prepare_input(self, inputs_info):
assert 'x' in inputs_info, "Test error: inputs_info must contain `x`"
x_shape = inputs_info['x']
inputs_data = {}
if np.issubdtype(self.input_type, np.floating):
inputs_data['x'] = rng.uniform(-2.0, 2.0, x_shape).astype(self.input_type)
elif np.issubdtype(self.input_type, np.signedinteger):
inputs_data['x'] = rng.integers(-8, 8, x_shape).astype(self.input_type)
else:
inputs_data['x'] = rng.integers(0, 8, x_shape).astype(self.input_type)
return inputs_data
def create_keras_upsampling2d_net(self, input_shapes, input_type, size,
data_format, interpolation,
ir_version):
# create TensorFlow 2 model with Keras UpSampling2D operation
self.input_type = input_type
tf.keras.backend.clear_session()
x1 = tf.keras.Input(shape=input_shapes[0][1:], name=input_names[0], dtype=input_type)
x1 = tf.keras.Input(shape=input_shapes[0][1:], name='x', dtype=input_type)
y = tf.keras.layers.UpSampling2D(size=size, data_format=data_format,
interpolation=interpolation)(x1)
tf2_net = tf.keras.Model(inputs=[x1], outputs=[y])
@ -24,55 +38,23 @@ class TestKerasUpSampling2D(CommonTF2LayerTest):
return tf2_net, ref_net
# Tests for nearest interpolation
test_data_nearest = [
dict(input_names=["x1"], input_shapes=[[5, 4, 8, 2]], input_type=tf.float32,
size=(2, 3), data_format='channels_last', interpolation='nearest'),
dict(input_names=["x1"], input_shapes=[[3, 2, 4, 2]], input_type=tf.float32,
size=(3, 1), data_format='channels_last', interpolation='nearest'),
dict(input_names=["x1"], input_shapes=[[1, 3, 8, 6]], input_type=tf.float32,
size=(5, 2), data_format='channels_last', interpolation='nearest'),
dict(input_shapes=[[5, 4, 8, 2]], size=(2, 3)),
dict(input_shapes=[[3, 2, 4, 2]], size=(3, 1)),
dict(input_shapes=[[1, 3, 8, 6]], size=(5, 2)),
]
@pytest.mark.parametrize("params", test_data_nearest)
@pytest.mark.parametrize("data_format", ['channels_last', 'channels_first'])
@pytest.mark.parametrize("interpolation", ['nearest', 'bilinear'])
@pytest.mark.parametrize("input_type", [np.float16, np.float32, np.float64, np.int8, np.uint8,
np.int16, np.uint16, np.int32, np.int64])
@pytest.mark.precommit_tf_fe
@pytest.mark.nightly
@pytest.mark.precommit
def test_keras_upsampling2d_nearest(self, params, ie_device, precision, ir_version, temp_dir,
def test_keras_upsampling2d_nearest(self, params, input_type, data_format, interpolation,
ie_device, precision, ir_version, temp_dir,
use_old_api, use_new_frontend):
self._test(*self.create_keras_upsampling2d_net(**params, ir_version=ir_version),
ie_device, precision, temp_dir=temp_dir, use_old_api=use_old_api, ir_version=ir_version,
use_new_frontend=use_new_frontend, **params)
# Tests for bilinear interpolation
test_data_bilinear = [
pytest.param(dict(input_names=["x1"], input_shapes=[[1, 6, 2, 1]], input_type=tf.float32,
size=(3, 1), data_format='channels_last', interpolation='bilinear'),
marks=pytest.mark.precommit_tf_fe),
dict(input_names=["x1"], input_shapes=[[1, 3, 1, 6]], input_type=tf.float32,
size=(5, 2), data_format='channels_last', interpolation='bilinear'),
]
@pytest.mark.parametrize("params", test_data_bilinear)
@pytest.mark.nightly
def test_keras_upsampling2d_bilinear(self, params, ie_device, precision, ir_version, temp_dir,
use_old_api, use_new_frontend):
self._test(*self.create_keras_upsampling2d_net(**params, ir_version=ir_version),
ie_device, precision, temp_dir=temp_dir, use_old_api=use_old_api, ir_version=ir_version,
use_new_frontend=use_new_frontend, **params)
test_data_channels_first = [
dict(input_names=["x1"], input_shapes=[[5, 4, 5, 3]], input_type=tf.float32,
size=(3, 4), data_format='channels_first', interpolation='nearest'),
dict(input_names=["x1"], input_shapes=[[3, 2, 7, 2]], input_type=tf.float32,
size=(2, 3), data_format='channels_first', interpolation='nearest'),
dict(input_names=["x1"], input_shapes=[[3, 5, 4, 6]], input_type=tf.float32,
size=(5, 2), data_format='channels_first', interpolation='nearest'),
]
@pytest.mark.parametrize("params", test_data_channels_first)
@pytest.mark.nightly
def test_keras_upsampling2d_channels_first(self, params, ie_device, precision, ir_version,
temp_dir, use_old_api, use_new_frontend):
self._test(*self.create_keras_upsampling2d_net(**params, ir_version=ir_version),
self._test(*self.create_keras_upsampling2d_net(**params, input_type=input_type, data_format=data_format,
interpolation=interpolation, ir_version=ir_version),
ie_device, precision, temp_dir=temp_dir, use_old_api=use_old_api, ir_version=ir_version,
use_new_frontend=use_new_frontend, **params)