pull/12842/merge
igeni 2024-08-24 21:41:47 +00:00 committed by GitHub
commit dc8d219c00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 62 additions and 48 deletions

View File

@ -449,6 +449,7 @@ def export_openvino(file, metadata, half, int8, data, prefix=colorstr("OpenVINO:
Quantization transform function. Quantization transform function.
Extracts and preprocess input data from dataloader item for quantization. Extracts and preprocess input data from dataloader item for quantization.
Parameters: Parameters:
data_item: Tuple with data item produced by DataLoader during iteration data_item: Tuple with data item produced by DataLoader during iteration
Returns: Returns:

View File

@ -349,8 +349,13 @@ def train(hyp, opt, device, callbacks):
train_loader.sampler.set_epoch(epoch) train_loader.sampler.set_epoch(epoch)
pbar = enumerate(train_loader) pbar = enumerate(train_loader)
LOGGER.info( LOGGER.info(
("\n" + "%11s" * 8) "\n"
% ("Epoch", "GPU_mem", "box_loss", "seg_loss", "obj_loss", "cls_loss", "Instances", "Size") + "".join(
[
f"{el:>11}"
for el in ["Epoch", "GPU_mem", "box_loss", "seg_loss", "obj_loss", "cls_loss", "Instances", "Size"]
]
)
) )
if RANK in {-1, 0}: if RANK in {-1, 0}:
pbar = tqdm(pbar, total=nb, bar_format=TQDM_BAR_FORMAT) # progress bar pbar = tqdm(pbar, total=nb, bar_format=TQDM_BAR_FORMAT) # progress bar

View File

@ -263,7 +263,11 @@ def run(
if isinstance(names, (list, tuple)): # old format if isinstance(names, (list, tuple)): # old format
names = dict(enumerate(names)) names = dict(enumerate(names))
class_map = coco80_to_coco91_class() if is_coco else list(range(1000)) class_map = coco80_to_coco91_class() if is_coco else list(range(1000))
s = ("%22s" + "%11s" * 10) % ( s = "".join(
[
f"{el:>11}" if idx > 0 else f"{el:>22}"
for idx, el in enumerate(
[
"Class", "Class",
"Images", "Images",
"Instances", "Instances",
@ -275,6 +279,9 @@ def run(
"R", "R",
"mAP50", "mAP50",
"mAP50-95)", "mAP50-95)",
]
)
]
) )
dt = Profile(device=device), Profile(device=device), Profile(device=device) dt = Profile(device=device), Profile(device=device), Profile(device=device)
metrics = Metrics() metrics = Metrics()

View File

@ -380,7 +380,12 @@ def train(hyp, opt, device, callbacks):
if RANK != -1: if RANK != -1:
train_loader.sampler.set_epoch(epoch) train_loader.sampler.set_epoch(epoch)
pbar = enumerate(train_loader) pbar = enumerate(train_loader)
LOGGER.info(("\n" + "%11s" * 7) % ("Epoch", "GPU_mem", "box_loss", "obj_loss", "cls_loss", "Instances", "Size")) LOGGER.info(
"\n"
+ "".join(
[f"{el:>11}" for el in ["Epoch", "GPU_mem", "box_loss", "obj_loss", "cls_loss", "Instances", "Size"]]
)
)
if RANK in {-1, 0}: if RANK in {-1, 0}:
pbar = tqdm(pbar, total=nb, bar_format=TQDM_BAR_FORMAT) # progress bar pbar = tqdm(pbar, total=nb, bar_format=TQDM_BAR_FORMAT) # progress bar
optimizer.zero_grad() optimizer.zero_grad()

View File

@ -156,7 +156,6 @@ def random_perspective(
): ):
# torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(0.1, 0.1), scale=(0.9, 1.1), shear=(-10, 10)) # torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(0.1, 0.1), scale=(0.9, 1.1), shear=(-10, 10))
# targets = [cls, xyxy] # targets = [cls, xyxy]
"""Applies random perspective transformation to an image, modifying the image and corresponding labels.""" """Applies random perspective transformation to an image, modifying the image and corresponding labels."""
height = im.shape[0] + border[0] * 2 # shape(h,w,c) height = im.shape[0] + border[0] * 2 # shape(h,w,c)
width = im.shape[1] + border[1] * 2 width = im.shape[1] + border[1] * 2

View File

@ -64,7 +64,6 @@ class Callbacks:
thread: (boolean) Run callbacks in daemon thread thread: (boolean) Run callbacks in daemon thread
kwargs: Keyword Arguments to receive from YOLOv5 kwargs: Keyword Arguments to receive from YOLOv5
""" """
assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}" assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}"
for logger in self._callbacks[hook]: for logger in self._callbacks[hook]:
if thread: if thread:

View File

@ -1104,7 +1104,8 @@ def extract_boxes(path=DATASETS_DIR / "coco128"):
def autosplit(path=DATASETS_DIR / "coco128/images", weights=(0.9, 0.1, 0.0), annotated_only=False): def autosplit(path=DATASETS_DIR / "coco128/images", weights=(0.9, 0.1, 0.0), annotated_only=False):
"""Autosplit a dataset into train/val/test splits and save path/autosplit_*.txt files """Autosplit a dataset into train/val/test splits and save path/autosplit_*.txt files
Usage: from utils.dataloaders import *; autosplit() Usage: from utils.dataloaders import *; autosplit()
Arguments
Arguments:
path: Path to images directory path: Path to images directory
weights: Train, val, test weights (list, tuple) weights: Train, val, test weights (list, tuple)
annotated_only: Only use images with an annotated txt file annotated_only: Only use images with an annotated txt file
@ -1183,7 +1184,7 @@ class HUBDatasetStats:
""" """
Class for generating HUB dataset JSON and `-hub` dataset directory. Class for generating HUB dataset JSON and `-hub` dataset directory.
Arguments Arguments:
path: Path to data.yaml or data.zip (with data.yaml inside data.zip) path: Path to data.yaml or data.zip (with data.yaml inside data.zip)
autodownload: Attempt to download dataset if not found locally autodownload: Attempt to download dataset if not found locally
@ -1314,7 +1315,7 @@ class ClassificationDataset(torchvision.datasets.ImageFolder):
""" """
YOLOv5 Classification Dataset. YOLOv5 Classification Dataset.
Arguments Arguments:
root: Dataset path root: Dataset path
transform: torchvision transforms, used by default transform: torchvision transforms, used by default
album_transform: Albumentations transforms, used if installed album_transform: Albumentations transforms, used if installed

View File

@ -518,7 +518,6 @@ def check_font(font=FONT, progress=False):
def check_dataset(data, autodownload=True): def check_dataset(data, autodownload=True):
"""Validates and/or auto-downloads a dataset, returning its configuration as a dictionary.""" """Validates and/or auto-downloads a dataset, returning its configuration as a dictionary."""
# Download (optional) # Download (optional)
extract_dir = "" extract_dir = ""
if isinstance(data, (str, Path)) and (is_zipfile(data) or is_tarfile(data)): if isinstance(data, (str, Path)) and (is_zipfile(data) or is_tarfile(data)):
@ -1023,7 +1022,6 @@ def non_max_suppression(
Returns: Returns:
list of detections, on (n,6) tensor per image [xyxy, conf, cls] list of detections, on (n,6) tensor per image [xyxy, conf, cls]
""" """
# Checks # Checks
assert 0 <= conf_thres <= 1, f"Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0" assert 0 <= conf_thres <= 1, f"Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0"
assert 0 <= iou_thres <= 1, f"Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0" assert 0 <= iou_thres <= 1, f"Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0"

View File

@ -350,7 +350,8 @@ class GenericLogger:
""" """
YOLOv5 General purpose logger for non-task specific logging YOLOv5 General purpose logger for non-task specific logging
Usage: from utils.loggers import GenericLogger; logger = GenericLogger(...) Usage: from utils.loggers import GenericLogger; logger = GenericLogger(...)
Arguments
Arguments:
opt: Run arguments opt: Run arguments
console_logger: Console logger console_logger: Console logger
include: loggers to include include: loggers to include

View File

@ -80,7 +80,7 @@ class ClearmlLogger:
- Initialize ClearML Task, this object will capture the experiment - Initialize ClearML Task, this object will capture the experiment
- Upload dataset version to ClearML Data if opt.upload_dataset is True - Upload dataset version to ClearML Data if opt.upload_dataset is True
arguments: Arguments:
opt (namespace) -- Commandline arguments for this run opt (namespace) -- Commandline arguments for this run
hyp (dict) -- Hyperparameters for this run hyp (dict) -- Hyperparameters for this run
@ -133,7 +133,7 @@ class ClearmlLogger:
""" """
Log scalars/metrics to ClearML. Log scalars/metrics to ClearML.
arguments: Arguments:
metrics (dict) Metrics in dict format: {"metrics/mAP": 0.8, ...} metrics (dict) Metrics in dict format: {"metrics/mAP": 0.8, ...}
epoch (int) iteration number for the current set of metrics epoch (int) iteration number for the current set of metrics
""" """
@ -145,7 +145,7 @@ class ClearmlLogger:
""" """
Log model weights to ClearML. Log model weights to ClearML.
arguments: Arguments:
model_path (PosixPath or str) Path to the model weights model_path (PosixPath or str) Path to the model weights
model_name (str) Name of the model visible in ClearML model_name (str) Name of the model visible in ClearML
epoch (int) Iteration / epoch of the model weights epoch (int) Iteration / epoch of the model weights
@ -158,7 +158,7 @@ class ClearmlLogger:
""" """
Log final metrics to a summary table. Log final metrics to a summary table.
arguments: Arguments:
metrics (dict) Metrics in dict format: {"metrics/mAP": 0.8, ...} metrics (dict) Metrics in dict format: {"metrics/mAP": 0.8, ...}
""" """
for k, v in metrics.items(): for k, v in metrics.items():
@ -168,7 +168,7 @@ class ClearmlLogger:
""" """
Log image as plot in the plot section of ClearML. Log image as plot in the plot section of ClearML.
arguments: Arguments:
title (str) Title of the plot title (str) Title of the plot
plot_path (PosixPath or str) Path to the saved image file plot_path (PosixPath or str) Path to the saved image file
""" """
@ -183,7 +183,7 @@ class ClearmlLogger:
""" """
Log files (images) as debug samples in the ClearML task. Log files (images) as debug samples in the ClearML task.
arguments: Arguments:
files (List(PosixPath)) a list of file paths in PosixPath format files (List(PosixPath)) a list of file paths in PosixPath format
title (str) A title that groups together images with the same values title (str) A title that groups together images with the same values
""" """
@ -199,7 +199,7 @@ class ClearmlLogger:
""" """
Draw the bounding boxes on a single image and report the result as a ClearML debug sample. Draw the bounding boxes on a single image and report the result as a ClearML debug sample.
arguments: Arguments:
image_path (PosixPath) the path the original image file image_path (PosixPath) the path the original image file
boxes (list): list of scaled predictions in the format - [xmin, ymin, xmax, ymax, confidence, class] boxes (list): list of scaled predictions in the format - [xmin, ymin, xmax, ymax, confidence, class]
class_names (dict): dict containing mapping of class int to class name class_names (dict): dict containing mapping of class int to class name

View File

@ -49,7 +49,7 @@ class WandbLogger:
- Upload dataset if opt.upload_dataset is True - Upload dataset if opt.upload_dataset is True
- Setup training processes if job_type is 'Training' - Setup training processes if job_type is 'Training'
arguments: Arguments:
opt (namespace) -- Commandline arguments for this run opt (namespace) -- Commandline arguments for this run
run_id (str) -- Run ID of W&B run to be resumed run_id (str) -- Run ID of W&B run to be resumed
job_type (str) -- To set the job_type for this run job_type (str) -- To set the job_type for this run
@ -90,7 +90,7 @@ class WandbLogger:
- Update data_dict, to contain info of previous run if resumed and the paths of dataset artifact if downloaded - Update data_dict, to contain info of previous run if resumed and the paths of dataset artifact if downloaded
- Setup log_dict, initialize bbox_interval - Setup log_dict, initialize bbox_interval
arguments: Arguments:
opt (namespace) -- commandline arguments for this run opt (namespace) -- commandline arguments for this run
""" """
@ -120,7 +120,7 @@ class WandbLogger:
""" """
Log the model checkpoint as W&B artifact. Log the model checkpoint as W&B artifact.
arguments: Arguments:
path (Path) -- Path of directory containing the checkpoints path (Path) -- Path of directory containing the checkpoints
opt (namespace) -- Command line arguments for this run opt (namespace) -- Command line arguments for this run
epoch (int) -- Current epoch number epoch (int) -- Current epoch number
@ -159,7 +159,7 @@ class WandbLogger:
""" """
Save the metrics to the logging dictionary. Save the metrics to the logging dictionary.
arguments: Arguments:
log_dict (Dict) -- metrics/media to be logged in current step log_dict (Dict) -- metrics/media to be logged in current step
""" """
if self.wandb_run: if self.wandb_run:
@ -170,7 +170,7 @@ class WandbLogger:
""" """
Commit the log_dict, model artifacts and Tables to W&B and flush the log_dict. Commit the log_dict, model artifacts and Tables to W&B and flush the log_dict.
arguments: Arguments:
best_result (boolean): Boolean representing if the result of this evaluation is best or not best_result (boolean): Boolean representing if the result of this evaluation is best or not
""" """
if self.wandb_run: if self.wandb_run:
@ -197,7 +197,7 @@ class WandbLogger:
@contextmanager @contextmanager
def all_logging_disabled(highest_level=logging.CRITICAL): def all_logging_disabled(highest_level=logging.CRITICAL):
"""source - https://gist.github.com/simon-weber/7853144 """Source - https://gist.github.com/simon-weber/7853144
A context manager that will prevent any logging messages triggered during the body from being processed. A context manager that will prevent any logging messages triggered during the body from being processed.
:param highest_level: the maximum logging level in use. :param highest_level: the maximum logging level in use.
This would only need to be changed if a custom level greater than CRITICAL is defined. This would only need to be changed if a custom level greater than CRITICAL is defined.

View File

@ -41,7 +41,6 @@ def ap_per_class(tp, conf, pred_cls, target_cls, plot=False, save_dir=".", names
# Returns # Returns
The average precision as computed in py-faster-rcnn. The average precision as computed in py-faster-rcnn.
""" """
# Sort by objectness # Sort by objectness
i = np.argsort(-conf) i = np.argsort(-conf)
tp, conf, pred_cls = tp[i], conf[i], pred_cls[i] tp, conf, pred_cls = tp[i], conf[i], pred_cls[i]
@ -103,7 +102,6 @@ def compute_ap(recall, precision):
# Returns # Returns
Average precision, precision curve, recall curve Average precision, precision curve, recall curve
""" """
# Append sentinel values to beginning and end # Append sentinel values to beginning and end
mrec = np.concatenate(([0.0], recall, [1.0])) mrec = np.concatenate(([0.0], recall, [1.0]))
mpre = np.concatenate(([1.0], precision, [0.0])) mpre = np.concatenate(([1.0], precision, [0.0]))
@ -137,6 +135,7 @@ class ConfusionMatrix:
Return intersection-over-union (Jaccard index) of boxes. Return intersection-over-union (Jaccard index) of boxes.
Both sets of boxes are expected to be in (x1, y1, x2, y2) format. Both sets of boxes are expected to be in (x1, y1, x2, y2) format.
Arguments: Arguments:
detections (Array[N, 6]), x1, y1, x2, y2, conf, class detections (Array[N, 6]), x1, y1, x2, y2, conf, class
labels (Array[M, 5]), class, x1, y1, x2, y2 labels (Array[M, 5]), class, x1, y1, x2, y2
@ -233,7 +232,6 @@ def bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7
Input shapes are box1(1,4) to box2(n,4). Input shapes are box1(1,4) to box2(n,4).
""" """
# Get the coordinates of bounding boxes # Get the coordinates of bounding boxes
if xywh: # transform from xywh to xyxy if xywh: # transform from xywh to xyxy
(x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1) (x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
@ -279,14 +277,15 @@ def box_iou(box1, box2, eps=1e-7):
Return intersection-over-union (Jaccard index) of boxes. Return intersection-over-union (Jaccard index) of boxes.
Both sets of boxes are expected to be in (x1, y1, x2, y2) format. Both sets of boxes are expected to be in (x1, y1, x2, y2) format.
Arguments: Arguments:
box1 (Tensor[N, 4]) box1 (Tensor[N, 4])
box2 (Tensor[M, 4]) box2 (Tensor[M, 4])
Returns: Returns:
iou (Tensor[N, M]): the NxM matrix containing the pairwise iou (Tensor[N, M]): the NxM matrix containing the pairwise
IoU values for every element in boxes1 and boxes2 IoU values for every element in boxes1 and boxes2
""" """
# inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2) # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2)
(a1, a2), (b1, b2) = box1.unsqueeze(1).chunk(2, 2), box2.unsqueeze(0).chunk(2, 2) (a1, a2), (b1, b2) = box1.unsqueeze(1).chunk(2, 2), box2.unsqueeze(0).chunk(2, 2)
inter = (torch.min(a2, b2) - torch.max(a1, b1)).clamp(0).prod(2) inter = (torch.min(a2, b2) - torch.max(a1, b1)).clamp(0).prod(2)
@ -304,7 +303,6 @@ def bbox_ioa(box1, box2, eps=1e-7):
box2: np.array of shape(nx4) box2: np.array of shape(nx4)
returns: np.array of shape(n) returns: np.array of shape(n)
""" """
# Get the coordinates of bounding boxes # Get the coordinates of bounding boxes
b1_x1, b1_y1, b1_x2, b1_y2 = box1 b1_x1, b1_y1, b1_x2, b1_y2 = box1
b2_x1, b2_y1, b2_x2, b2_y2 = box2.T b2_x1, b2_y1, b2_x2, b2_y2 = box2.T

View File

@ -29,7 +29,6 @@ def random_perspective(
): ):
# torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(.1, .1), scale=(.9, 1.1), shear=(-10, 10)) # torchvision.transforms.RandomAffine(degrees=(-10, 10), translate=(.1, .1), scale=(.9, 1.1), shear=(-10, 10))
# targets = [cls, xyxy] # targets = [cls, xyxy]
"""Applies random perspective, rotation, scale, shear, and translation augmentations to an image and targets.""" """Applies random perspective, rotation, scale, shear, and translation augmentations to an image and targets."""
height = im.shape[0] + border[0] * 2 # shape(h,w,c) height = im.shape[0] + border[0] * 2 # shape(h,w,c)
width = im.shape[1] + border[1] * 2 width = im.shape[1] + border[1] * 2

View File

@ -14,7 +14,6 @@ def crop_mask(masks, boxes):
- masks should be a size [n, h, w] tensor of masks - masks should be a size [n, h, w] tensor of masks
- boxes should be a size [n, 4] tensor of bbox coords in relative point form - boxes should be a size [n, 4] tensor of bbox coords in relative point form
""" """
n, h, w = masks.shape n, h, w = masks.shape
x1, y1, x2, y2 = torch.chunk(boxes[:, :, None], 4, 1) # x1 shape(1,1,n) x1, y1, x2, y2 = torch.chunk(boxes[:, :, None], 4, 1) # x1 shape(1,1,n)
r = torch.arange(w, device=masks.device, dtype=x1.dtype)[None, None, :] # rows shape(1,w,1) r = torch.arange(w, device=masks.device, dtype=x1.dtype)[None, None, :] # rows shape(1,w,1)
@ -33,7 +32,6 @@ def process_mask_upsample(protos, masks_in, bboxes, shape):
return: h, w, n return: h, w, n
""" """
c, mh, mw = protos.shape # CHW c, mh, mw = protos.shape # CHW
masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw)
masks = F.interpolate(masks[None], shape, mode="bilinear", align_corners=False)[0] # CHW masks = F.interpolate(masks[None], shape, mode="bilinear", align_corners=False)[0] # CHW
@ -51,7 +49,6 @@ def process_mask(protos, masks_in, bboxes, shape, upsample=False):
return: h, w, n return: h, w, n
""" """
c, mh, mw = protos.shape # CHW c, mh, mw = protos.shape # CHW
ih, iw = shape ih, iw = shape
masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) # CHW masks = (masks_in @ protos.float().view(c, -1)).sigmoid().view(-1, mh, mw) # CHW

View File

@ -17,10 +17,9 @@ class TritonRemoteModel:
def __init__(self, url: str): def __init__(self, url: str):
""" """
Keyword arguments: Keyword Arguments:
url: Fully qualified address of the Triton server - for e.g. grpc://localhost:8000 url: Fully qualified address of the Triton server - for e.g. grpc://localhost:8000
""" """
parsed_url = urlparse(url) parsed_url = urlparse(url)
if parsed_url.scheme == "grpc": if parsed_url.scheme == "grpc":
from tritonclient.grpc import InferenceServerClient, InferInput from tritonclient.grpc import InferenceServerClient, InferInput

7
val.py
View File

@ -319,7 +319,12 @@ def run(
if isinstance(names, (list, tuple)): # old format if isinstance(names, (list, tuple)): # old format
names = dict(enumerate(names)) names = dict(enumerate(names))
class_map = coco80_to_coco91_class() if is_coco else list(range(1000)) class_map = coco80_to_coco91_class() if is_coco else list(range(1000))
s = ("%22s" + "%11s" * 6) % ("Class", "Images", "Instances", "P", "R", "mAP50", "mAP50-95") s = "".join(
[
f"{el:>11}" if idx > 0 else f"{el:>22}"
for idx, el in enumerate(["Class", "Images", "Instances", "P", "R", "mAP50", "mAP50-95"])
]
)
tp, fp, p, r, f1, mp, mr, map50, ap50, map = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 tp, fp, p, r, f1, mp, mr, map50, ap50, map = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
dt = Profile(device=device), Profile(device=device), Profile(device=device) # profiling times dt = Profile(device=device), Profile(device=device), Profile(device=device) # profiling times
loss = torch.zeros(3, device=device) loss = torch.zeros(3, device=device)