diff --git a/src/frontends/tensorflow/src/input_model.cpp b/src/frontends/tensorflow/src/input_model.cpp index cd64c466dec1b3..14474eec64125a 100644 --- a/src/frontends/tensorflow/src/input_model.cpp +++ b/src/frontends/tensorflow/src/input_model.cpp @@ -376,11 +376,12 @@ std::vector> InputModel::InputModelTFImpl::topologicall ops_to_do.push(output_operation_place); } - // walk through all NextIteration nodes and put their producers into ops_to_do - // this is needed to avoid missed nodes in the body graph of TF1 While operation for (const auto& op_place : m_op_places) { auto op_decoder = op_place->get_decoder(); + auto op_name = op_decoder->get_op_name(); if (op_decoder->get_op_type() == "NextIteration") { + // walk through all NextIteration nodes and put their producers into ops_to_do + // this is needed to avoid missed nodes in the body graph of TF1 While operation std::string producer_name; std::string producer_output_port_name; size_t producer_output_port_idx; @@ -390,6 +391,15 @@ std::vector> InputModel::InputModelTFImpl::topologicall "NextIteration is not found among operation places " + producer_name); ops_to_do.push(m_op_places_map.at(producer_name)); + } else if (op_decoder->get_op_type() == "LookupTableImport" || + op_decoder->get_op_type() == "LookupTableImportV2") { + // all LookupTableImport nodes must be preserved in a graph for conversion because + // they can be terminating nodes and contain input values for HashTable initialization + FRONT_END_GENERAL_CHECK(m_op_places_map.count(op_name), + "[TensorFlow Frontend] internal error or inconsistent model: LookupTableImport " + "operation is not found among operation places " + + op_name); + ops_to_do.push(m_op_places_map.at(op_name)); } } diff --git a/tests/model_hub_tests/models_hub_common/utils.py b/tests/model_hub_tests/models_hub_common/utils.py index 9c5a02207b5729..d223f3bc984c6e 100644 --- a/tests/model_hub_tests/models_hub_common/utils.py +++ b/tests/model_hub_tests/models_hub_common/utils.py @@ -56,11 +56,26 @@ def get_models_list_not_skipped(model_list_file: str, skip_list_file: str): def compare_two_tensors(ov_res, fw_res, eps): is_ok = True - if not np.allclose(ov_res, fw_res, atol=eps, rtol=eps, equal_nan=True): + if ov_res.dtype.type == str or ov_res.dtype.type == np.str_ or ov_res.dtype.type == np.object_: + ov_res = ov_res.astype('U') + # TF can represent string tensors in different format: array of bytestreams + # so we have to align formats of both string tensors, for example, to unicode + if ov_res.dtype.type != fw_res.dtype.type: + try: + fw_res = fw_res.astype('U') + except: + # ref_array of object type and each element must be utf-8 decoded + utf8_decoded_elems = [elem.decode('UTF-8') for elem in fw_res.flatten()] + fw_res = np.array(utf8_decoded_elems, dtype=str).reshape(fw_res.shape) + is_ok = np.array_equal(ov_res, fw_res) + elif ov_res.dtype == bool: + is_ok = np.array_equal(ov_res, fw_res) + elif not np.allclose(ov_res, fw_res, atol=eps, rtol=eps, equal_nan=True): is_ok = False max_diff = np.abs(ov_res.astype(np.float32) - fw_res.astype(np.float32)).max() print("Max diff is {}".format(max_diff)) - else: + + if is_ok: print("Accuracy validation successful!\n") print("absolute eps: {}, relative eps: {}".format(eps, eps)) return is_ok diff --git a/tests/model_hub_tests/tensorflow/model_lists/precommit_read_model b/tests/model_hub_tests/tensorflow/model_lists/precommit_read_model index 8e24ef1cbd8833..2a40914e660d84 100644 --- a/tests/model_hub_tests/tensorflow/model_lists/precommit_read_model +++ b/tests/model_hub_tests/tensorflow/model_lists/precommit_read_model @@ -4,4 +4,6 @@ mil-nce/s3d,https://www.kaggle.com/models/deepmind/mil-nce/frameworks/tensorFlow yamnet,https://www.kaggle.com/models/google/yamnet/frameworks/tensorFlow2/variations/yamnet/versions/1 universal-sentence-encoder-multilingual,https://www.kaggle.com/models/google/universal-sentence-encoder/frameworks/tensorFlow2/variations/multilingual/versions/2 movenet/singlepose/lightning,https://www.kaggle.com/models/google/movenet/frameworks/tensorFlow2/variations/singlepose-lightning/versions/4 -imagenet/resnet_v2_50/feature_vector,https://www.kaggle.com/models/google/resnet-v2/frameworks/tensorFlow2/variations/50-feature-vector/versions/2 \ No newline at end of file +imagenet/resnet_v2_50/feature_vector,https://www.kaggle.com/models/google/resnet-v2/frameworks/tensorFlow2/variations/50-feature-vector/versions/2 +# LookupTableImportV2 is terminating node and is needed for conversion +openimages_v4/ssd/mobilenet_v2,https://www.kaggle.com/models/google/mobilenet-v2/frameworks/tensorFlow1/variations/openimages-v4-ssd-mobilenet-v2/versions/1 \ No newline at end of file