diff --git a/models/common.py b/models/common.py index 8bd4bc88be..b8be2b2dd1 100644 --- a/models/common.py +++ b/models/common.py @@ -160,8 +160,7 @@ def __init__(self, c1, c2, shortcut=True, g=1, e=0.5): # ch_in, ch_out, shortcu self.add = shortcut and c1 == c2 def forward(self, x): - """Executes forward pass, performing convolutional ops and optional shortcut addition; expects input tensor x. - """ + """Executes forward pass, performing convolutional ops and optional shortcut addition; expects input tensor x.""" return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x)) @@ -183,8 +182,7 @@ def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, nu self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n))) def forward(self, x): - """Processes input through layers, combining outputs with activation and normalization for feature extraction. - """ + """Processes input through layers, combining outputs with activation and normalization for feature extraction.""" y1 = self.cv3(self.m(self.cv1(x))) y2 = self.cv2(x) return self.cv4(self.act(self.bn(torch.cat((y1, y2), 1)))) @@ -212,8 +210,7 @@ class C3(nn.Module): """Implements a CSP Bottleneck with 3 convolutions, optional shortcuts, group convolutions, and expansion factor.""" def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion - """Initializes CSP Bottleneck with 3 convolutions, optional shortcuts, group convolutions, and expansion factor. - """ + """Initializes CSP Bottleneck with 3 convolutions, optional shortcuts, group convolutions, and expansion factor.""" super().__init__() c_ = int(c2 * e) # hidden channels self.cv1 = Conv(c1, c_, 1, 1) diff --git a/pyproject.toml b/pyproject.toml index 1480a793f0..72d730b31d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ dependencies = [ "scipy>=1.4.1", "setuptools>=70.0.0", "torch>=1.8.0", - "torchvision>=0.9.0", + "torchvision>=0.27.1", "tqdm>=4.66.3", # progress bars "psutil>=5.9.0", # system utilization "thop>=0.1.1", # FLOPs computation diff --git a/requirements.txt b/requirements.txt index a8fe023a23..6ce6d9cdc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ requests>=2.32.2 # HTTP requests, used in model hub/downloads scipy>=1.4.1 # Scientific computing (e.g. IoU, metrics) thop>=0.1.1 # Model profiling - FLOPs and parameter count torch>=1.8.0 # Core PyTorch for training/inference -torchvision>=0.9.0 # Torch utilities for vision (transforms, datasets) +torchvision>=0.27.1 # Torch utilities for vision (transforms, datasets) tqdm>=4.66.3 # Progress bar in CLI ultralytics>=8.4.65 # YOLO framework library (models, training, utils) diff --git a/utils/activations.py b/utils/activations.py index 5ff6eb1f7b..2fd568f30b 100644 --- a/utils/activations.py +++ b/utils/activations.py @@ -110,8 +110,7 @@ def __init__(self, c1, k=1, s=1, r=16): # ch_in, kernel, stride, r # self.bn2 = nn.BatchNorm2d(c1) def forward(self, x): - """Apply the MetaAconC activation, generating beta from the input's spatial average via the bottleneck network. - """ + """Apply the MetaAconC activation, generating beta from the input's spatial average via the bottleneck network.""" y = x.mean(dim=2, keepdims=True).mean(dim=3, keepdims=True) # batch-size 1 bug/instabilities https://github.com/ultralytics/yolov5/issues/2891 # beta = torch.sigmoid(self.bn2(self.fc2(self.bn1(self.fc1(y))))) # bug/unstable diff --git a/utils/augmentations.py b/utils/augmentations.py index b1901fafc3..d561b816ea 100644 --- a/utils/augmentations.py +++ b/utils/augmentations.py @@ -263,8 +263,7 @@ def cutout(im, labels, p=0.5): def mixup(im, labels, im2, labels2): - """Applies MixUp augmentation by blending images and labels; see https://arxiv.org/pdf/1710.09412.pdf for details. - """ + """Applies MixUp augmentation by blending images and labels; see https://arxiv.org/pdf/1710.09412.pdf for details.""" r = np.random.beta(32.0, 32.0) # mixup ratio, alpha=beta=32.0 im = (im * r + im2 * (1 - r)).astype(np.uint8) labels = np.concatenate((labels, labels2), 0) diff --git a/utils/dataloaders.py b/utils/dataloaders.py index 8597617a04..393c61111b 100644 --- a/utils/dataloaders.py +++ b/utils/dataloaders.py @@ -481,8 +481,7 @@ def __len__(self): def img2label_paths(img_paths): - """Converts image paths to corresponding label paths by replacing `/images/` with `/labels/` and `.jpg` with `.txt`. - """ + """Converts image paths to corresponding label paths by replacing `/images/` with `/labels/` and `.jpg` with `.txt`.""" sa, sb = f"{os.sep}images{os.sep}", f"{os.sep}labels{os.sep}" # /images/, /labels/ substrings return [sb.join(x.rsplit(sa, 1)).rsplit(".", 1)[0] + ".txt" for x in img_paths] diff --git a/utils/general.py b/utils/general.py index 44f6c50e55..bba8a73b7d 100644 --- a/utils/general.py +++ b/utils/general.py @@ -197,8 +197,7 @@ class Profile(contextlib.ContextDecorator): """Profiles code execution time, usable as a context manager or decorator for performance monitoring.""" def __init__(self, t=0.0): - """Initializes a profiling context for YOLOv3 with optional timing threshold `t` and checks CUDA availability. - """ + """Initializes a profiling context for YOLOv3 with optional timing threshold `t` and checks CUDA availability.""" self.t = t self.cuda = torch.cuda.is_available() @@ -225,8 +224,7 @@ class Timeout(contextlib.ContextDecorator): """Enforces a timeout on code execution, raising TimeoutError on expiry.""" def __init__(self, seconds, *, timeout_msg="", suppress_timeout_errors=True): - """Initializes a timeout context/decorator with specified duration, custom message, and error handling option. - """ + """Initializes a timeout context/decorator with specified duration, custom message, and error handling option.""" self.seconds = int(seconds) self.timeout_message = timeout_msg self.suppress = bool(suppress_timeout_errors) @@ -311,15 +309,13 @@ def get_default_args(func): def get_latest_run(search_dir="."): - """Returns path to the most recent 'last.pt' file within 'search_dir' for resuming, or an empty string if not found. - """ + """Returns path to the most recent 'last.pt' file within 'search_dir' for resuming, or an empty string if not found.""" last_list = glob.glob(f"{search_dir}/**/last*.pt", recursive=True) return max(last_list, key=os.path.getctime) if last_list else "" def check_online(): - """Checks internet connectivity by attempting to connect to "1.1.1.1" on port 443 twice; returns True if successful. - """ + """Checks internet connectivity by attempting to connect to "1.1.1.1" on port 443 twice; returns True if successful.""" import socket def run_once(): @@ -614,12 +610,10 @@ def url2file(url): def download(url, dir=".", unzip=True, delete=True, curl=False, threads=1, retry=3): - """Downloads files from URLs into a specified directory, optionally unzips, and supports multithreading and retries. - """ + """Downloads files from URLs into a specified directory, optionally unzips, and supports multithreading and retries.""" def download_one(url, dir): - """Downloads a file from a URL into the specified directory, supporting retries and using curl or torch methods. - """ + """Downloads a file from a URL into the specified directory, supporting retries and using curl or torch methods.""" success = True if os.path.isfile(url): f = Path(url) # filename diff --git a/utils/loss.py b/utils/loss.py index 4a406b65a0..d766710e32 100644 --- a/utils/loss.py +++ b/utils/loss.py @@ -83,8 +83,7 @@ def __init__(self, loss_fcn, gamma=1.5, alpha=0.25): self.loss_fcn.reduction = "none" # required to apply FL to each element def forward(self, pred, true): - """Computes focal loss between predictions and true labels using configured loss function, `gamma`, and `alpha`. - """ + """Computes focal loss between predictions and true labels using configured loss function, `gamma`, and `alpha`.""" loss = self.loss_fcn(pred, true) pred_prob = torch.sigmoid(pred) # prob from logits @@ -187,8 +186,7 @@ def __call__(self, p, targets): # predictions, targets return (lbox + lobj + lcls) * bs, torch.cat((lbox, lobj, lcls)).detach() def build_targets(self, p, targets): - """Match `targets` (image, class, x, y, w, h) to anchors per layer, returning tcls, tbox, indices, and anchors. - """ + """Match `targets` (image, class, x, y, w, h) to anchors per layer, returning tcls, tbox, indices, and anchors.""" na, nt = self.na, targets.shape[0] # number of anchors, targets tcls, tbox, indices, anch = [], [], [], [] gain = torch.ones(7, device=self.device) # normalized to gridspace gain diff --git a/utils/torch_utils.py b/utils/torch_utils.py index 267f60b4b7..2dfc383fec 100644 --- a/utils/torch_utils.py +++ b/utils/torch_utils.py @@ -184,8 +184,7 @@ def de_parallel(model): def sparsity(model): - """Calculates and returns the global sparsity of a model as the ratio of zero-valued parameters to total parameters. - """ + """Calculates and returns the global sparsity of a model as the ratio of zero-valued parameters to total parameters.""" a, b = 0, 0 for p in model.parameters(): a += p.numel() diff --git a/utils/triton.py b/utils/triton.py index e71c2d7ade..9001ca7443 100644 --- a/utils/triton.py +++ b/utils/triton.py @@ -71,8 +71,7 @@ def __call__(self, *args, **kwargs) -> torch.Tensor | tuple[torch.Tensor, ...]: return result[0] if len(result) == 1 else result def _create_inputs(self, *args, **kwargs): - """Generates model inputs from args or kwargs, not allowing both; raises error if neither or both are provided. - """ + """Generates model inputs from args or kwargs, not allowing both; raises error if neither or both are provided.""" args_len, kwargs_len = len(args), len(kwargs) if not args_len and not kwargs_len: raise RuntimeError("No inputs provided.")