Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tools/accuracy_checker/accuracy_checker/adapters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ AccuracyChecker supports following set of adapters:
* `yolo_v8_detection` - converting output of YOLO v8 family pretrained for object detection to `DetectionPrediction`.
* `conf_threshold` - minimal confidence for filtering valid detections (Optional, default 0.25).
* `multi_label` - allow to use multiple labels for the same box coordinates (Optional, default True).
* `yolo26` - converting output of YOLO26 model to `DetectionPrediction` representation.
* `conf_threshold` - minimal confidence for filtering valid detections (Optional, default 0.25).
* `lpr` - converting output of license plate recognition model to `CharacterRecognitionPrediction` representation.
* `aocr` - converting output of attention-ocr model to `CharacterRecognitionPrediction`.
* `output_blob` - name of output layer with predicted labels or string (Optional, if not provided, first founded output will be used).
Expand Down
4 changes: 3 additions & 1 deletion tools/accuracy_checker/accuracy_checker/adapters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@
YoloxsAdapter,
YolofAdapter,
# for adapter registration, it should be imported and added to __all__ list
YoloV8DetectionAdapter
YoloV8DetectionAdapter,
Yolo26Adapter
)
from .classification import ClassificationAdapter, MaskToBinaryClassification
from .segmentation import (
Expand Down Expand Up @@ -188,6 +189,7 @@
'YoloxsAdapter',
'YolofAdapter',
'YoloV8DetectionAdapter',
'Yolo26Adapter',

'SSDAdapter',
'SSDAdapterMxNet',
Expand Down
35 changes: 35 additions & 0 deletions tools/accuracy_checker/accuracy_checker/adapters/yolo.py
Original file line number Diff line number Diff line change
Expand Up @@ -963,3 +963,38 @@ def process(self, raw, identifiers, frame_meta):
# DetectionPrediction(identifier, label, score, x_mins, y_mins, x_maxs, y_maxs, meta)
result.append(DetectionPrediction(identifier, labels, conf, *box.T, meta))
return result

class Yolo26Adapter(Adapter):
Comment thread
pkowalczint marked this conversation as resolved.
__provider__ = "yolo26"

@classmethod
def parameters(cls):
params = super().parameters()
params.update({"conf_threshold": NumberField(value_type=float, optional=True, min_value=0, default=0.25,
description="Minimal confidence value for valid detections.")})
return params

def configure(self):
self.conf_threshold = self.get_value_from_config("conf_threshold")

def process(self, raw, identifiers, frame_meta):
result = []
raw_outputs = self._extract_predictions(raw, frame_meta)
prediction = raw_outputs[self.output_blob]

# expected output format is box(x1, y1, x2, y2), confidence, class_id for each detected object
if len(prediction.shape) != 3 and prediction.shape[1] != 6:
raise ValueError("Output format should have 3 dimensions where the second dimension is 6, "
"but found shape {}".format(prediction.shape))

for identifier, output, meta in zip(identifiers, prediction, frame_meta):
boxes = output[:, :4]
confidences = output[:, 4]
classes = output[:, 5]

min_conf = confidences.reshape(-1) > self.conf_threshold
boxes = boxes[min_conf]
confidences = confidences[min_conf]
classes = classes[min_conf]
result.append(DetectionPrediction(identifier, classes, confidences, *boxes.T, meta))
return result
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
CLASS_REGEX = r'(?:\w+)'
MODULE_REGEX = r'(?:\w+)(?:(?:.\w+)*)'
DEVICE_REGEX = r'(?P<device>cpu$|cuda)?'
CHECKPOINT_URL_REGEX = r'^https?://.*\.pth(\?.*)?(#.*)?$'
CHECKPOINT_URL_REGEX = r'^https?://.*\.pth?(\?.*)?(#.*)?$'
SCALAR_INPUTS = ('input_ids', 'input_mask', 'segment_ids', 'attention_mask', 'token_type_ids')

class PyTorchLauncher(Launcher):
Expand All @@ -49,6 +49,9 @@ def parameters(cls):
'checkpoint_url': StringField(
optional=True, regex=CHECKPOINT_URL_REGEX, description='Url link to pre-trained model checkpoint.'
),
'checkpoint_weights_only': BoolField(
optional=True, default=True, description='Model checkpoint stored as weights only.'
Comment thread
pkowalczint marked this conversation as resolved.
),
'state_key': StringField(optional=True, regex=r'\w+', description='pre-trained model checkpoint state key'),
'python_path': PathField(
check_exists=True, is_directory=True, optional=True,
Expand Down Expand Up @@ -108,6 +111,7 @@ def __init__(self, config_entry: dict, *args, **kwargs):
checkpoint = config_entry.get('checkpoint')
if checkpoint is None:
checkpoint = config_entry.get('checkpoint_url')
self.checkpoint_weights_only = config_entry.get('checkpoint_weights_only', True)
Comment thread
pkowalczint marked this conversation as resolved.

python_path = config_entry.get("python_path")

Expand Down Expand Up @@ -174,9 +178,24 @@ def load_module(self, model_cls, module_args, module_kwargs, checkpoint=None, st
if isinstance(checkpoint, str) and re.match(CHECKPOINT_URL_REGEX, checkpoint):
checkpoint = urllib.request.urlretrieve(checkpoint)[0] # nosec B310 # disable urllib-urlopen check
checkpoint = self._torch.load(
checkpoint, map_location=None if self.cuda else self._torch.device('cpu')
checkpoint,
map_location=None if self.cuda else self._torch.device('cpu'),
weights_only=self.checkpoint_weights_only
)
state = checkpoint if not state_key else checkpoint[state_key]

if not self.checkpoint_weights_only:

state_dict_contains_model = (
isinstance(state, dict) and
'model' in state and
isinstance(state['model'], self._torch.nn.Module)
)

if state_dict_contains_model:
loaded_model = state['model']
return self.prepare_module(loaded_model, model_cls)

if all(key.startswith('module.') for key in state):
module = self._torch.nn.DataParallel(module)
module.load_state_dict(state, strict=False)
Expand Down Expand Up @@ -262,7 +281,13 @@ def predict(self, inputs, metadata=None, **kwargs):
results = []
with self._torch.no_grad():
for batch_input in inputs:
if metadata[0].get('input_is_dict_type') or (isinstance(batch_input, dict) and 'input' in batch_input):
is_input_as_dict = metadata[0].get('input_is_dict_type') or isinstance(batch_input, dict)
if is_input_as_dict and 'input' in batch_input:
inp = batch_input['input']
model_dtype = next(self.module.parameters()).dtype
if inp.dtype != model_dtype:
batch_input['input'] = inp.to(model_dtype)

outputs = self.module(batch_input['input'])
else:
outputs = self.module(**batch_input)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ For enabling PyTorch launcher you need to add `framework: pytorch` in launchers
* `module`- PyTorch network module for loading.
* `checkpoint` - pre-trained model checkpoint (Optional).
* `checkpoint_url` - url link to pre-trained model checkpoint (Optional).
* `checkpoint_weights_only` - boolean, use weights only model checkpoint (Optional, default `True`).
Comment thread
pkowalczint marked this conversation as resolved.
* `state_key` - pre-trained model checkpoint state key (Optional).
* `python_path` - appendix for PYTHONPATH for making network module visible in current python environment (Optional).
* `module_args` - list of positional arguments for network module (Optional).
Expand Down
Loading