Skip to content

Commit

Permalink
update to ultralytics/yolov5 13.12.22 (#170)
Browse files Browse the repository at this point in the history
* init update

* update val

* update export

* update benchmarks

* update detect

* update train

* update utils

* update segment utils

* update wandb utils

* update clearml utils

* update data

* update models

* update version

* update classify

* update segment

* fix val

* fix val

* fix val half

* fix val half
  • Loading branch information
fcakyon authored Dec 13, 2022
1 parent 9defab4 commit bba5f85
Show file tree
Hide file tree
Showing 33 changed files with 409 additions and 279 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ You can finally install <a href="https://github.com/ultralytics/yolov5">YOLOv5 o
</div>

<br>
This yolov5 package contains everything from ultralytics/yolov5 <a href="https://github.com/ultralytics/yolov5/tree/8236d8818bca21c692d5c4508fee2af835ec1dbe">at this commit</a> plus:
This yolov5 package contains everything from ultralytics/yolov5 <a href="https://github.com/ultralytics/yolov5/commit/357cde9ee7da13ba3095995488c5a23631467f1a">at this commit</a> plus:
<br>
1. Easy installation via pip: `pip install yolov5`
<br>
Expand Down
26 changes: 14 additions & 12 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
# YOLOv5 requirements
# YOLOv5 🚀 requirements
# Usage: pip install -r requirements.txt

# Base ----------------------------------------
# Base ------------------------------------------------------------------------
gitpython
ipython # interactive notebook
matplotlib>=3.2.2
numpy>=1.18.5
opencv-python>=4.1.1
Pillow>=7.1.2
psutil # system resources
PyYAML>=5.3.1
requests>=2.23.0
scipy>=1.4.1
torch>=1.7.0 # see https://pytorch.org/get-started/locally/ (recommended)
thop>=0.1.1 # FLOPs computation
torch>=1.7.0 # see https://pytorch.org/get-started/locally (recommended)
torchvision>=0.8.1
tqdm>=4.64.0
# protobuf<=3.20.1 # https://github.com/ultralytics/yolov5/issues/8012

# Logging -------------------------------------
# Logging ---------------------------------------------------------------------
tensorboard>=2.4.1
# clearml
# clearml>=1.2.0
# comet

# Plotting ------------------------------------
# Plotting --------------------------------------------------------------------
pandas>=1.1.4
seaborn>=0.11.0

# Export --------------------------------------
# Export ----------------------------------------------------------------------
# coremltools>=6.0 # CoreML export
# onnx>=1.9.0 # ONNX export
# onnx-simplifier>=0.4.1 # ONNX simplifier
Expand All @@ -34,17 +38,15 @@ seaborn>=0.11.0
# tensorflowjs>=3.9.0 # TF.js export
# openvino-dev # OpenVINO export

# Deploy --------------------------------------
# Deploy ----------------------------------------------------------------------
# tritonclient[all]~=2.24.0

# Extras --------------------------------------
ipython # interactive notebook
psutil # system utilization
thop>=0.1.1 # FLOPs computation
# Extras ----------------------------------------------------------------------
# mss # screenshots
# albumentations>=1.0.3
# pycocotools>=2.0 # COCO mAP
# roboflow
# ultralytics # HUB https://hub.ultralytics.com

# CLI
fire
Expand Down
2 changes: 1 addition & 1 deletion yolov5/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from yolov5.helpers import YOLOv5
from yolov5.helpers import load_model as load

__version__ = "6.2.3"
__version__ = "7.0.0"
2 changes: 1 addition & 1 deletion yolov5/benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def run_cli(**kwargs):

def parse_opt():
parser = argparse.ArgumentParser()
parser.add_argument('--weights', type=str, default=ROOT / 'yolov5s.pt', help='weights path')
parser.add_argument('--weights', type=str, default='yolov5s.pt', help='weights path')
parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='inference size (pixels)')
parser.add_argument('--batch-size', type=int, default=1, help='batch size')
parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='dataset.yaml path')
Expand Down
9 changes: 6 additions & 3 deletions yolov5/classify/predict.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
$ python classify/predict.py --weights yolov5s-cls.pt --source 0 # webcam
img.jpg # image
vid.mp4 # video
screen # screenshot
path/ # directory
list.txt # list of images
list.streams # list of streams
'path/*.jpg' # glob
'https://youtu.be/Zgi9g1ksQHc' # YouTube
'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP stream
Expand Down Expand Up @@ -63,7 +66,7 @@ def run(
augment=False, # augmented inference
visualize=False, # visualize features
update=False, # update all models
project=ROOT / 'runs/predict-cls', # save results to project/name
project='runs/predict-cls', # save results to project/name
name='exp', # save results to project/name
exist_ok=False, # existing project/name ok, do not increment
half=False, # use FP16 half-precision inference
Expand All @@ -74,7 +77,7 @@ def run(
save_img = not nosave and not source.endswith('.txt') # save inference images
is_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)
is_url = source.lower().startswith(('rtsp://', 'rtmp://', 'http://', 'https://'))
webcam = source.isnumeric() or source.endswith('.txt') or (is_url and not is_file)
webcam = source.isnumeric() or source.endswith('.streams') or (is_url and not is_file)
screenshot = source.lower().startswith('screen')
if is_url and is_file:
source = check_file(source) # download
Expand Down Expand Up @@ -205,7 +208,7 @@ def parse_opt():
parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[224], help='inference size h,w')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--view-img', action='store_true', help='show results')
parser.add_argument('--save-txt', action='store_false', help='save results to *.txt')
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--visualize', action='store_true', help='visualize features')
Expand Down
7 changes: 4 additions & 3 deletions yolov5/classify/train.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
from yolov5.models.experimental import attempt_load
from yolov5.models.yolo import ClassificationModel, DetectionModel
from yolov5.utils.dataloaders import create_classification_dataloader
from yolov5.utils.general import (DATASETS_DIR, LOGGER, WorkingDirectory, check_git_status, check_requirements, colorstr,
download, increment_path, init_seeds, print_args, yaml_save)
from yolov5.utils.general import (DATASETS_DIR, LOGGER, TQDM_BAR_FORMAT, WorkingDirectory, check_git_info, check_git_status,
check_requirements, colorstr, download, increment_path, init_seeds, print_args, yaml_save)
from yolov5.utils.loggers import GenericLogger
from yolov5.utils.plots import imshow_cls
from yolov5.utils.torch_utils import (ModelEMA, model_info, reshape_classifier_output, select_device, smart_DDP,
Expand All @@ -50,6 +50,7 @@
LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1)) # https://pytorch.org/docs/stable/elastic/run.html
RANK = int(os.getenv('RANK', -1))
WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1))
#GIT_INFO = check_git_info()


def train(opt, device):
Expand Down Expand Up @@ -174,7 +175,7 @@ def train(opt, device):
trainloader.sampler.set_epoch(epoch)
pbar = enumerate(trainloader)
if RANK in {-1, 0}:
pbar = tqdm(enumerate(trainloader), total=len(trainloader), bar_format='{l_bar}{bar:10}{r_bar}{bar:-10b}')
pbar = tqdm(enumerate(trainloader), total=len(trainloader), bar_format=TQDM_BAR_FORMAT)
for i, (images, labels) in pbar: # progress bar
images, labels = images.to(device, non_blocking=True), labels.to(device)

Expand Down
5 changes: 3 additions & 2 deletions yolov5/classify/val.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@

from yolov5.models.common import DetectMultiBackend
from yolov5.utils.dataloaders import create_classification_dataloader
from yolov5.utils.general import LOGGER, Profile, check_img_size, check_requirements, colorstr, increment_path, print_args
from yolov5.utils.general import (LOGGER, TQDM_BAR_FORMAT, Profile, check_img_size, check_requirements, colorstr,
increment_path, print_args)
from yolov5.utils.torch_utils import select_device, smart_inference_mode


Expand Down Expand Up @@ -112,7 +113,7 @@ def run(
n = len(dataloader) # number of batches
action = 'validating' if dataloader.dataset.root.stem == 'val' else 'testing'
desc = f"{pbar.desc[:-36]}{action:>36}" if pbar else f"{action}"
bar = tqdm(dataloader, desc, n, not training, bar_format='{l_bar}{bar:10}{r_bar}{bar:-10b}', position=0)
bar = tqdm(dataloader, desc, n, not training, bar_format=TQDM_BAR_FORMAT, position=0)
with torch.cuda.amp.autocast(enabled=device.type != 'cpu'):
for images, labels in bar:
with dt[0]:
Expand Down
7 changes: 4 additions & 3 deletions yolov5/data/scripts/download_weights.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
# └── ...

python - <<EOF
from yolov5.utils.downloads import attempt_download
from utils.downloads import attempt_download
p5 = ['n', 's', 'm', 'l', 'x'] # P5 models
p5 = list('nsmlx') # P5 models
p6 = [f'{x}6' for x in p5] # P6 models
cls = [f'{x}-cls' for x in p5] # classification models
seg = [f'{x}-seg' for x in p5] # classification models
for x in p5 + p6 + cls:
for x in p5 + p6 + cls + seg:
attempt_download(f'weights/yolov5{x}.pt')
EOF
2 changes: 1 addition & 1 deletion yolov5/data/scripts/get_coco.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ url=https://github.com/ultralytics/yolov5/releases/download/v1.0/
if [ "$segments" == "true" ]; then
f='coco2017labels-segments.zip' # 168 MB
else
f='coco2017labels.zip' # 168 MB
f='coco2017labels.zip' # 46 MB
fi
echo 'Downloading' $url$f ' ...'
curl -L $url$f -o $f -# && unzip -q $f -d $d && rm $f &
Expand Down
37 changes: 20 additions & 17 deletions yolov5/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,28 @@
Usage - sources:
$ yolov5 detect --weights yolov5s.pt --source 0 # webcam
img.jpg # image
vid.mp4 # video
path/ # directory
'path/*.jpg' # glob
'https://youtu.be/Zgi9g1ksQHc' # YouTube
'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP stream
img.jpg # image
vid.mp4 # video
screen # screenshot
path/ # directory
list.txt # list of images
list.streams # list of streams
'path/*.jpg' # glob
'https://youtu.be/Zgi9g1ksQHc' # YouTube
'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP stream
Usage - formats:
$ yolov5 detect --weights yolov5s.pt # PyTorch
yolov5s.torchscript # TorchScript
yolov5s.onnx # ONNX Runtime or OpenCV DNN with --dnn
yolov5s.xml # OpenVINO
yolov5s.engine # TensorRT
yolov5s.mlmodel # CoreML (macOS-only)
yolov5s_saved_model # TensorFlow SavedModel
yolov5s.pb # TensorFlow GraphDef
yolov5s.tflite # TensorFlow Lite
yolov5s_edgetpu.tflite # TensorFlow Edge TPU
yolov5s_paddle_model # PaddlePaddle
yolov5s.torchscript # TorchScript
yolov5s.onnx # ONNX Runtime or OpenCV DNN with --dnn
yolov5s_openvino_model # OpenVINO
yolov5s.engine # TensorRT
yolov5s.mlmodel # CoreML (macOS-only)
yolov5s_saved_model # TensorFlow SavedModel
yolov5s.pb # TensorFlow GraphDef
yolov5s.tflite # TensorFlow Lite
yolov5s_edgetpu.tflite # TensorFlow Edge TPU
yolov5s_paddle_model # PaddlePaddle
"""

import argparse
Expand Down Expand Up @@ -82,7 +85,7 @@ def run(
save_img = not nosave and not source.endswith('.txt') # save inference images
is_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)
is_url = source.lower().startswith(('rtsp://', 'rtmp://', 'http://', 'https://'))
webcam = source.isnumeric() or source.endswith('.txt') or (is_url and not is_file)
webcam = source.isnumeric() or source.endswith('.streams') or (is_url and not is_file)
screenshot = source.lower().startswith('screen')
if is_url and is_file:
source = check_file(source) # download
Expand Down
11 changes: 6 additions & 5 deletions yolov5/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
$ yolov5 export --weights yolov5s.pt --include torchscript onnx openvino engine coreml tflite ...
Inference:
$ yolov5 export --weights yolov5s.pt # PyTorch
$ yolov5 detect --weights yolov5s.pt # PyTorch
yolov5s.torchscript # TorchScript
yolov5s.onnx # ONNX Runtime or OpenCV DNN with --dnn
yolov5s.xml # OpenVINO
yolov5s_openvino_model # OpenVINO
yolov5s.engine # TensorRT
yolov5s.mlmodel # CoreML (macOS-only)
yolov5s_saved_model # TensorFlow SavedModel
Expand Down Expand Up @@ -153,7 +153,7 @@ def export_onnx(model, im, file, opset, dynamic, simplify, prefix=colorstr('ONNX
f,
verbose=False,
opset_version=opset,
do_constant_folding=True,
do_constant_folding=True, # WARNING: DNN inference with torch>=1.12 may require do_constant_folding=False
input_names=['images'],
output_names=output_names,
dynamic_axes=dynamic or None)
Expand Down Expand Up @@ -607,15 +607,16 @@ def run(
f = [str(x) for x in f if x] # filter out '' and None
if any(f):
cls, det, seg = (isinstance(model, x) for x in (ClassificationModel, DetectionModel, SegmentationModel)) # type
det &= not seg # segmentation models inherit from SegmentationModel(DetectionModel)
dir = Path('segment' if seg else 'classify' if cls else '')
h = '--half' if half else '' # --half FP16 inference arg
s = "# WARNING ⚠️ ClassificationModel not yet supported for PyTorch Hub AutoShape inference" if cls else \
"# WARNING ⚠️ SegmentationModel not yet supported for PyTorch Hub AutoShape inference" if seg else ''
LOGGER.info(f'\nExport complete ({time.time() - t:.1f}s)'
f"\nResults saved to {colorstr('bold', file.parent.resolve())}"
f"\nDetect: yolov5 {'detect' if det else 'predict'} --weights {f[-1]} {h}"
f"\nValidate: yolov5 val --weights {f[-1]} {h}"
f"\nPython: model = yolov5.load('{f[-1]}') {s}"
f"\nValidate: yolov5 yolov5 val --weights {f[-1]} {h}"
f"\nnPython: model = yolov5.load('{f[-1]}') {s}"
f"\nVisualize: https://netron.app")
return f # return list of exported files/dirs

Expand Down
4 changes: 2 additions & 2 deletions yolov5/models/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,9 +692,9 @@ def forward(self, ims, size=640, augment=False, profile=False):
s = im.shape[:2] # HWC
shape0.append(s) # image shape
g = max(size) / max(s) # gain
shape1.append([y * g for y in s])
shape1.append([int(y * g) for y in s])
ims[i] = im if im.data.contiguous else np.ascontiguousarray(im) # update
shape1 = [make_divisible(x, self.stride) for x in np.array(shape1).max(0)] if self.pt else size # inf shape
shape1 = [make_divisible(x, self.stride) for x in np.array(shape1).max(0)] # inf shape
x = [letterbox(im, shape1, auto=False)[0] for im in ims] # pad
x = np.ascontiguousarray(np.array(x).transpose((0, 3, 1, 2))) # stack and BHWC to BCHW
x = torch.from_numpy(x).to(p.device).type_as(p) / 255 # uint8 to fp16/32
Expand Down
5 changes: 3 additions & 2 deletions yolov5/models/tf.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ def __init__(self, nc=80, anchors=(), nm=32, npr=256, ch=(), imgsz=(640, 640), w

def call(self, x):
p = self.proto(x[0])
# p = TFUpsample(None, scale_factor=4, mode='nearest')(self.proto(x[0])) # (optional) full-size protos
p = tf.transpose(p, [0, 3, 1, 2]) # from shape(1,160,160,32) to shape(1,32,160,160)
x = self.detect(self, x)
return (x, p) if self.training else (x[0], p)
Expand All @@ -355,8 +356,8 @@ class TFUpsample(keras.layers.Layer):
# TF version of torch.nn.Upsample()
def __init__(self, size, scale_factor, mode, w=None): # warning: all arguments needed including 'w'
super().__init__()
assert scale_factor == 2, "scale_factor must be 2"
self.upsample = lambda x: tf.image.resize(x, (x.shape[1] * 2, x.shape[2] * 2), method=mode)
assert scale_factor % 2 == 0, "scale_factor must be multiple of 2"
self.upsample = lambda x: tf.image.resize(x, (x.shape[1] * scale_factor, x.shape[2] * scale_factor), mode)
# self.upsample = keras.layers.UpSampling2D(size=scale_factor, interpolation=mode)
# with default arguments: align_corners=False, half_pixel_centers=False
# self.upsample = lambda x: tf.raw_ops.ResizeNearestNeighbor(images=x,
Expand Down
Loading

0 comments on commit bba5f85

Please sign in to comment.