Skip to content

Commit aad63a9

Browse files
Partial annotation
Signed-off-by: Ashwin Vaidya <[email protected]>
1 parent 5000bb6 commit aad63a9

File tree

7 files changed

+102
-81
lines changed

7 files changed

+102
-81
lines changed

model_api/python/model_api/models/anomaly.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
import numpy as np
1616

1717
from model_api.adapters.inference_adapter import InferenceAdapter
18-
19-
from .image_model import ImageModel
20-
from .result_types import AnomalyResult
21-
from .types import ListValue, NumericalValue, StringValue
18+
from model_api.models.image_model import ImageModel
19+
from model_api.models.result_types import AnomalyResult
20+
from model_api.models.types import ListValue, NumericalValue, StringValue
2221

2322

2423
class AnomalyDetection(ImageModel):

model_api/python/model_api/models/classification.py

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,24 @@
99
import json
1010
from collections import defaultdict
1111
from pathlib import Path
12+
from typing import List, Tuple
1213

1314
import numpy as np
15+
from numpy import float32
1416
from openvino.preprocess import PrePostProcessor
1517
from openvino.runtime import Model, Type
1618
from openvino.runtime import opset10 as opset
1719

1820
from model_api.adapters.inference_adapter import InferenceAdapter
19-
20-
from .image_model import ImageModel
21-
from .result_types import ClassificationResult
22-
from .types import BooleanValue, ListValue, NumericalValue, StringValue
21+
from model_api.models.image_model import ImageModel
22+
from model_api.models.result_types import ClassificationResult
23+
from model_api.models.types import BooleanValue, ListValue, NumericalValue, StringValue
2324

2425

2526
class ClassificationModel(ImageModel):
2627
__model__ = "Classification"
2728

28-
def __init__(self, inference_adapter: InferenceAdapter, configuration: dict = {}, preload: bool = False):
29+
def __init__(self, inference_adapter: InferenceAdapter, configuration: dict = {}, preload: bool = False) -> None:
2930
super().__init__(inference_adapter, configuration, preload=False)
3031
self.topk: int
3132
self.labels: list[str]
@@ -102,7 +103,7 @@ def __init__(self, inference_adapter: InferenceAdapter, configuration: dict = {}
102103
if preload:
103104
self.load()
104105

105-
def _load_labels(self, labels_file):
106+
def _load_labels(self, labels_file: str) -> list:
106107
with Path(labels_file).open() as f:
107108
labels = []
108109
for s in f:
@@ -113,7 +114,7 @@ def _load_labels(self, labels_file):
113114
labels.append(s[(begin_idx + 1) : end_idx])
114115
return labels
115116

116-
def _verify_single_output(self):
117+
def _verify_single_output(self) -> None:
117118
layer_name = next(iter(self.outputs))
118119
layer_shape = self.outputs[layer_name].shape
119120

@@ -137,7 +138,7 @@ def _verify_single_output(self):
137138
)
138139

139140
@classmethod
140-
def parameters(cls):
141+
def parameters(cls) -> dict:
141142
parameters = super().parameters()
142143
parameters.update(
143144
{
@@ -180,7 +181,8 @@ def parameters(cls):
180181
)
181182
return parameters
182183

183-
def postprocess(self, outputs, meta):
184+
def postprocess(self, outputs: dict, meta: dict) -> ClassificationResult:
185+
del meta # unused
184186
if self.multilabel:
185187
result = self.get_multilabel_predictions(
186188
outputs[self.out_layer_names[0]].squeeze(),
@@ -220,7 +222,7 @@ def get_saliency_maps(self, outputs: dict) -> np.ndarray:
220222
reordered_saliency_maps[batch].append(saliency_maps[batch][idx])
221223
return np.array(reordered_saliency_maps)
222224

223-
def get_all_probs(self, logits: np.ndarray):
225+
def get_all_probs(self, logits: np.ndarray) -> np.ndarray:
224226
if self.multilabel:
225227
probs = sigmoid_numpy(logits.reshape(-1))
226228
elif self.hierarchical:
@@ -266,10 +268,10 @@ def get_hierarchical_predictions(self, logits: np.ndarray):
266268
predicted_labels.append(label_str)
267269
predicted_scores.append(head_logits[i])
268270

269-
predictions = zip(predicted_labels, predicted_scores)
271+
predictions = list(zip(predicted_labels, predicted_scores))
270272
return self.labels_resolver.resolve_labels(predictions)
271273

272-
def get_multilabel_predictions(self, logits: np.ndarray):
274+
def get_multilabel_predictions(self, logits: np.ndarray) -> List[Tuple[int, str, float32]]:
273275
logits = sigmoid_numpy(logits)
274276
scores = []
275277
indices = []
@@ -281,7 +283,7 @@ def get_multilabel_predictions(self, logits: np.ndarray):
281283

282284
return list(zip(indices, labels, scores))
283285

284-
def get_multiclass_predictions(self, outputs):
286+
def get_multiclass_predictions(self, outputs: dict) -> list[tuple[int, str, float]]:
285287
if self.embedded_topk:
286288
indicesTensor = outputs[self.out_layer_names[0]][0]
287289
scoresTensor = outputs[self.out_layer_names[1]][0]
@@ -293,7 +295,7 @@ def get_multiclass_predictions(self, outputs):
293295
return list(zip(indicesTensor, labels, scoresTensor))
294296

295297

296-
def addOrFindSoftmaxAndTopkOutputs(inference_adapter: InferenceAdapter, topk: int, output_raw_scores: bool):
298+
def addOrFindSoftmaxAndTopkOutputs(inference_adapter: InferenceAdapter, topk: int, output_raw_scores: bool) -> None:
297299
softmaxNode = None
298300
for i in range(len(inference_adapter.model.outputs)):
299301
output_node = inference_adapter.model.get_output_op(i).input(0).get_source_output().get_node()
@@ -345,17 +347,17 @@ def addOrFindSoftmaxAndTopkOutputs(inference_adapter: InferenceAdapter, topk: in
345347
inference_adapter.model = ppp.build()
346348

347349

348-
def sigmoid_numpy(x: np.ndarray):
350+
def sigmoid_numpy(x: np.ndarray) -> np.ndarray:
349351
return 1.0 / (1.0 + np.exp(-x))
350352

351353

352-
def softmax_numpy(x: np.ndarray, eps: float = 1e-9):
354+
def softmax_numpy(x: np.ndarray, eps: float = 1e-9) -> np.ndarray:
353355
x = np.exp(x - np.max(x))
354356
return x / (np.sum(x) + eps)
355357

356358

357359
class GreedyLabelsResolver:
358-
def __init__(self, hierarchical_config) -> None:
360+
def __init__(self, hierarchical_config: dict) -> None:
359361
self.label_to_idx = hierarchical_config["cls_heads_info"]["label_to_idx"]
360362
self.label_relations = hierarchical_config["label_tree_edges"]
361363
self.label_groups = hierarchical_config["cls_heads_info"]["all_groups"]
@@ -364,7 +366,7 @@ def __init__(self, hierarchical_config) -> None:
364366
for child, parent in self.label_relations:
365367
self.label_tree.add_edge(parent, child)
366368

367-
def resolve_labels(self, predictions):
369+
def resolve_labels(self, predictions: list[tuple]) -> list:
368370
"""Resolves hierarchical labels and exclusivity based on a list of ScoredLabels (labels with probability).
369371
The following two steps are taken:
370372
- select the most likely label from each label group
@@ -374,7 +376,7 @@ def resolve_labels(self, predictions):
374376
predictions: a list of tuples (label name, score)
375377
"""
376378

377-
def get_predecessors(lbl, candidates):
379+
def get_predecessors(lbl: str, candidates: list[str]) -> list:
378380
"""Return all predecessors.
379381
380382
Returns all the predecessors of the input label or an empty list if one of the predecessors is not a
@@ -422,12 +424,12 @@ def get_predecessors(lbl, candidates):
422424

423425

424426
class ProbabilisticLabelsResolver(GreedyLabelsResolver):
425-
def __init__(self, hierarchical_config, warmup_cache=True) -> None:
427+
def __init__(self, hierarchical_config: dict, warmup_cache: bool = True) -> None:
426428
super().__init__(hierarchical_config)
427429
if warmup_cache:
428430
self.label_tree.get_labels_in_topological_order()
429431

430-
def resolve_labels(self, predictions):
432+
def resolve_labels(self, predictions: list[tuple[str, float]]) -> list[tuple[int, str, float]]:
431433
"""Resolves hierarchical labels and exclusivity based on a list of ScoredLabels (labels with probability).
432434
433435
The following two steps are taken:
@@ -446,8 +448,8 @@ def resolve_labels(self, predictions):
446448

447449
def __resolve_labels_probabilistic(
448450
self,
449-
label_to_probability,
450-
):
451+
label_to_probability: dict[str, float],
452+
) -> list[tuple[int, str, float]]:
451453
"""Resolves hierarchical labels and exclusivity based on a probabilistic label output.
452454
453455
- selects the most likely (max) label from an exclusive group
@@ -546,24 +548,24 @@ class SimpleLabelsGraph:
546548
like adding edges, getting children and parents.
547549
"""
548550

549-
def __init__(self, vertices):
551+
def __init__(self, vertices: list[str]) -> None:
550552
self._v = vertices
551-
self._adj = defaultdict(list)
552-
self._topological_order_cache = None
553-
self._parents_map = {}
553+
self._adj: dict[str, list] = {v: [] for v in vertices}
554+
self._topological_order_cache: list | None = None
555+
self._parents_map: dict[str, str] = {}
554556

555-
def add_edge(self, parent, child):
557+
def add_edge(self, parent: str, child: str) -> None:
556558
self._adj[parent].append(child)
557559
self._parents_map[child] = parent
558560
self.clear_topological_cache()
559561

560-
def get_children(self, label):
562+
def get_children(self, label: str) -> list:
561563
return self._adj[label]
562564

563-
def get_parent(self, label):
565+
def get_parent(self, label: str) -> str | None:
564566
return self._parents_map.get(label, None)
565567

566-
def get_ancestors(self, label):
568+
def get_ancestors(self, label: str) -> list[str]:
567569
"""Returns all the ancestors of the input label, including self."""
568570
predecessors = [label]
569571
last_parent = self.get_parent(label)
@@ -576,14 +578,14 @@ def get_ancestors(self, label):
576578

577579
return predecessors
578580

579-
def get_labels_in_topological_order(self):
581+
def get_labels_in_topological_order(self) -> list:
580582
if self._topological_order_cache is None:
581583
self._topological_order_cache = self.topological_sort()
582584

583585
return self._topological_order_cache
584586

585-
def topological_sort(self):
586-
in_degree = defaultdict(int)
587+
def topological_sort(self) -> list:
588+
in_degree: dict[str, int] = dict.fromkeys(self._v, 0)
587589

588590
for node_adj in self._adj.values():
589591
for j in node_adj:
@@ -610,7 +612,7 @@ def topological_sort(self):
610612

611613
return ordered
612614

613-
def clear_topological_cache(self):
615+
def clear_topological_cache(self) -> None:
614616
self._topological_order_cache = None
615617

616618

@@ -619,15 +621,15 @@ def clear_topological_cache(self):
619621
_raw_scores_name = "raw_scores"
620622

621623

622-
def _get_non_xai_names(output_names):
624+
def _get_non_xai_names(output_names: list[str]) -> list[str]:
623625
return [
624626
output_name
625627
for output_name in output_names
626628
if _saliency_map_name != output_name and _feature_vector_name != output_name
627629
]
628630

629631

630-
def _append_xai_names(outputs, output_names):
632+
def _append_xai_names(outputs: dict, output_names: list[str]) -> None:
631633
if _saliency_map_name in outputs:
632634
output_names.append(_saliency_map_name)
633635
if _feature_vector_name in outputs:

model_api/python/model_api/models/image_model.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
# SPDX-License-Identifier: Apache-2.0
44
#
55

6-
from model_api.adapters.utils import RESIZE_TYPES, InputTransform
6+
import numpy as np
77

8-
from .model import Model
9-
from .types import BooleanValue, ListValue, NumericalValue, StringValue
8+
from model_api.adapters.utils import RESIZE_TYPES, InputTransform
9+
from model_api.models.model import Model
10+
from model_api.models.types import BooleanValue, ListValue, NumericalValue, StringValue
1011

1112

1213
class ImageModel(Model):
@@ -89,7 +90,7 @@ def __init__(self, inference_adapter, configuration: dict = {}, preload=False):
8990
self.orig_height, self.orig_width = self.h, self.w
9091

9192
@classmethod
92-
def parameters(cls):
93+
def parameters(cls) -> dict:
9394
parameters = super().parameters()
9495
parameters.update(
9596
{
@@ -169,7 +170,7 @@ def _get_inputs(self):
169170
)
170171
return image_blob_names, image_info_blob_names
171172

172-
def preprocess(self, inputs):
173+
def preprocess(self, inputs) -> list[dict]:
173174
"""Data preprocess method
174175
175176
It performs basic preprocessing of a single image:
@@ -194,10 +195,13 @@ def preprocess(self, inputs):
194195
}
195196
- the input metadata, which might be used in `postprocess` method
196197
"""
197-
return {self.image_blob_name: inputs[None]}, {
198-
"original_shape": inputs.shape,
199-
"resized_shape": (self.w, self.h, self.c),
200-
}
198+
return [
199+
{self.image_blob_name: inputs[None]},
200+
{
201+
"original_shape": inputs.shape,
202+
"resized_shape": (self.w, self.h, self.c),
203+
},
204+
]
201205

202206
def _change_layout(self, image):
203207
"""Changes the input image layout to fit the layout of the model input layer.

0 commit comments

Comments
 (0)