88import copy
99import json
1010from pathlib import Path
11- from typing import TYPE_CHECKING , List , Tuple
11+ from typing import TYPE_CHECKING
1212
1313import numpy as np
14- from numpy import float32
1514from openvino .preprocess import PrePostProcessor
1615from openvino .runtime import Model , Type
1716from openvino .runtime import opset10 as opset
1817
1918from model_api .models .image_model import ImageModel
20- from model_api .models .result_types import ClassificationResult
19+ from model_api .models .result_types import ClassificationResult , Label
2120from model_api .models .types import BooleanValue , ListValue , NumericalValue , StringValue
2221from model_api .models .utils import softmax
2322
@@ -267,7 +266,7 @@ def get_all_probs(self, logits: np.ndarray) -> np.ndarray:
267266 probs = softmax (logits .reshape (- 1 ))
268267 return probs
269268
270- def get_hierarchical_predictions (self , logits : np .ndarray ):
269+ def get_hierarchical_predictions (self , logits : np .ndarray ) -> list [ Label ] :
271270 predicted_labels = []
272271 predicted_scores = []
273272 cls_heads_info = self .hierarchical_info ["cls_heads_info" ]
@@ -294,7 +293,7 @@ def get_hierarchical_predictions(self, logits: np.ndarray):
294293 predictions = list (zip (predicted_labels , predicted_scores ))
295294 return self .labels_resolver .resolve_labels (predictions )
296295
297- def get_multilabel_predictions (self , logits : np .ndarray ) -> List [ Tuple [ int , str , float32 ] ]:
296+ def get_multilabel_predictions (self , logits : np .ndarray ) -> list [ Label ]:
298297 logits = sigmoid_numpy (logits )
299298 scores = []
300299 indices = []
@@ -304,18 +303,18 @@ def get_multilabel_predictions(self, logits: np.ndarray) -> List[Tuple[int, str,
304303 scores .append (logits [i ])
305304 labels = [self .labels [i ] if self .labels else "" for i in indices ]
306305
307- return list ( zip (indices , labels , scores ))
306+ return [ Label ( * data ) for data in zip (indices , labels , scores )]
308307
309- def get_multiclass_predictions (self , outputs : dict ) -> list [tuple [ int , str , float ] ]:
308+ def get_multiclass_predictions (self , outputs : dict ) -> list [Label ]:
310309 if self .embedded_topk :
311310 indicesTensor = outputs [self .out_layer_names [0 ]][0 ]
312311 scoresTensor = outputs [self .out_layer_names [1 ]][0 ]
313312 labels = [self .labels [i ] if self .labels else "" for i in indicesTensor ]
314313 else :
315314 scoresTensor = softmax (outputs [self .out_layer_names [0 ]][0 ])
316- indicesTensor = [np .argmax (scoresTensor )]
315+ indicesTensor = [int ( np .argmax (scoresTensor ) )]
317316 labels = [self .labels [i ] if self .labels else "" for i in indicesTensor ]
318- return list ( zip (indicesTensor , labels , scoresTensor ))
317+ return [ Label ( * data ) for data in zip (indicesTensor , labels , scoresTensor )]
319318
320319
321320def addOrFindSoftmaxAndTopkOutputs (inference_adapter : InferenceAdapter , topk : int , output_raw_scores : bool ) -> None :
@@ -384,7 +383,7 @@ def __init__(self, hierarchical_config: dict) -> None:
384383 for child , parent in self .label_relations :
385384 self .label_tree .add_edge (parent , child )
386385
387- def resolve_labels (self , predictions : list [tuple ]) -> list :
386+ def resolve_labels (self , predictions : list [tuple ]) -> list [ Label ] :
388387 """Resolves hierarchical labels and exclusivity based on a list of ScoredLabels (labels with probability).
389388 The following two steps are taken:
390389 - select the most likely label from each label group
@@ -438,7 +437,7 @@ def get_predecessors(lbl: str, candidates: list[str]) -> list:
438437 if new_lbl not in output_labels :
439438 output_labels .append (new_lbl )
440439
441- return [(self .label_to_idx [lbl ], lbl , label_to_prob [lbl ]) for lbl in sorted (output_labels )]
440+ return [Label (self .label_to_idx [lbl ], lbl , label_to_prob [lbl ]) for lbl in sorted (output_labels )]
442441
443442
444443class ProbabilisticLabelsResolver (GreedyLabelsResolver ):
@@ -447,7 +446,7 @@ def __init__(self, hierarchical_config: dict, warmup_cache: bool = True) -> None
447446 if warmup_cache :
448447 self .label_tree .get_labels_in_topological_order ()
449448
450- def resolve_labels (self , predictions : list [tuple [str , float ]]) -> list [tuple [ int , str , float ] ]:
449+ def resolve_labels (self , predictions : list [tuple [str , float ]]) -> list [Label ]:
451450 """Resolves hierarchical labels and exclusivity based on a list of ScoredLabels (labels with probability).
452451
453452 The following two steps are taken:
@@ -467,7 +466,7 @@ def resolve_labels(self, predictions: list[tuple[str, float]]) -> list[tuple[int
467466 def __resolve_labels_probabilistic (
468467 self ,
469468 label_to_probability : dict [str , float ],
470- ) -> list [tuple [ int , str , float ] ]:
469+ ) -> list [Label ]:
471470 """Resolves hierarchical labels and exclusivity based on a probabilistic label output.
472471
473472 - selects the most likely (max) label from an exclusive group
@@ -495,7 +494,7 @@ def __resolve_labels_probabilistic(
495494 for lbl , probability in sorted (resolved .items ()):
496495 if probability > 0 : # only return labels with non-zero probability
497496 result .append (
498- (
497+ Label (
499498 self .label_to_idx [lbl ],
500499 lbl ,
501500 # retain the original probability in the output
0 commit comments