Skip to content

Commit

Permalink
ultralytics 8.0.47 Docker and reformat updates (ultralytics#1153)
Browse files Browse the repository at this point in the history
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
glenn-jocher and pre-commit-ci[bot] authored Feb 26, 2023
1 parent d4be4cb commit a58f766
Show file tree
Hide file tree
Showing 41 changed files with 224 additions and 201 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
if [ "${{ matrix.os }}" == "macos-latest" ]; then
pip install -e . coremltools openvino-dev tensorflow-macos --extra-index-url https://download.pytorch.org/whl/cpu
else
pip install -e . coremltools openvino-dev tensorflow-cpu paddlepaddle x2paddle --extra-index-url https://download.pytorch.org/whl/cpu
pip install -e . coremltools openvino-dev tensorflow-cpu --extra-index-url https://download.pytorch.org/whl/cpu
fi
yolo export format=tflite
- name: Check environment
Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
shell: python
run: |
from ultralytics.yolo.utils.benchmarks import benchmark
benchmark(model='${{ matrix.model }}-cls.pt', imgsz=160, half=False, hard_fail=0.70)
benchmark(model='${{ matrix.model }}-cls.pt', imgsz=160, half=False, hard_fail=0.60)
- name: Benchmark Summary
run: cat benchmarks.log

Expand Down
9 changes: 5 additions & 4 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,11 @@ Ultralytics [发布页](https://github.com/ultralytics/ultralytics/releases) 自

## <div align="center">License</div>

- YOLOv8 在两种不同的 License 下可用:
- **GPL-3.0 License**: 查看 [License](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) 文件的详细信息。
- **企业License**:在没有 GPL-3.0 开源要求的情况下为商业产品开发提供更大的灵活性。典型用例是将 Ultralytics 软件和 AI
模型嵌入到商业产品和应用程序中。在以下位置申请企业许可证 [Ultralytics 许可](https://ultralytics.com/license)
YOLOv8 在两种不同的 License 下可用:

- **GPL-3.0 License**: 查看 [License](https://github.com/ultralytics/ultralytics/blob/main/LICENSE) 文件的详细信息。
- **企业License**:在没有 GPL-3.0 开源要求的情况下为商业产品开发提供更大的灵活性。典型用例是将 Ultralytics 软件和 AI
模型嵌入到商业产品和应用程序中。在以下位置申请企业许可证 [Ultralytics 许可](https://ultralytics.com/license)

## <div align="center">联系我们</div>

Expand Down
3 changes: 1 addition & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ WORKDIR /usr/src/ultralytics
RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics

# Install pip packages
COPY requirements.txt .
RUN python3 -m pip install --upgrade pip wheel
RUN pip install --no-cache ultralytics[export] albumentations comet gsutil notebook
RUN pip install --no-cache '.[export]' albumentations comet gsutil notebook

# Set environment variables
ENV OMP_NUM_THREADS=1
Expand Down
3 changes: 1 addition & 2 deletions docker/Dockerfile-arm64
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ WORKDIR /usr/src/ultralytics
RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics

# Install pip packages
COPY requirements.txt .
RUN python3 -m pip install --upgrade pip wheel
RUN pip install --no-cache ultralytics albumentations gsutil notebook
RUN pip install --no-cache . albumentations gsutil notebook

# Cleanup
ENV DEBIAN_FRONTEND teletype
Expand Down
3 changes: 1 addition & 2 deletions docker/Dockerfile-cpu
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ WORKDIR /usr/src/ultralytics
RUN git clone https://github.com/ultralytics/ultralytics /usr/src/ultralytics

# Install pip packages
COPY requirements.txt .
RUN python3 -m pip install --upgrade pip wheel
RUN pip install --no-cache ultralytics[export] albumentations gsutil notebook \
RUN pip install --no-cache '.[export]' albumentations gsutil notebook \
--extra-index-url https://download.pytorch.org/whl/cpu

# Cleanup
Expand Down
4 changes: 2 additions & 2 deletions docs/predict.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ Class reference documentation for `Results` module and its components can be fou

## Plotting results

You can use `plot()` function of `Result` object to plot results on in image object. It plots all components(boxes, masks,
classification logits, etc) found in the results object
You can use `plot()` function of `Result` object to plot results on in image object. It plots all components(boxes,
masks, classification logits, etc) found in the results object

```python
res = model(img)
Expand Down
17 changes: 13 additions & 4 deletions docs/tasks/tracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ Use a trained YOLOv8n/YOLOv8n-seg model to run tracker on video streams.

```

As in the above usage, we support both the detection and segmentation models for tracking and the only thing you need to do is loading the corresponding(detection or segmentation) model.
As in the above usage, we support both the detection and segmentation models for tracking and the only thing you need to
do is loading the corresponding (detection or segmentation) model.

## Configuration

### Tracking
Tracking shares the configuration with predict, i.e `conf`, `iou`, `show`. More configurations please refer to [predict page](https://docs.ultralytics.com/cfg/#prediction).

Tracking shares the configuration with predict, i.e `conf`, `iou`, `show`. More configurations please refer
to [predict page](https://docs.ultralytics.com/cfg/#prediction).
!!! example ""

=== "Python"
Expand All @@ -65,7 +69,10 @@ Tracking shares the configuration with predict, i.e `conf`, `iou`, `show`. More
```

### Tracker
We also support using a modified tracker config file, just copy a config file i.e `custom_tracker.yaml` from [ultralytics/tracker/cfg](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/tracker/cfg) and modify any configurations(expect the `tracker_type`) you need to.

We also support using a modified tracker config file, just copy a config file i.e `custom_tracker.yaml`
from [ultralytics/tracker/cfg](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/tracker/cfg) and modify
any configurations(expect the `tracker_type`) you need to.
!!! example ""

=== "Python"
Expand All @@ -82,5 +89,7 @@ We also support using a modified tracker config file, just copy a config file i.
yolo track model=yolov8n.pt source="https://youtu.be/Zgi9g1ksQHc" tracker='custom_tracker.yaml'

```
Please refer to [ultralytics/tracker/cfg](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/tracker/cfg) page.

Please refer to [ultralytics/tracker/cfg](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/tracker/cfg)
page.

1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ seaborn>=0.11.0
# Extras --------------------------------------
psutil # system utilization
thop>=0.1.1 # FLOPs computation
wheel>=0.38.0 # Snyk vulnerability fix
# ipython # interactive notebook
# albumentations>=1.0.3
# pycocotools>=2.0.6 # COCO mAP
Expand Down
12 changes: 7 additions & 5 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@ verbose = 2
# https://pep8.readthedocs.io/en/latest/intro.html#error-codes
format = pylint
# see: https://www.flake8rules.com/
ignore = E731,F405,E402,F401,W504,E127,E231,E501,F403
ignore = E731,F405,E402,W504,E501
# E731: Do not assign a lambda expression, use a def
# F405: name may be undefined, or defined from star imports: module
# E402: module level import not at top of file
# F401: module imported but unused
# W504: line break after binary operator
# E127: continuation line over-indented for visual indent
# E231: missing whitespace after ‘,’, ‘;’, or ‘:’
# E501: line too long
# removed:
# F401: module imported but unused
# E231: missing whitespace after ‘,’, ‘;’, or ‘:’
# E127: continuation line over-indented for visual indent
# F403: ‘from module import *’ used; unable to detect undefined names


[isort]
# https://pycqa.github.io/isort/docs/configuration/options.html
line_length = 120
Expand All @@ -48,7 +50,7 @@ spaces_before_comment = 2
COLUMN_LIMIT = 120
COALESCE_BRACKETS = True
SPACES_AROUND_POWER_OPERATOR = True
SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET = False
SPACE_BETWEEN_ENDING_COMMA_AND_CLOSING_BRACKET = True
SPLIT_BEFORE_CLOSING_BRACKET = False
SPLIT_BEFORE_FIRST_ARGUMENT = False
# EACH_DICT_ENTRY_ON_SEPARATE_LINE = False
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def get_version():
'Topic :: Scientific/Engineering :: Image Recognition',
'Operating System :: POSIX :: Linux',
'Operating System :: MacOS',
'Operating System :: Microsoft :: Windows',],
'Operating System :: Microsoft :: Windows', ],
keywords='machine-learning, deep-learning, vision, ML, DL, AI, YOLO, YOLOv3, YOLOv5, YOLOv8, HUB, Ultralytics',
entry_points={
'console_scripts': ['yolo = ultralytics.yolo.cfg:entrypoint', 'ultralytics = ultralytics.yolo.cfg:entrypoint']})
4 changes: 2 additions & 2 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_special_modes():

# Train checks ---------------------------------------------------------------------------------------------------------
def test_train_det():
run(f'yolo train detect model={CFG}.yaml data=coco8.yaml imgsz=32 epochs=1')
run(f'yolo train detect model={CFG}.yaml data=coco8.yaml imgsz=32 epochs=1 v5loader')


def test_train_seg():
Expand All @@ -48,7 +48,7 @@ def test_val_classify():

# Predict checks -------------------------------------------------------------------------------------------------------
def test_predict_detect():
run(f"yolo predict model={MODEL}.pt source={ROOT / 'assets'} imgsz=32 save")
run(f"yolo predict model={MODEL}.pt source={ROOT / 'assets'} imgsz=32 save save_crop save_txt")
if checks.check_online():
run(f'yolo predict model={MODEL}.pt source=https://ultralytics.com/images/bus.jpg imgsz=32')
run(f'yolo predict model={MODEL}.pt source=https://ultralytics.com/assets/decelera_landscape_min.mov imgsz=32')
Expand Down
5 changes: 2 additions & 3 deletions tests/test_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,8 @@ def test_workflow():


def test_predict_callback_and_setup():

def on_predict_batch_end(predictor):
# results -> List[batch_size]
# test callback addition for prediction
def on_predict_batch_end(predictor): # results -> List[batch_size]
path, _, im0s, _, _ = predictor.batch
# print('on_predict_batch_end', im0s[0].shape)
im0s = im0s if isinstance(im0s, list) else [im0s]
Expand Down
4 changes: 2 additions & 2 deletions ultralytics/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Ultralytics YOLO 🚀, GPL-3.0 license

__version__ = '8.0.46'
__version__ = '8.0.47'

from ultralytics.yolo.engine.model import YOLO
from ultralytics.yolo.utils.checks import check_yolo as checks

__all__ = ['__version__', 'YOLO', 'checks'] # allow simpler import
__all__ = '__version__', 'YOLO', 'checks' # allow simpler import
11 changes: 6 additions & 5 deletions ultralytics/hub/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,12 @@ def __init__(self):
'python': platform.python_version(),
'release': __version__,
'environment': ENVIRONMENT}
self.enabled = SETTINGS['sync'] and \
RANK in {-1, 0} and \
check_online() and \
not TESTS_RUNNING and \
(is_pip_package() or get_git_origin_url() == 'https://github.com/ultralytics/ultralytics.git')
self.enabled = \
SETTINGS['sync'] and \
RANK in {-1, 0} and \
check_online() and \
not TESTS_RUNNING and \
(is_pip_package() or get_git_origin_url() == 'https://github.com/ultralytics/ultralytics.git')

def __call__(self, cfg, all_keys=False, traces_sample_rate=1.0):
"""
Expand Down
26 changes: 15 additions & 11 deletions ultralytics/nn/autobackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def __init__(self, weights='yolov8n.pt', device=torch.device('cpu'), dnn=False,
batch_dim = get_batch(network)
if batch_dim.is_static:
batch_size = batch_dim.get_length()
executable_network = ie.compile_model(network, device_name='CPU') # device_name="MYRIAD" for Intel NCS2
executable_network = ie.compile_model(network, device_name='CPU') # device_name="MYRIAD" for NCS2
elif engine: # TensorRT
LOGGER.info(f'Loading {w} for TensorRT inference...')
import tensorrt as trt # https://developer.nvidia.com/nvidia-tensorrt-download
Expand Down Expand Up @@ -176,6 +176,8 @@ def __init__(self, weights='yolov8n.pt', device=torch.device('cpu'), dnn=False,
LOGGER.info(f'Loading {w} for CoreML inference...')
import coremltools as ct
model = ct.models.MLModel(w)
names, stride, task = (model.user_defined_metadata.get(k) for k in ('names', 'stride', 'task'))
names, stride = eval(names), int(stride)
elif saved_model: # TF SavedModel
LOGGER.info(f'Loading {w} for TensorFlow SavedModel inference...')
import tensorflow as tf
Expand All @@ -185,18 +187,13 @@ def __init__(self, weights='yolov8n.pt', device=torch.device('cpu'), dnn=False,
LOGGER.info(f'Loading {w} for TensorFlow GraphDef inference...')
import tensorflow as tf

from ultralytics.yolo.engine.exporter import gd_outputs

def wrap_frozen_graph(gd, inputs, outputs):
x = tf.compat.v1.wrap_function(lambda: tf.compat.v1.import_graph_def(gd, name=''), []) # wrapped
ge = x.graph.as_graph_element
return x.prune(tf.nest.map_structure(ge, inputs), tf.nest.map_structure(ge, outputs))

def gd_outputs(gd):
name_list, input_list = [], []
for node in gd.node: # tensorflow.core.framework.node_def_pb2.NodeDef
name_list.append(node.name)
input_list.extend(node.input)
return sorted(f'{x}:0' for x in list(set(name_list) - set(input_list)) if not x.startswith('NoOp'))

gd = tf.Graph().as_graph_def() # TF GraphDef
with open(w, 'rb') as f:
gd.ParseFromString(f.read())
Expand Down Expand Up @@ -319,10 +316,17 @@ def forward(self, im, augment=False, visualize=False):
self.context.execute_v2(list(self.binding_addrs.values()))
y = [self.bindings[x].data for x in sorted(self.output_names)]
elif self.coreml: # CoreML
im = im.cpu().numpy()
im = Image.fromarray((im[0] * 255).astype('uint8'))
im = im[0].cpu().numpy()
if self.task == 'classify':
from ultralytics.yolo.data.utils import IMAGENET_MEAN, IMAGENET_STD

# im_pil = Image.fromarray(((im / 6 + 0.5) * 255).astype('uint8'))
for i in range(3):
im[..., i] *= IMAGENET_STD[i]
im[..., i] += IMAGENET_MEAN[i]
im_pil = Image.fromarray((im * 255).astype('uint8'))
# im = im.resize((192, 320), Image.ANTIALIAS)
y = self.model.predict({'image': im}) # coordinates are xywh normalized
y = self.model.predict({'image': im_pil}) # coordinates are xywh normalized
if 'confidence' in y:
box = xywh2xyxy(y['coordinates'] * [[w, h, w, h]]) # xyxy pixels
conf, cls = y['confidence'].max(1), y['confidence'].argmax(1).astype(np.float)
Expand Down
41 changes: 23 additions & 18 deletions ultralytics/nn/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from ultralytics.nn.modules import (C1, C2, C3, C3TR, SPP, SPPF, Bottleneck, BottleneckCSP, C2f, C3Ghost, C3x, Classify,
Concat, Conv, ConvTranspose, Detect, DWConv, DWConvTranspose2d, Ensemble, Focus,
GhostBottleneck, GhostConv, Segment)
from ultralytics.yolo.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, RANK, colorstr, yaml_load
from ultralytics.yolo.utils import DEFAULT_CFG_DICT, DEFAULT_CFG_KEYS, LOGGER, RANK, colorstr, emojis, yaml_load
from ultralytics.yolo.utils.checks import check_requirements, check_yaml
from ultralytics.yolo.utils.torch_utils import (fuse_conv_and_bn, fuse_deconv_and_bn, initialize_weights,
intersect_dicts, make_divisible, model_info, scale_img, time_sync)
Expand Down Expand Up @@ -76,7 +76,7 @@ def _profile_one_layer(self, m, x, dt):
None
"""
c = m == self.model[-1] # is final layer, copy input as inplace fix
o = thop.profile(m, inputs=(x.clone() if c else x,), verbose=False)[0] / 1E9 * 2 if thop else 0 # FLOPs
o = thop.profile(m, inputs=[x.clone() if c else x], verbose=False)[0] / 1E9 * 2 if thop else 0 # FLOPs
t = time_sync()
for _ in range(10):
m(x.clone() if c else x)
Expand Down Expand Up @@ -339,14 +339,20 @@ def torch_safe_load(weight):
file = attempt_download_asset(weight) # search online if missing locally
try:
return torch.load(file, map_location='cpu'), file # load
except ModuleNotFoundError as e:
if e.name == 'omegaconf': # e.name is missing module name
LOGGER.warning(f'WARNING ⚠️ {weight} requires {e.name}, which is not in ultralytics requirements.'
f'\nAutoInstall will run now for {e.name} but this feature will be removed in the future.'
f'\nRecommend fixes are to train a new model using updated ultralytics package or to '
f'download updated models from https://github.com/ultralytics/assets/releases/tag/v0.0.0')
if e.name != 'models':
check_requirements(e.name) # install missing module
except ModuleNotFoundError as e: # e.name is missing module name
if e.name == 'models':
raise TypeError(
emojis(f'ERROR ❌️ {weight} appears to be an Ultralytics YOLOv5 model originally trained '
f'with https://github.com/ultralytics/yolov5.\nThis model is NOT forwards compatible with '
f'YOLOv8 at https://github.com/ultralytics/ultralytics.'
f"\nRecommend fixes are to train a new model using the latest 'ultralytics' package or to "
f"run a command with an official YOLOv8 model, i.e. 'yolo predict model=yolov8n.pt'")) from e
LOGGER.warning(f"WARNING ⚠️ {weight} appears to require '{e.name}', which is not in ultralytics requirements."
f"\nAutoInstall will run now for '{e.name}' but this feature will be removed in the future."
f"\nRecommend fixes are to train a new model using the latest 'ultralytics' package or to "
f"run a command with an official YOLOv8 model, i.e. 'yolo predict model=yolov8n.pt'")
check_requirements(e.name) # install missing module

return torch.load(file, map_location='cpu'), file # load


Expand Down Expand Up @@ -437,22 +443,21 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)
args[j] = eval(a) if isinstance(a, str) else a # eval strings

n = n_ = max(round(n * gd), 1) if n > 1 else n # depth gain
if m in {
Classify, Conv, ConvTranspose, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, Focus,
BottleneckCSP, C1, C2, C2f, C3, C3TR, C3Ghost, nn.ConvTranspose2d, DWConvTranspose2d, C3x}:
if m in (Classify, Conv, ConvTranspose, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, Focus,
BottleneckCSP, C1, C2, C2f, C3, C3TR, C3Ghost, nn.ConvTranspose2d, DWConvTranspose2d, C3x):
c1, c2 = ch[f], args[0]
if c2 != nc: # if c2 not equal to number of classes (i.e. for Classify() output)
c2 = make_divisible(c2 * gw, 8)

args = [c1, c2, *args[1:]]
if m in {BottleneckCSP, C1, C2, C2f, C3, C3TR, C3Ghost, C3x}:
if m in (BottleneckCSP, C1, C2, C2f, C3, C3TR, C3Ghost, C3x):
args.insert(2, n) # number of repeats
n = 1
elif m is nn.BatchNorm2d:
args = [ch[f]]
elif m is Concat:
c2 = sum(ch[x] for x in f)
elif m in {Detect, Segment}:
elif m in (Detect, Segment):
args.append([ch[x] for x in f])
if m is Segment:
args[2] = make_divisible(args[2] * gw, 8)
Expand Down Expand Up @@ -490,11 +495,11 @@ def guess_model_task(model):
def cfg2task(cfg):
# Guess from YAML dictionary
m = cfg['head'][-1][-2].lower() # output module name
if m in ['classify', 'classifier', 'cls', 'fc']:
if m in ('classify', 'classifier', 'cls', 'fc'):
return 'classify'
if m in ['detect']:
if m == 'detect':
return 'detect'
if m in ['segment']:
if m == 'segment':
return 'segment'

# Guess from model cfg
Expand Down
2 changes: 2 additions & 0 deletions ultralytics/tracker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@

from .track import register_tracker
from .trackers import BOTSORT, BYTETracker

__all__ = 'register_tracker', 'BOTSORT', 'BYTETracker' # allow simpler import
Loading

0 comments on commit a58f766

Please sign in to comment.