Refactor code for speed and clarity
This commit is contained in:
Glenn Jocher authored and GitHub committed 2024-06-30 12:34:04 +02:00
1 parent 05e59bdec1
commit b9019671f4
13 files changed
+29 -5

No files matched your search

+1
View File
@@ -34,6 +34,7 @@ def threaded(func):
"""Decorator @threaded to run a function in a separate thread, returning the thread instance."""
def wrapper(*args, **kwargs):
"""Runs the decorated function in a separate daemon thread and returns the thread instance."""
thread = threading.Thread(target=func, args=args, kwargs=kwargs, daemon=True)
thread.start()
return thread
+4
View File
@@ -33,6 +33,7 @@ def check_anchors(dataset, model, thr=4.0, imgsz=640):
wh = torch.tensor(np.concatenate([l[:, 3:5] * s for s, l in zip(shapes * scale, dataset.labels)])).float() # wh
def metric(k): # compute metric
"""Computes ratio metric, anchors above threshold, and best possible recall for YOLOv5 anchor evaluation."""
r = wh[:, None] / k[None]
x = torch.min(r, 1 / r).min(2)[0] # ratio metric
best = x.max(1)[0] # best_x
@@ -86,16 +87,19 @@ def kmean_anchors(dataset="./data/coco128.yaml", n=9, img_size=640, thr=4.0, gen
thr = 1 / thr
def metric(k, wh): # compute metrics
"""Computes ratio metric, anchors above threshold, and best possible recall for YOLOv5 anchor evaluation."""
r = wh[:, None] / k[None]
x = torch.min(r, 1 / r).min(2)[0] # ratio metric
# x = wh_iou(wh, torch.tensor(k)) # iou metric
return x, x.max(1)[0] # x, best_x
def anchor_fitness(k): # mutation fitness
"""Evaluates fitness of YOLOv5 anchors by computing recall and ratio metrics for an anchor evolution process."""
_, best = metric(torch.tensor(k, dtype=torch.float32), wh)
return (best * (best > thr).float()).mean() # fitness
def print_results(k, verbose=True):
"""Sorts and logs kmeans-evolved anchor metrics and best possible recall values for YOLOv5 anchor evaluation."""
k = k[np.argsort(k.prod(1))] # sort small to large
x, best = metric(k, wh0)
bpr, aat = (best > thr).float().mean(), (x > thr).float().mean() * n # best possible recall, anch > thr
+1 -1
View File
@@ -92,7 +92,7 @@ def attempt_download(file, repo="ultralytics/yolov5", release="v7.0"):
from utils.general import LOGGER
def github_assets(repository, version="latest"):
# Return GitHub repo tag (i.e. 'v7.0') and assets (i.e. ['yolov5s.pt', 'yolov5m.pt', ...])
"""Fetches GitHub repository release tag and asset names using the GitHub API."""
if version != "latest":
version = f"tags/{version}" # i.e. tags/v7.0
response = requests.get(f"https://api.github.com/repos/{repository}/releases/{version}").json() # github api
+3 -3
View File
@@ -343,7 +343,7 @@ def check_online():
import socket
def run_once():
# Check once
"""Checks internet connectivity by attempting to create a connection to "1.1.1.1" on port 443."""
try:
socket.create_connection(("1.1.1.1", 443), 5) # check host accessibility
return True
@@ -587,7 +587,7 @@ def check_amp(model):
from models.common import AutoShape, DetectMultiBackend
def amp_allclose(model, im):
# All close FP32 vs AMP results
"""Compares FP32 and AMP model inference outputs, ensuring they are close within a 10% absolute tolerance."""
m = AutoShape(model, verbose=False) # model
a = m(im).xywhn[0] # FP32 inference
m.amp = True
@@ -652,7 +652,7 @@ def download(url, dir=".", unzip=True, delete=True, curl=False, threads=1, retry
"""Downloads and optionally unzips files concurrently, supporting retries and curl fallback."""
def download_one(url, dir):
# Download 1 file
"""Downloads a single file from `url` to `dir`, with retry support and optional curl fallback."""
success = True
if os.path.isfile(url):
f = Path(url) # filename
+3
View File
@@ -67,6 +67,9 @@ class CometLogger:
"""Log metrics, parameters, source code, models and much more with Comet."""
def __init__(self, opt, hyp, run_id=None, job_type="Training", **experiment_kwargs) -> None:
"""Initializes CometLogger with given options, hyperparameters, run ID, job type, and additional experiment
arguments.
"""
self.job_type = job_type
self.opt = opt
self.hyp = hyp
+3
View File
@@ -124,6 +124,9 @@ def butter_lowpass_filtfilt(data, cutoff=1500, fs=50000, order=5):
# https://stackoverflow.com/questions/28536191/how-to-filter-smooth-with-scipy-numpy
def butter_lowpass(cutoff, fs, order):
"""Applies a low-pass Butterworth filter to a signal with specified cutoff frequency, sample rate, and filter
order.
"""
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
return butter(order, normal_cutoff, btype="low", analog=False)
+6
View File
@@ -55,6 +55,9 @@ def ap_per_class_box_and_mask(
class Metric:
def __init__(self) -> None:
"""Initializes performance metric attributes for precision, recall, F1 score, average precision, and class
indices.
"""
self.p = [] # (nc, )
self.r = [] # (nc, )
self.f1 = [] # (nc, )
@@ -151,6 +154,9 @@ class Metrics:
"""Metric for boxes and masks."""
def __init__(self) -> None:
"""Initializes Metric objects for bounding boxes and masks to compute performance metrics in the Metrics
class.
"""
self.metric_box = Metric()
self.metric_mask = Metric()
+1
View File
@@ -37,6 +37,7 @@ def smart_inference_mode(torch_1_9=check_version(torch.__version__, "1.9.0")):
"""Applies torch.inference_mode() if torch>=1.9.0, else torch.no_grad() as a decorator for functions."""
def decorate(fn):
"""Applies torch.inference_mode() if torch>=1.9.0, else torch.no_grad() to the decorated function."""
return (torch.inference_mode if torch_1_9 else torch.no_grad)()(fn)
return decorate