mirror of
https://github.com/THU-MIG/yolov10.git
synced 2025-05-23 21:44:22 +08:00
Remove unused code (#4327)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
1c753cbce6
commit
9366062af2
@ -40,6 +40,9 @@ The FastSAM models are easy to integrate into your Python applications. Ultralyt
|
||||
|
||||
To perform object detection on an image, use the `predict` method as shown below:
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "Python"
|
||||
```python
|
||||
from ultralytics import FastSAM
|
||||
from ultralytics.models.fastsam import FastSAMPrompt
|
||||
@ -83,6 +86,10 @@ This snippet demonstrates the simplicity of loading a pre-trained model and runn
|
||||
|
||||
Validation of the model on a dataset can be done as follows:
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "Python"
|
||||
|
||||
```python
|
||||
from ultralytics import FastSAM
|
||||
|
||||
|
@ -61,6 +61,9 @@ You can download the model [here](https://github.com/ChaoningZhang/MobileSAM/blo
|
||||
|
||||
### Point Prompt
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "Python"
|
||||
```python
|
||||
from ultralytics import SAM
|
||||
|
||||
@ -73,6 +76,9 @@ model.predict('ultralytics/assets/zidane.jpg', points=[900, 370], labels=[1])
|
||||
|
||||
### Box Prompt
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "Python"
|
||||
```python
|
||||
from ultralytics import SAM
|
||||
|
||||
|
@ -152,6 +152,10 @@ This comparison shows the order-of-magnitude differences in the model sizes and
|
||||
|
||||
Tests run on a 2023 Apple M2 Macbook with 16GB of RAM. To reproduce this test:
|
||||
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "Python"
|
||||
```python
|
||||
from ultralytics import FastSAM, SAM, YOLO
|
||||
|
||||
@ -184,6 +188,9 @@ Auto-annotation is a key feature of SAM, allowing users to generate a [segmentat
|
||||
|
||||
To auto-annotate your dataset with the Ultralytics framework, use the `auto_annotate` function as shown below:
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "Python"
|
||||
```python
|
||||
from ultralytics.data.annotator import auto_annotate
|
||||
|
||||
|
@ -33,6 +33,7 @@ Train YOLOv8n on the COCO128 dataset for 100 epochs at image size 640. See Argum
|
||||
# Train the model
|
||||
results = model.train(data='coco128.yaml', epochs=100, imgsz=640)
|
||||
```
|
||||
|
||||
=== "CLI"
|
||||
|
||||
```bash
|
||||
@ -63,6 +64,7 @@ The training device can be specified using the `device` argument. If no argument
|
||||
# Train the model with 2 GPUs
|
||||
results = model.train(data='coco128.yaml', epochs=100, imgsz=640, device=[0, 1])
|
||||
```
|
||||
|
||||
=== "CLI"
|
||||
|
||||
```bash
|
||||
@ -89,6 +91,7 @@ To enable training on Apple M1 and M2 chips, you should specify 'mps' as your de
|
||||
# Train the model with 2 GPUs
|
||||
results = model.train(data='coco128.yaml', epochs=100, imgsz=640, device='mps')
|
||||
```
|
||||
|
||||
=== "CLI"
|
||||
|
||||
```bash
|
||||
@ -121,6 +124,7 @@ Below is an example of how to resume an interrupted training using Python and vi
|
||||
# Resume training
|
||||
results = model.train(resume=True)
|
||||
```
|
||||
|
||||
=== "CLI"
|
||||
|
||||
```bash
|
||||
@ -196,6 +200,9 @@ To use a logger, select it from the dropdown menu in the code snippet above and
|
||||
|
||||
To use Comet:
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "Python"
|
||||
```python
|
||||
# pip install comet_ml
|
||||
import comet_ml
|
||||
@ -211,6 +218,9 @@ Remember to sign in to your Comet account on their website and get your API key.
|
||||
|
||||
To use ClearML:
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "Python"
|
||||
```python
|
||||
# pip install clearml
|
||||
import clearml
|
||||
@ -226,6 +236,9 @@ After running this script, you will need to sign in to your ClearML account on t
|
||||
|
||||
To use TensorBoard in [Google Colab](https://colab.research.google.com/github/ultralytics/ultralytics/blob/main/examples/tutorial.ipynb):
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "CLI"
|
||||
```bash
|
||||
load_ext tensorboard
|
||||
tensorboard --logdir ultralytics/runs # replace with 'runs' directory
|
||||
@ -233,6 +246,9 @@ tensorboard --logdir ultralytics/runs # replace with 'runs' directory
|
||||
|
||||
To use TensorBoard locally run the below command and view results at http://localhost:6006/.
|
||||
|
||||
!!! example ""
|
||||
|
||||
=== "CLI"
|
||||
```bash
|
||||
tensorboard --logdir ultralytics/runs # replace with 'runs' directory
|
||||
```
|
||||
|
@ -9,34 +9,14 @@ keywords: Ultralytics, Mask Data, Transformation, Encoding, RLE encoding, Image
|
||||
|
||||
Full source code for this file is available at [https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/amg.py](https://github.com/ultralytics/ultralytics/blob/main/ultralytics/models/sam/amg.py). Help us fix any issues you see by submitting a [Pull Request](https://docs.ultralytics.com/help/contributing/) 🛠️. Thank you 🙏!
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.MaskData
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.is_box_near_crop_edge
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.box_xyxy_to_xywh
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.batch_iterator
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.mask_to_rle_pytorch
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.rle_to_mask
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.area_from_rle
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.calculate_stability_score
|
||||
<br><br>
|
||||
@ -69,10 +49,6 @@ keywords: Ultralytics, Mask Data, Transformation, Encoding, RLE encoding, Image
|
||||
## ::: ultralytics.models.sam.amg.remove_small_regions
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.coco_encode_rle
|
||||
<br><br>
|
||||
|
||||
---
|
||||
## ::: ultralytics.models.sam.amg.batched_mask_to_box
|
||||
<br><br>
|
||||
|
@ -17,8 +17,6 @@ from ultralytics.utils.ops import segment2box
|
||||
|
||||
from .utils import polygons2masks, polygons2masks_overlap
|
||||
|
||||
POSE_FLIPLR_INDEX = [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]
|
||||
|
||||
|
||||
# TODO: we might need a BaseTransform to make all these augments be compatible with both classification and semantic
|
||||
class BaseTransform:
|
||||
|
@ -30,7 +30,6 @@ class YOLODataset(BaseDataset):
|
||||
(torch.utils.data.Dataset): A PyTorch dataset object that can be used for training an object detection model.
|
||||
"""
|
||||
cache_version = '1.0.2' # dataset labels *.cache version, >= 1.0.0 for YOLOv8
|
||||
rand_interp_methods = [cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_LANCZOS4]
|
||||
|
||||
def __init__(self, *args, data=None, use_segments=False, use_keypoints=False, **kwargs):
|
||||
self.use_segments = use_segments
|
||||
|
@ -28,8 +28,6 @@ HELP_URL = 'See https://docs.ultralytics.com/datasets/detect for dataset formatt
|
||||
IMG_FORMATS = 'bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp', 'pfm' # image suffixes
|
||||
VID_FORMATS = 'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm' # video suffixes
|
||||
PIN_MEMORY = str(os.getenv('PIN_MEMORY', True)).lower() == 'true' # global pin_memory for dataloaders
|
||||
IMAGENET_MEAN = 0.485, 0.456, 0.406 # RGB mean
|
||||
IMAGENET_STD = 0.229, 0.224, 0.225 # RGB standard deviation
|
||||
|
||||
# Get orientation exif tag
|
||||
for orientation in ExifTags.TAGS.keys():
|
||||
|
@ -1,82 +1,13 @@
|
||||
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
||||
|
||||
import math
|
||||
from copy import deepcopy
|
||||
from itertools import product
|
||||
from typing import Any, Dict, Generator, ItemsView, List, Tuple
|
||||
from typing import Any, Generator, List, Tuple
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
|
||||
class MaskData:
|
||||
"""
|
||||
A structure for storing masks and their related data in batched format.
|
||||
Implements basic filtering and concatenation.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs) -> None:
|
||||
"""Initialize a MaskData object, ensuring all values are supported types."""
|
||||
for v in kwargs.values():
|
||||
assert isinstance(
|
||||
v, (list, np.ndarray, torch.Tensor)), 'MaskData only supports list, numpy arrays, and torch tensors.'
|
||||
self._stats = dict(**kwargs)
|
||||
|
||||
def __setitem__(self, key: str, item: Any) -> None:
|
||||
"""Set an item in the MaskData object, ensuring it is a supported type."""
|
||||
assert isinstance(
|
||||
item, (list, np.ndarray, torch.Tensor)), 'MaskData only supports list, numpy arrays, and torch tensors.'
|
||||
self._stats[key] = item
|
||||
|
||||
def __delitem__(self, key: str) -> None:
|
||||
"""Delete an item from the MaskData object."""
|
||||
del self._stats[key]
|
||||
|
||||
def __getitem__(self, key: str) -> Any:
|
||||
"""Get an item from the MaskData object."""
|
||||
return self._stats[key]
|
||||
|
||||
def items(self) -> ItemsView[str, Any]:
|
||||
"""Return an ItemsView of the MaskData object."""
|
||||
return self._stats.items()
|
||||
|
||||
def filter(self, keep: torch.Tensor) -> None:
|
||||
"""Filter the MaskData object based on the given boolean tensor."""
|
||||
for k, v in self._stats.items():
|
||||
if v is None:
|
||||
self._stats[k] = None
|
||||
elif isinstance(v, torch.Tensor):
|
||||
self._stats[k] = v[torch.as_tensor(keep, device=v.device)]
|
||||
elif isinstance(v, np.ndarray):
|
||||
self._stats[k] = v[keep.detach().cpu().numpy()]
|
||||
elif isinstance(v, list) and keep.dtype == torch.bool:
|
||||
self._stats[k] = [a for i, a in enumerate(v) if keep[i]]
|
||||
elif isinstance(v, list):
|
||||
self._stats[k] = [v[i] for i in keep]
|
||||
else:
|
||||
raise TypeError(f'MaskData key {k} has an unsupported type {type(v)}.')
|
||||
|
||||
def cat(self, new_stats: 'MaskData') -> None:
|
||||
"""Concatenate a new MaskData object to the current one."""
|
||||
for k, v in new_stats.items():
|
||||
if k not in self._stats or self._stats[k] is None:
|
||||
self._stats[k] = deepcopy(v)
|
||||
elif isinstance(v, torch.Tensor):
|
||||
self._stats[k] = torch.cat([self._stats[k], v], dim=0)
|
||||
elif isinstance(v, np.ndarray):
|
||||
self._stats[k] = np.concatenate([self._stats[k], v], axis=0)
|
||||
elif isinstance(v, list):
|
||||
self._stats[k] = self._stats[k] + deepcopy(v)
|
||||
else:
|
||||
raise TypeError(f'MaskData key {k} has an unsupported type {type(v)}.')
|
||||
|
||||
def to_numpy(self) -> None:
|
||||
"""Convert all torch tensors in the MaskData object to numpy arrays."""
|
||||
for k, v in self._stats.items():
|
||||
if isinstance(v, torch.Tensor):
|
||||
self._stats[k] = v.detach().cpu().numpy()
|
||||
|
||||
|
||||
def is_box_near_crop_edge(boxes: torch.Tensor,
|
||||
crop_box: List[int],
|
||||
orig_box: List[int],
|
||||
@ -91,14 +22,6 @@ def is_box_near_crop_edge(boxes: torch.Tensor,
|
||||
return torch.any(near_crop_edge, dim=1)
|
||||
|
||||
|
||||
def box_xyxy_to_xywh(box_xyxy: torch.Tensor) -> torch.Tensor:
|
||||
"""Convert bounding boxes from XYXY format to XYWH format."""
|
||||
box_xywh = deepcopy(box_xyxy)
|
||||
box_xywh[2] = box_xywh[2] - box_xywh[0]
|
||||
box_xywh[3] = box_xywh[3] - box_xywh[1]
|
||||
return box_xywh
|
||||
|
||||
|
||||
def batch_iterator(batch_size: int, *args) -> Generator[List[Any], None, None]:
|
||||
"""Yield batches of data from the input arguments."""
|
||||
assert args and all(len(a) == len(args[0]) for a in args), 'Batched iteration must have same-size inputs.'
|
||||
@ -107,50 +30,6 @@ def batch_iterator(batch_size: int, *args) -> Generator[List[Any], None, None]:
|
||||
yield [arg[b * batch_size:(b + 1) * batch_size] for arg in args]
|
||||
|
||||
|
||||
def mask_to_rle_pytorch(tensor: torch.Tensor) -> List[Dict[str, Any]]:
|
||||
"""Encode masks as uncompressed RLEs in the format expected by pycocotools."""
|
||||
# Put in fortran order and flatten h,w
|
||||
b, h, w = tensor.shape
|
||||
tensor = tensor.permute(0, 2, 1).flatten(1)
|
||||
|
||||
# Compute change indices
|
||||
diff = tensor[:, 1:] ^ tensor[:, :-1]
|
||||
change_indices = diff.nonzero()
|
||||
|
||||
# Encode run length
|
||||
out = []
|
||||
for i in range(b):
|
||||
cur_idxs = change_indices[change_indices[:, 0] == i, 1]
|
||||
cur_idxs = torch.cat([
|
||||
torch.tensor([0], dtype=cur_idxs.dtype, device=cur_idxs.device),
|
||||
cur_idxs + 1,
|
||||
torch.tensor([h * w], dtype=cur_idxs.dtype, device=cur_idxs.device), ])
|
||||
btw_idxs = cur_idxs[1:] - cur_idxs[:-1]
|
||||
counts = [] if tensor[i, 0] == 0 else [0]
|
||||
counts.extend(btw_idxs.detach().cpu().tolist())
|
||||
out.append({'size': [h, w], 'counts': counts})
|
||||
return out
|
||||
|
||||
|
||||
def rle_to_mask(rle: Dict[str, Any]) -> np.ndarray:
|
||||
"""Compute a binary mask from an uncompressed RLE."""
|
||||
h, w = rle['size']
|
||||
mask = np.empty(h * w, dtype=bool)
|
||||
idx = 0
|
||||
parity = False
|
||||
for count in rle['counts']:
|
||||
mask[idx:idx + count] = parity
|
||||
idx += count
|
||||
parity ^= True
|
||||
mask = mask.reshape(w, h)
|
||||
return mask.transpose() # Put in C order
|
||||
|
||||
|
||||
def area_from_rle(rle: Dict[str, Any]) -> int:
|
||||
"""Calculate the area of a mask from its uncompressed RLE."""
|
||||
return sum(rle['counts'][1::2])
|
||||
|
||||
|
||||
def calculate_stability_score(masks: torch.Tensor, mask_threshold: float, threshold_offset: float) -> torch.Tensor:
|
||||
"""
|
||||
Computes the stability score for a batch of masks. The stability
|
||||
@ -264,16 +143,6 @@ def remove_small_regions(mask: np.ndarray, area_thresh: float, mode: str) -> Tup
|
||||
return mask, True
|
||||
|
||||
|
||||
def coco_encode_rle(uncompressed_rle: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Encode uncompressed RLE (run-length encoding) to COCO RLE format."""
|
||||
from pycocotools import mask as mask_utils # type: ignore
|
||||
|
||||
h, w = uncompressed_rle['size']
|
||||
rle = mask_utils.frPyObjects(uncompressed_rle, h, w)
|
||||
rle['counts'] = rle['counts'].decode('utf-8') # Necessary to serialize with json
|
||||
return rle
|
||||
|
||||
|
||||
def batched_mask_to_box(masks: torch.Tensor) -> torch.Tensor:
|
||||
"""
|
||||
Calculates boxes in XYXY format around masks. Return [0,0,0,0] for
|
||||
|
@ -26,7 +26,6 @@ from ultralytics import __version__
|
||||
# PyTorch Multi-GPU DDP Constants
|
||||
RANK = int(os.getenv('RANK', -1))
|
||||
LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1)) # https://pytorch.org/docs/stable/elastic/run.html
|
||||
WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1))
|
||||
|
||||
# Other Constants
|
||||
FILE = Path(__file__).resolve()
|
||||
|
@ -22,7 +22,7 @@ class WorkingDirectory(contextlib.ContextDecorator):
|
||||
"""Changes the current directory to the specified directory."""
|
||||
os.chdir(self.dir)
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
def __exit__(self, exc_type, exc_val, exc_tb): # noqa
|
||||
"""Restore the current working directory on context exit."""
|
||||
os.chdir(self.cwd)
|
||||
|
||||
|
@ -39,7 +39,7 @@ class Profile(contextlib.ContextDecorator):
|
||||
self.start = self.time()
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
def __exit__(self, type, value, traceback): # noqa
|
||||
"""
|
||||
Stop timing.
|
||||
"""
|
||||
|
@ -15,7 +15,6 @@ import torch
|
||||
import torch.distributed as dist
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
import torchvision
|
||||
|
||||
from ultralytics.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, RANK, __version__
|
||||
from ultralytics.utils.checks import check_version
|
||||
@ -25,10 +24,7 @@ try:
|
||||
except ImportError:
|
||||
thop = None
|
||||
|
||||
TORCHVISION_0_10 = check_version(torchvision.__version__, '0.10.0')
|
||||
TORCH_1_9 = check_version(torch.__version__, '1.9.0')
|
||||
TORCH_1_11 = check_version(torch.__version__, '1.11.0')
|
||||
TORCH_1_12 = check_version(torch.__version__, '1.12.0')
|
||||
TORCH_2_0 = check_version(torch.__version__, '2.0.0')
|
||||
|
||||
|
||||
@ -457,7 +453,7 @@ def profile(input, ops, n=10, device=None):
|
||||
y = m(x)
|
||||
t[1] = time_sync()
|
||||
try:
|
||||
_ = (sum(yi.sum() for yi in y) if isinstance(y, list) else y).sum().backward()
|
||||
(sum(yi.sum() for yi in y) if isinstance(y, list) else y).sum().backward()
|
||||
t[2] = time_sync()
|
||||
except Exception: # no backward method
|
||||
# print(e) # for debug
|
||||
|
Loading…
x
Reference in New Issue
Block a user