Unverified 提交 4821d076 authored 作者: Glenn Jocher's avatar Glenn Jocher 提交者: GitHub

Increment train, test, detect runs/ (#1322)

* Increment train, test, detect runs/ * Update ci-testing.yml * inference/images to data/images * move images * runs/exp to runs/train/exp * update 'results saved to %s' str
上级 d3e77781
...@@ -66,10 +66,10 @@ jobs: ...@@ -66,10 +66,10 @@ jobs:
python train.py --img 256 --batch 8 --weights weights/${{ matrix.model }}.pt --cfg models/${{ matrix.model }}.yaml --epochs 1 --device $di python train.py --img 256 --batch 8 --weights weights/${{ matrix.model }}.pt --cfg models/${{ matrix.model }}.yaml --epochs 1 --device $di
# detect # detect
python detect.py --weights weights/${{ matrix.model }}.pt --device $di python detect.py --weights weights/${{ matrix.model }}.pt --device $di
python detect.py --weights runs/exp0/weights/last.pt --device $di python detect.py --weights runs/train/exp0/weights/last.pt --device $di
# test # test
python test.py --img 256 --batch 8 --weights weights/${{ matrix.model }}.pt --device $di python test.py --img 256 --batch 8 --weights weights/${{ matrix.model }}.pt --device $di
python test.py --img 256 --batch 8 --weights runs/exp0/weights/last.pt --device $di python test.py --img 256 --batch 8 --weights runs/train/exp0/weights/last.pt --device $di
python models/yolo.py --cfg models/${{ matrix.model }}.yaml # inspect python models/yolo.py --cfg models/${{ matrix.model }}.yaml # inspect
python models/export.py --img 256 --batch 1 --weights weights/${{ matrix.model }}.pt # export python models/export.py --img 256 --batch 1 --weights weights/${{ matrix.model }}.pt # export
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
storage.googleapis.com storage.googleapis.com
runs/* runs/*
data/* data/*
!data/samples/zidane.jpg !data/images/zidane.jpg
!data/samples/bus.jpg !data/images/bus.jpg
!data/coco.names !data/coco.names
!data/coco_paper.names !data/coco_paper.names
!data/coco.data !data/coco.data
......
...@@ -46,7 +46,7 @@ COPY . /usr/src/app ...@@ -46,7 +46,7 @@ COPY . /usr/src/app
# sudo docker commit 092b16b25c5b usr/resume && sudo docker run -it --gpus all --ipc=host -v "$(pwd)"/coco:/usr/src/coco --entrypoint=sh usr/resume # sudo docker commit 092b16b25c5b usr/resume && sudo docker run -it --gpus all --ipc=host -v "$(pwd)"/coco:/usr/src/coco --entrypoint=sh usr/resume
# Send weights to GCP # Send weights to GCP
# python -c "from utils.general import *; strip_optimizer('runs/exp0_*/weights/best.pt', 'tmp.pt')" && gsutil cp tmp.pt gs://*.pt # python -c "from utils.general import *; strip_optimizer('runs/train/exp0_*/weights/best.pt', 'tmp.pt')" && gsutil cp tmp.pt gs://*.pt
# Clean up # Clean up
# docker system prune -a --volumes # docker system prune -a --volumes
...@@ -70,7 +70,7 @@ YOLOv5 may be run in any of the following up-to-date verified environments (with ...@@ -70,7 +70,7 @@ YOLOv5 may be run in any of the following up-to-date verified environments (with
## Inference ## Inference
detect.py runs inference on a variety of sources, downloading models automatically from the [latest YOLOv5 release](https://github.com/ultralytics/yolov5/releases) and saving results to `inference/output`. detect.py runs inference on a variety of sources, downloading models automatically from the [latest YOLOv5 release](https://github.com/ultralytics/yolov5/releases) and saving results to `runs/detect`.
```bash ```bash
$ python detect.py --source 0 # webcam $ python detect.py --source 0 # webcam
file.jpg # image file.jpg # image
...@@ -82,20 +82,20 @@ $ python detect.py --source 0 # webcam ...@@ -82,20 +82,20 @@ $ python detect.py --source 0 # webcam
http://112.50.243.8/PLTV/88888888/224/3221225900/1.m3u8 # http stream http://112.50.243.8/PLTV/88888888/224/3221225900/1.m3u8 # http stream
``` ```
To run inference on example images in `inference/images`: To run inference on example images in `data/images`:
```bash ```bash
$ python detect.py --source inference/images --weights yolov5s.pt --conf 0.25 $ python detect.py --source data/images --weights yolov5s.pt --conf 0.25
Namespace(agnostic_nms=False, augment=False, classes=None, conf_thres=0.25, device='', img_size=640, iou_thres=0.45, output='inference/output', save_conf=False, save_txt=False, source='inference/images', update=False, view_img=False, weights='yolov5s.pt') Namespace(agnostic_nms=False, augment=False, classes=None, conf_thres=0.25, device='', img_size=640, iou_thres=0.45, output='runs/detect', save_conf=False, save_txt=False, source='data/images', update=False, view_img=False, weights='yolov5s.pt')
Using CUDA device0 _CudaDeviceProperties(name='Tesla V100-SXM2-16GB', total_memory=16160MB) Using CUDA device0 _CudaDeviceProperties(name='Tesla V100-SXM2-16GB', total_memory=16160MB)
Downloading https://github.com/ultralytics/yolov5/releases/download/v3.0/yolov5s.pt to yolov5s.pt... 100%|██████████████| 14.5M/14.5M [00:00<00:00, 21.3MB/s] Downloading https://github.com/ultralytics/yolov5/releases/download/v3.0/yolov5s.pt to yolov5s.pt... 100%|██████████████| 14.5M/14.5M [00:00<00:00, 21.3MB/s]
Fusing layers... Fusing layers...
Model Summary: 140 layers, 7.45958e+06 parameters, 0 gradients Model Summary: 140 layers, 7.45958e+06 parameters, 0 gradients
image 1/2 yolov5/inference/images/bus.jpg: 640x480 4 persons, 1 buss, 1 skateboards, Done. (0.013s) image 1/2 data/images/bus.jpg: 640x480 4 persons, 1 buss, 1 skateboards, Done. (0.013s)
image 2/2 yolov5/inference/images/zidane.jpg: 384x640 2 persons, 2 ties, Done. (0.013s) image 2/2 data/images/zidane.jpg: 384x640 2 persons, 2 ties, Done. (0.013s)
Results saved to yolov5/inference/output Results saved to runs/detect/exp0
Done. (0.124s) Done. (0.124s)
``` ```
<img src="https://user-images.githubusercontent.com/26833433/97107365-685a8d80-16c7-11eb-8c2e-83aac701d8b9.jpeg" width="500"> <img src="https://user-images.githubusercontent.com/26833433/97107365-685a8d80-16c7-11eb-8c2e-83aac701d8b9.jpeg" width="500">
......
import argparse import argparse
import os import os
import shutil
import time import time
from pathlib import Path from pathlib import Path
...@@ -11,23 +10,25 @@ from numpy import random ...@@ -11,23 +10,25 @@ from numpy import random
from models.experimental import attempt_load from models.experimental import attempt_load
from utils.datasets import LoadStreams, LoadImages from utils.datasets import LoadStreams, LoadImages
from utils.general import ( from utils.general import check_img_size, non_max_suppression, apply_classifier, scale_coords, xyxy2xywh, \
check_img_size, non_max_suppression, apply_classifier, scale_coords, plot_one_box, strip_optimizer, set_logging, increment_dir
xyxy2xywh, plot_one_box, strip_optimizer, set_logging)
from utils.torch_utils import select_device, load_classifier, time_synchronized from utils.torch_utils import select_device, load_classifier, time_synchronized
def detect(save_img=False): def detect(save_img=False):
out, source, weights, view_img, save_txt, imgsz = \ save_dir, source, weights, view_img, save_txt, imgsz = \
opt.save_dir, opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size Path(opt.save_dir), opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size
webcam = source.isnumeric() or source.startswith(('rtsp://', 'rtmp://', 'http://')) or source.endswith('.txt') webcam = source.isnumeric() or source.startswith(('rtsp://', 'rtmp://', 'http://')) or source.endswith('.txt')
# Directories
if save_dir == Path('runs/detect'): # if default
os.makedirs('runs/detect', exist_ok=True) # make base
save_dir = Path(increment_dir(save_dir / 'exp', opt.name)) # increment run
os.makedirs(save_dir / 'labels' if save_txt else save_dir, exist_ok=True) # make new dir
# Initialize # Initialize
set_logging() set_logging()
device = select_device(opt.device) device = select_device(opt.device)
if os.path.exists(out): # output dir
shutil.rmtree(out) # delete dir
os.makedirs(out) # make new dir
half = device.type != 'cpu' # half precision only supported on CUDA half = device.type != 'cpu' # half precision only supported on CUDA
# Load model # Load model
...@@ -83,12 +84,12 @@ def detect(save_img=False): ...@@ -83,12 +84,12 @@ def detect(save_img=False):
# Process detections # Process detections
for i, det in enumerate(pred): # detections per image for i, det in enumerate(pred): # detections per image
if webcam: # batch_size >= 1 if webcam: # batch_size >= 1
p, s, im0 = path[i], '%g: ' % i, im0s[i].copy() p, s, im0 = Path(path[i]), '%g: ' % i, im0s[i].copy()
else: else:
p, s, im0 = path, '', im0s p, s, im0 = Path(path), '', im0s
save_path = str(Path(out) / Path(p).name) save_path = str(save_dir / p.name)
txt_path = str(Path(out) / Path(p).stem) + ('_%g' % dataset.frame if dataset.mode == 'video' else '') txt_path = str(save_dir / 'labels' / p.stem) + ('_%g' % dataset.frame if dataset.mode == 'video' else '')
s += '%gx%g ' % img.shape[2:] # print string s += '%gx%g ' % img.shape[2:] # print string
gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh
if det is not None and len(det): if det is not None and len(det):
...@@ -104,7 +105,7 @@ def detect(save_img=False): ...@@ -104,7 +105,7 @@ def detect(save_img=False):
for *xyxy, conf, cls in reversed(det): for *xyxy, conf, cls in reversed(det):
if save_txt: # Write to file if save_txt: # Write to file
xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
line = (cls, conf, *xywh) if opt.save_conf else (cls, *xywh) # label format line = (cls, *xywh, conf) if opt.save_conf else (cls, *xywh) # label format
with open(txt_path + '.txt', 'a') as f: with open(txt_path + '.txt', 'a') as f:
f.write(('%g ' * len(line) + '\n') % line) f.write(('%g ' * len(line) + '\n') % line)
...@@ -139,7 +140,7 @@ def detect(save_img=False): ...@@ -139,7 +140,7 @@ def detect(save_img=False):
vid_writer.write(im0) vid_writer.write(im0)
if save_txt or save_img: if save_txt or save_img:
print('Results saved to %s' % Path(out)) print('Results saved to %s' % save_dir)
print('Done. (%.3fs)' % (time.time() - t0)) print('Done. (%.3fs)' % (time.time() - t0))
...@@ -147,15 +148,16 @@ def detect(save_img=False): ...@@ -147,15 +148,16 @@ def detect(save_img=False):
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)') parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')
parser.add_argument('--source', type=str, default='inference/images', help='source') # file/folder, 0 for webcam parser.add_argument('--source', type=str, default='data/images', help='source') # file/folder, 0 for webcam
parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)') parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold') parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS') parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') 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='display results') parser.add_argument('--view-img', action='store_true', help='display results')
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt') parser.add_argument('--save-txt', action='store_false', help='save results to *.txt')
parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels') parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
parser.add_argument('--save-dir', type=str, default='inference/output', help='directory to save results') parser.add_argument('--save-dir', type=str, default='runs/detect', help='directory to save results')
parser.add_argument('--name', default='', help='name to append to --save-dir: i.e. runs/{N} -> runs/{N}_{name}')
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3') parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS') parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true', help='augmented inference') parser.add_argument('--augment', action='store_true', help='augmented inference')
......
...@@ -113,6 +113,6 @@ if __name__ == '__main__': ...@@ -113,6 +113,6 @@ if __name__ == '__main__':
# Verify inference # Verify inference
from PIL import Image from PIL import Image
img = Image.open('inference/images/zidane.jpg') img = Image.open('data/images/zidane.jpg')
y = model(img) y = model(img)
print(y[0].shape) print(y[0].shape)
差异被折叠。
...@@ -2,7 +2,6 @@ import argparse ...@@ -2,7 +2,6 @@ import argparse
import glob import glob
import json import json
import os import os
import shutil
from pathlib import Path from pathlib import Path
import numpy as np import numpy as np
...@@ -12,9 +11,9 @@ from tqdm import tqdm ...@@ -12,9 +11,9 @@ from tqdm import tqdm
from models.experimental import attempt_load from models.experimental import attempt_load
from utils.datasets import create_dataloader from utils.datasets import create_dataloader
from utils.general import ( from utils.general import coco80_to_coco91_class, check_dataset, check_file, check_img_size, compute_loss, \
coco80_to_coco91_class, check_dataset, check_file, check_img_size, compute_loss, non_max_suppression, scale_coords, non_max_suppression, scale_coords, xyxy2xywh, clip_coords, plot_images, xywh2xyxy, box_iou, output_to_target, \
xyxy2xywh, clip_coords, plot_images, xywh2xyxy, box_iou, output_to_target, ap_per_class, set_logging) ap_per_class, set_logging, increment_dir
from utils.torch_utils import select_device, time_synchronized from utils.torch_utils import select_device, time_synchronized
...@@ -46,16 +45,11 @@ def test(data, ...@@ -46,16 +45,11 @@ def test(data,
device = select_device(opt.device, batch_size=batch_size) device = select_device(opt.device, batch_size=batch_size)
save_txt = opt.save_txt # save *.txt labels save_txt = opt.save_txt # save *.txt labels
# Remove previous # Directories
if os.path.exists(save_dir): if save_dir == Path('runs/test'): # if default
shutil.rmtree(save_dir) # delete dir os.makedirs('runs/test', exist_ok=True) # make base
os.makedirs(save_dir) # make new dir save_dir = Path(increment_dir(save_dir / 'exp', opt.name)) # increment run
os.makedirs(save_dir / 'labels' if save_txt else save_dir, exist_ok=True) # make new dir
if save_txt:
out = save_dir / 'autolabels'
if os.path.exists(out):
shutil.rmtree(out) # delete dir
os.makedirs(out) # make new dir
# Load model # Load model
model = attempt_load(weights, map_location=device) # load FP32 model model = attempt_load(weights, map_location=device) # load FP32 model
...@@ -144,8 +138,8 @@ def test(data, ...@@ -144,8 +138,8 @@ def test(data,
x[:, :4] = scale_coords(img[si].shape[1:], x[:, :4], shapes[si][0], shapes[si][1]) # to original x[:, :4] = scale_coords(img[si].shape[1:], x[:, :4], shapes[si][0], shapes[si][1]) # to original
for *xyxy, conf, cls in x: for *xyxy, conf, cls in x:
xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
line = (cls, conf, *xywh) if save_conf else (cls, *xywh) # label format line = (cls, *xywh, conf) if save_conf else (cls, *xywh) # label format
with open(str(out / Path(paths[si]).stem) + '.txt', 'a') as f: with open(str(save_dir / 'labels' / Path(paths[si]).stem) + '.txt', 'a') as f:
f.write(('%g ' * len(line) + '\n') % line) f.write(('%g ' * len(line) + '\n') % line)
# W&B logging # W&B logging
...@@ -268,6 +262,7 @@ def test(data, ...@@ -268,6 +262,7 @@ def test(data,
print('ERROR: pycocotools unable to run: %s' % e) print('ERROR: pycocotools unable to run: %s' % e)
# Return results # Return results
print('Results saved to %s' % save_dir)
model.float() # for training model.float() # for training
maps = np.zeros(nc) + map maps = np.zeros(nc) + map
for i, c in enumerate(ap_class): for i, c in enumerate(ap_class):
...@@ -292,6 +287,7 @@ if __name__ == '__main__': ...@@ -292,6 +287,7 @@ if __name__ == '__main__':
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt') parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels') parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
parser.add_argument('--save-dir', type=str, default='runs/test', help='directory to save results') parser.add_argument('--save-dir', type=str, default='runs/test', help='directory to save results')
parser.add_argument('--name', default='', help='name to append to --save-dir: i.e. runs/{N} -> runs/{N}_{name}')
opt = parser.parse_args() opt = parser.parse_args()
opt.save_json |= opt.data.endswith('coco.yaml') opt.save_json |= opt.data.endswith('coco.yaml')
opt.data = check_file(opt.data) # check file opt.data = check_file(opt.data) # check file
...@@ -313,8 +309,6 @@ if __name__ == '__main__': ...@@ -313,8 +309,6 @@ if __name__ == '__main__':
save_conf=opt.save_conf, save_conf=opt.save_conf,
) )
print('Results saved to %s' % opt.save_dir)
elif opt.task == 'study': # run over a range of settings and save/plot elif opt.task == 'study': # run over a range of settings and save/plot
for weights in ['yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt']: for weights in ['yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt']:
f = 'study_%s_%s.txt' % (Path(opt.data).stem, Path(weights).stem) # filename to save to f = 'study_%s_%s.txt' % (Path(opt.data).stem, Path(weights).stem) # filename to save to
......
import argparse import argparse
import logging import logging
import math
import os import os
import random import random
import shutil import shutil
...@@ -7,7 +8,6 @@ import time ...@@ -7,7 +8,6 @@ import time
from pathlib import Path from pathlib import Path
from warnings import warn from warnings import warn
import math
import numpy as np import numpy as np
import torch.distributed as dist import torch.distributed as dist
import torch.nn as nn import torch.nn as nn
...@@ -404,14 +404,14 @@ if __name__ == '__main__': ...@@ -404,14 +404,14 @@ if __name__ == '__main__':
parser.add_argument('--bucket', type=str, default='', help='gsutil bucket') parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
parser.add_argument('--cache-images', action='store_true', help='cache images for faster training') parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training') parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
parser.add_argument('--name', default='', help='renames experiment folder exp{N} to exp{N}_{name} if supplied')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%') parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset') parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset')
parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer') parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')
parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode') parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify') parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')
parser.add_argument('--logdir', type=str, default='runs/', help='logging directory') parser.add_argument('--logdir', type=str, default='runs/train', help='logging directory')
parser.add_argument('--name', default='', help='name to append to --save-dir: i.e. runs/{N} -> runs/{N}_{name}')
parser.add_argument('--log-imgs', type=int, default=10, help='number of images for W&B logging, max 100') parser.add_argument('--log-imgs', type=int, default=10, help='number of images for W&B logging, max 100')
parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers') parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')
...@@ -428,7 +428,7 @@ if __name__ == '__main__': ...@@ -428,7 +428,7 @@ if __name__ == '__main__':
# Resume # Resume
if opt.resume: # resume an interrupted run if opt.resume: # resume an interrupted run
ckpt = opt.resume if isinstance(opt.resume, str) else get_latest_run() # specified or most recent path ckpt = opt.resume if isinstance(opt.resume, str) else get_latest_run() # specified or most recent path
log_dir = Path(ckpt).parent.parent # runs/exp0 log_dir = Path(ckpt).parent.parent # runs/train/exp0
assert os.path.isfile(ckpt), 'ERROR: --resume checkpoint does not exist' assert os.path.isfile(ckpt), 'ERROR: --resume checkpoint does not exist'
with open(log_dir / 'opt.yaml') as f: with open(log_dir / 'opt.yaml') as f:
opt = argparse.Namespace(**yaml.load(f, Loader=yaml.FullLoader)) # replace opt = argparse.Namespace(**yaml.load(f, Loader=yaml.FullLoader)) # replace
...@@ -467,14 +467,13 @@ if __name__ == '__main__': ...@@ -467,14 +467,13 @@ if __name__ == '__main__':
if opt.global_rank in [-1, 0]: if opt.global_rank in [-1, 0]:
# Tensorboard # Tensorboard
logger.info(f'Start Tensorboard with "tensorboard --logdir {opt.logdir}", view at http://localhost:6006/') logger.info(f'Start Tensorboard with "tensorboard --logdir {opt.logdir}", view at http://localhost:6006/')
tb_writer = SummaryWriter(log_dir=log_dir) # runs/exp0 tb_writer = SummaryWriter(log_dir=log_dir) # runs/train/exp0
# W&B # W&B
try: try:
import wandb import wandb
assert os.environ.get('WANDB_DISABLED') != 'true' assert os.environ.get('WANDB_DISABLED') != 'true'
logger.info("Weights & Biases logging enabled, to disable set os.environ['WANDB_DISABLED'] = 'true'")
except (ImportError, AssertionError): except (ImportError, AssertionError):
opt.log_imgs = 0 opt.log_imgs = 0
logger.info("Install Weights & Biases for experiment logging via 'pip install wandb' (recommended)") logger.info("Install Weights & Biases for experiment logging via 'pip install wandb' (recommended)")
......
...@@ -596,22 +596,22 @@ ...@@ -596,22 +596,22 @@
} }
}, },
"source": [ "source": [
"!python detect.py --weights yolov5s.pt --img 640 --conf 0.25 --source inference/images/\n", "!python detect.py --weights yolov5s.pt --img 640 --conf 0.25 --source data/images/\n",
"Image(filename='inference/output/zidane.jpg', width=600)" "Image(filename='runs/detect/exp0/zidane.jpg', width=600)"
], ],
"execution_count": null, "execution_count": null,
"outputs": [ "outputs": [
{ {
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"Namespace(agnostic_nms=False, augment=False, classes=None, conf_thres=0.25, device='', img_size=640, iou_thres=0.45, save_conf=False, save_dir='inference/output', save_txt=False, source='inference/images/', update=False, view_img=False, weights=['yolov5s.pt'])\n", "Namespace(agnostic_nms=False, augment=False, classes=None, conf_thres=0.25, device='', img_size=640, iou_thres=0.45, save_conf=False, save_dir='runs/detect', save_txt=False, source='data/images/', update=False, view_img=False, weights=['yolov5s.pt'])\n",
"Using CUDA device0 _CudaDeviceProperties(name='Tesla V100-SXM2-16GB', total_memory=16130MB)\n", "Using CUDA device0 _CudaDeviceProperties(name='Tesla V100-SXM2-16GB', total_memory=16130MB)\n",
"\n", "\n",
"Fusing layers... \n", "Fusing layers... \n",
"Model Summary: 140 layers, 7.45958e+06 parameters, 0 gradients\n", "Model Summary: 140 layers, 7.45958e+06 parameters, 0 gradients\n",
"image 1/2 /content/yolov5/inference/images/bus.jpg: 640x480 4 persons, 1 buss, 1 skateboards, Done. (0.012s)\n", "image 1/2 /content/yolov5/data/images/bus.jpg: 640x480 4 persons, 1 buss, 1 skateboards, Done. (0.012s)\n",
"image 2/2 /content/yolov5/inference/images/zidane.jpg: 384x640 2 persons, 2 ties, Done. (0.012s)\n", "image 2/2 /content/yolov5/data/images/zidane.jpg: 384x640 2 persons, 2 ties, Done. (0.012s)\n",
"Results saved to inference/output\n", "Results saved to runs/detect/exp0\n",
"Done. (0.113s)\n" "Done. (0.113s)\n"
], ],
"name": "stdout" "name": "stdout"
...@@ -640,7 +640,7 @@ ...@@ -640,7 +640,7 @@
"id": "4qbaa3iEcrcE" "id": "4qbaa3iEcrcE"
}, },
"source": [ "source": [
"Results are saved to `inference/output`. A full list of available inference sources:\n", "Results are saved to `runs/detect`. A full list of available inference sources:\n",
"<img src=\"https://user-images.githubusercontent.com/26833433/98274798-2b7a7a80-1f94-11eb-91a4-70c73593e26b.jpg\" width=\"900\"> " "<img src=\"https://user-images.githubusercontent.com/26833433/98274798-2b7a7a80-1f94-11eb-91a4-70c73593e26b.jpg\" width=\"900\"> "
] ]
}, },
...@@ -887,7 +887,7 @@ ...@@ -887,7 +887,7 @@
"source": [ "source": [
"Train a YOLOv5s model on [COCO128](https://www.kaggle.com/ultralytics/coco128) with dataset `--data coco128.yaml`, starting from pretrained `--weights yolov5s.pt`, or from randomly initialized `--weights '' --cfg yolov5s.yaml`. Models are downloaded automatically from the [latest YOLOv5 release](https://github.com/ultralytics/yolov5/releases), and **COCO, COCO128, and VOC datasets are downloaded automatically** on first use.\n", "Train a YOLOv5s model on [COCO128](https://www.kaggle.com/ultralytics/coco128) with dataset `--data coco128.yaml`, starting from pretrained `--weights yolov5s.pt`, or from randomly initialized `--weights '' --cfg yolov5s.yaml`. Models are downloaded automatically from the [latest YOLOv5 release](https://github.com/ultralytics/yolov5/releases), and **COCO, COCO128, and VOC datasets are downloaded automatically** on first use.\n",
"\n", "\n",
"All training results are saved to `runs/exp0` for the first experiment, then `runs/exp1`, `runs/exp2` etc. for subsequent experiments.\n" "All training results are saved to `runs/train/exp0` for the first experiment, then `runs/exp1`, `runs/exp2` etc. for subsequent experiments.\n"
] ]
}, },
{ {
...@@ -969,7 +969,7 @@ ...@@ -969,7 +969,7 @@
"Analyzing anchors... anchors/target = 4.26, Best Possible Recall (BPR) = 0.9946\n", "Analyzing anchors... anchors/target = 4.26, Best Possible Recall (BPR) = 0.9946\n",
"Image sizes 640 train, 640 test\n", "Image sizes 640 train, 640 test\n",
"Using 2 dataloader workers\n", "Using 2 dataloader workers\n",
"Logging results to runs/exp0\n", "Logging results to runs/train/exp0\n",
"Starting training for 3 epochs...\n", "Starting training for 3 epochs...\n",
"\n", "\n",
" Epoch gpu_mem box obj cls total targets img_size\n", " Epoch gpu_mem box obj cls total targets img_size\n",
...@@ -986,8 +986,8 @@ ...@@ -986,8 +986,8 @@
" 2/2 3.17G 0.04445 0.06545 0.01666 0.1266 149 640: 100% 8/8 [00:01<00:00, 4.33it/s]\n", " 2/2 3.17G 0.04445 0.06545 0.01666 0.1266 149 640: 100% 8/8 [00:01<00:00, 4.33it/s]\n",
" Class Images Targets P R mAP@.5 mAP@.5:.95: 100% 8/8 [00:02<00:00, 2.78it/s]\n", " Class Images Targets P R mAP@.5 mAP@.5:.95: 100% 8/8 [00:02<00:00, 2.78it/s]\n",
" all 128 929 0.395 0.766 0.701 0.455\n", " all 128 929 0.395 0.766 0.701 0.455\n",
"Optimizer stripped from runs/exp0/weights/last.pt, 15.2MB\n", "Optimizer stripped from runs/train/exp0/weights/last.pt, 15.2MB\n",
"Optimizer stripped from runs/exp0/weights/best.pt, 15.2MB\n", "Optimizer stripped from runs/train/exp0/weights/best.pt, 15.2MB\n",
"3 epochs completed in 0.005 hours.\n", "3 epochs completed in 0.005 hours.\n",
"\n" "\n"
], ],
...@@ -1030,7 +1030,7 @@ ...@@ -1030,7 +1030,7 @@
"source": [ "source": [
"## Local Logging\n", "## Local Logging\n",
"\n", "\n",
"All results are logged by default to the `runs/exp0` directory, with a new directory created for each new training as `runs/exp1`, `runs/exp2`, etc. View train and test jpgs to see mosaics, labels/predictions and augmentation effects. Note a **Mosaic Dataloader** is used for training (shown below), a new concept developed by Ultralytics and first featured in [YOLOv4](https://arxiv.org/abs/2004.10934)." "All results are logged by default to the `runs/train/exp0` directory, with a new directory created for each new training as `runs/exp1`, `runs/exp2`, etc. View train and test jpgs to see mosaics, labels/predictions and augmentation effects. Note a **Mosaic Dataloader** is used for training (shown below), a new concept developed by Ultralytics and first featured in [YOLOv4](https://arxiv.org/abs/2004.10934)."
] ]
}, },
{ {
...@@ -1039,9 +1039,9 @@ ...@@ -1039,9 +1039,9 @@
"id": "riPdhraOTCO0" "id": "riPdhraOTCO0"
}, },
"source": [ "source": [
"Image(filename='runs/exp0/train_batch0.jpg', width=800) # train batch 0 mosaics and labels\n", "Image(filename='runs/train/exp0/train_batch0.jpg', width=800) # train batch 0 mosaics and labels\n",
"Image(filename='runs/exp0/test_batch0_gt.jpg', width=800) # test batch 0 ground truth\n", "Image(filename='runs/train/exp0/test_batch0_gt.jpg', width=800) # test batch 0 ground truth\n",
"Image(filename='runs/exp0/test_batch0_pred.jpg', width=800) # test batch 0 predictions" "Image(filename='runs/train/exp0/test_batch0_pred.jpg', width=800) # test batch 0 predictions"
], ],
"execution_count": null, "execution_count": null,
"outputs": [] "outputs": []
...@@ -1078,7 +1078,7 @@ ...@@ -1078,7 +1078,7 @@
}, },
"source": [ "source": [
"from utils.utils import plot_results \n", "from utils.utils import plot_results \n",
"plot_results(save_dir='runs/exp0') # plot results.txt as results.png\n", "plot_results(save_dir='runs/train/exp0') # plot results.txt as results.png\n",
"Image(filename='results.png', width=800) " "Image(filename='results.png', width=800) "
], ],
"execution_count": null, "execution_count": null,
...@@ -1170,9 +1170,9 @@ ...@@ -1170,9 +1170,9 @@
" for di in 0 cpu # inference devices\n", " for di in 0 cpu # inference devices\n",
" do\n", " do\n",
" python detect.py --weights $x.pt --device $di # detect official\n", " python detect.py --weights $x.pt --device $di # detect official\n",
" python detect.py --weights runs/exp0/weights/last.pt --device $di # detect custom\n", " python detect.py --weights runs/train/exp0/weights/last.pt --device $di # detect custom\n",
" python test.py --weights $x.pt --device $di # test official\n", " python test.py --weights $x.pt --device $di # test official\n",
" python test.py --weights runs/exp0/weights/last.pt --device $di # test custom\n", " python test.py --weights runs/train/exp0/weights/last.pt --device $di # test custom\n",
" done\n", " done\n",
" python models/yolo.py --cfg $x.yaml # inspect\n", " python models/yolo.py --cfg $x.yaml # inspect\n",
" python models/export.py --weights $x.pt --img 640 --batch 1 # export\n", " python models/export.py --weights $x.pt --img 640 --batch 1 # export\n",
......
...@@ -955,9 +955,15 @@ def increment_dir(dir, comment=''): ...@@ -955,9 +955,15 @@ def increment_dir(dir, comment=''):
# Increments a directory runs/exp1 --> runs/exp2_comment # Increments a directory runs/exp1 --> runs/exp2_comment
n = 0 # number n = 0 # number
dir = str(Path(dir)) # os-agnostic dir = str(Path(dir)) # os-agnostic
if os.path.isdir(dir):
stem = ''
dir += os.sep # removed by Path
else:
stem = Path(dir).stem
dirs = sorted(glob.glob(dir + '*')) # directories dirs = sorted(glob.glob(dir + '*')) # directories
if dirs: if dirs:
matches = [re.search(r"exp(\d+)", d) for d in dirs] matches = [re.search(r"%s(\d+)" % stem, d) for d in dirs]
idxs = [int(m.groups()[0]) for m in matches if m] idxs = [int(m.groups()[0]) for m in matches if m]
if idxs: if idxs:
n = max(idxs) + 1 # increment n = max(idxs) + 1 # increment
...@@ -1262,7 +1268,7 @@ def plot_results_overlay(start=0, stop=0): # from utils.general import *; plot_ ...@@ -1262,7 +1268,7 @@ def plot_results_overlay(start=0, stop=0): # from utils.general import *; plot_
def plot_results(start=0, stop=0, bucket='', id=(), labels=(), save_dir=''): def plot_results(start=0, stop=0, bucket='', id=(), labels=(), save_dir=''):
# from utils.general import *; plot_results(save_dir='runs/exp0') # from utils.general import *; plot_results(save_dir='runs/train/exp0')
# Plot training 'results*.txt' as seen in https://github.com/ultralytics/yolov5#reproduce-our-training # Plot training 'results*.txt' as seen in https://github.com/ultralytics/yolov5#reproduce-our-training
fig, ax = plt.subplots(2, 5, figsize=(12, 6)) fig, ax = plt.subplots(2, 5, figsize=(12, 6))
ax = ax.ravel() ax = ax.ravel()
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论