mirror of
https://github.com/THU-MIG/yolov10.git
synced 2025-05-24 06:14:55 +08:00
Replace nosave
and noval
with save
and val
(#127)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
598f17a472
commit
63c7a74691
@ -1,71 +1,69 @@
|
|||||||
# YOLO 🚀 by Ultralytics, GPL-3.0 license
|
# YOLO 🚀 by Ultralytics, GPL-3.0 license
|
||||||
# Default training settings and hyperparameters for medium-augmentation COCO training
|
# Default training settings and hyperparameters for medium-augmentation COCO training
|
||||||
|
|
||||||
# Task and Mode
|
task: "classify" # choices=['detect', 'segment', 'classify', 'init'] # init is a special case. Specify task to run.
|
||||||
task: "classify" # choices=['detect', 'segment', 'classify', 'init'] # init is a special case
|
mode: "train" # choices=['train', 'val', 'predict'] # mode to run task in.
|
||||||
mode: "train" # choice=['train', 'val', 'predict']
|
|
||||||
|
|
||||||
# Train settings -------------------------------------------------------------------------------------------------------
|
# Train settings -------------------------------------------------------------------------------------------------------
|
||||||
model: null # i.e. yolov5s.pt, yolo.yaml
|
model: null # i.e. yolov5s.pt, yolo.yaml. Path to model file
|
||||||
data: null # i.e. coco128.yaml
|
data: null # i.e. coco128.yaml. Path to data file
|
||||||
epochs: 100
|
epochs: 100 # number of epochs to train for
|
||||||
batch_size: 16
|
batch_size: 16 # number of images per batch
|
||||||
imgsz: 640
|
imgsz: 640 # size of input images
|
||||||
nosave: False
|
save: True # save checkpoints
|
||||||
cache: False # True/ram, disk or False
|
cache: False # True/ram, disk or False. Use cache for data loading
|
||||||
device: '' # cuda device, i.e. 0 or 0,1,2,3 or cpu
|
device: '' # cuda device, i.e. 0 or 0,1,2,3 or cpu. Device to run on
|
||||||
workers: 8
|
workers: 8 # number of worker threads for data loading
|
||||||
project: null
|
project: null # project name
|
||||||
name: null
|
name: null # experiment name
|
||||||
exist_ok: False
|
exist_ok: False # whether to overwrite existing experiment
|
||||||
pretrained: False
|
pretrained: False # whether to use a pretrained model
|
||||||
optimizer: 'SGD' # choices=['SGD', 'Adam', 'AdamW', 'RMSProp']
|
optimizer: 'SGD' # optimizer to use, choices=['SGD', 'Adam', 'AdamW', 'RMSProp']
|
||||||
verbose: False
|
verbose: False # whether to print verbose output
|
||||||
seed: 0
|
seed: 0 # random seed for reproducibility
|
||||||
deterministic: True
|
deterministic: True # whether to enable deterministic mode
|
||||||
local_rank: -1
|
local_rank: -1 # local rank for distributed training
|
||||||
single_cls: False # train multi-class data as single-class
|
single_cls: False # train multi-class data as single-class
|
||||||
image_weights: False # use weighted image selection for training
|
image_weights: False # use weighted image selection for training
|
||||||
rect: False # support rectangular training
|
rect: False # support rectangular training
|
||||||
cos_lr: False # use cosine LR scheduler
|
cos_lr: False # use cosine learning rate scheduler
|
||||||
close_mosaic: 10 # disable mosaic for final 10 epochs
|
close_mosaic: 10 # disable mosaic augmentation for final 10 epochs
|
||||||
resume: False
|
resume: False # resume training from last checkpoint
|
||||||
# Segmentation
|
# Segmentation
|
||||||
overlap_mask: True # masks overlap
|
overlap_mask: True # masks should overlap during training
|
||||||
mask_ratio: 4 # mask downsample ratio
|
mask_ratio: 4 # mask downsample ratio
|
||||||
# Classification
|
# Classification
|
||||||
dropout: False # use dropout
|
dropout: False # use dropout regularization
|
||||||
|
|
||||||
|
|
||||||
# Val/Test settings ----------------------------------------------------------------------------------------------------
|
# Val/Test settings ----------------------------------------------------------------------------------------------------
|
||||||
noval: False
|
val: True # validate/test during training
|
||||||
save_json: False
|
save_json: False # save results to JSON file
|
||||||
save_hybrid: False
|
save_hybrid: False # save hybrid version of labels (labels + additional predictions)
|
||||||
conf_thres: 0.001
|
conf_thres: 0.001 # object confidence threshold for detection
|
||||||
iou_thres: 0.7
|
iou_thres: 0.7 # intersection over union threshold for NMS
|
||||||
max_det: 300
|
max_det: 300 # maximum number of detections per image
|
||||||
half: False
|
half: False # use half precision (FP16)
|
||||||
dnn: False # use OpenCV DNN for ONNX inference
|
dnn: False # use OpenCV DNN for ONNX inference
|
||||||
plots: True
|
plots: True # show plots during training
|
||||||
|
|
||||||
# Prediction settings --------------------------------------------------------------------------------------------------
|
# Prediction settings --------------------------------------------------------------------------------------------------
|
||||||
source: "ultralytics/assets/"
|
source: "ultralytics/assets" # source directory for images or videos
|
||||||
view_img: False
|
show: False # show results if possible
|
||||||
save_txt: False
|
save_txt: False # save results as .txt file
|
||||||
save_conf: False
|
save_conf: False # save results with confidence scores
|
||||||
save_crop: False
|
save_crop: False # save cropped images with results
|
||||||
hide_labels: False # hide labels
|
hide_labels: False # hide labels
|
||||||
hide_conf: False
|
hide_conf: False # hide confidence scores
|
||||||
vid_stride: 1 # video frame-rate stride
|
vid_stride: 1 # video frame-rate stride
|
||||||
line_thickness: 3 # bounding box thickness (pixels)
|
line_thickness: 3 # bounding box thickness (pixels)
|
||||||
update: False # Update all models
|
update: False # Update all models
|
||||||
visualize: False
|
visualize: False # visualize results
|
||||||
augment: False
|
augment: False # apply data augmentation to images
|
||||||
agnostic_nms: False # class-agnostic NMS
|
agnostic_nms: False # class-agnostic NMS
|
||||||
retina_masks: False
|
retina_masks: False # use retina masks for object detection
|
||||||
|
|
||||||
# Export settings ------------------------------------------------------------------------------------------------------
|
# Export settings ------------------------------------------------------------------------------------------------------
|
||||||
format: torchscript
|
format: torchscript # format to export to
|
||||||
keras: False # use Keras
|
keras: False # use Keras
|
||||||
optimize: False # TorchScript: optimize for mobile
|
optimize: False # TorchScript: optimize for mobile
|
||||||
int8: False # CoreML/TF INT8 quantization
|
int8: False # CoreML/TF INT8 quantization
|
||||||
@ -103,11 +101,11 @@ mosaic: 1.0 # image mosaic (probability)
|
|||||||
mixup: 0.0 # image mixup (probability)
|
mixup: 0.0 # image mixup (probability)
|
||||||
copy_paste: 0.0 # segment copy-paste (probability)
|
copy_paste: 0.0 # segment copy-paste (probability)
|
||||||
|
|
||||||
# For debugging. Don't change
|
|
||||||
v5loader: False
|
|
||||||
|
|
||||||
# Hydra configs --------------------------------------------------------------------------------------------------------
|
# Hydra configs --------------------------------------------------------------------------------------------------------
|
||||||
hydra:
|
hydra:
|
||||||
output_subdir: null # disable hydra directory creation
|
output_subdir: null # disable hydra directory creation
|
||||||
run:
|
run:
|
||||||
dir: .
|
dir: .
|
||||||
|
|
||||||
|
# Debug, do not modify -------------------------------------------------------------------------------------------------
|
||||||
|
v5loader: False # use legacy YOLOv5 dataloader
|
||||||
|
@ -67,7 +67,7 @@ def build_dataloader(cfg, batch_size, img_path, stride=32, label_path=None, rank
|
|||||||
augment=mode == "train", # augmentation
|
augment=mode == "train", # augmentation
|
||||||
hyp=cfg, # TODO: probably add a get_hyps_from_cfg function
|
hyp=cfg, # TODO: probably add a get_hyps_from_cfg function
|
||||||
rect=cfg.rect if mode == "train" else True, # rectangular batches
|
rect=cfg.rect if mode == "train" else True, # rectangular batches
|
||||||
cache=None if cfg.noval else cfg.get("cache", None),
|
cache=cfg.get("cache", None),
|
||||||
single_cls=cfg.get("single_cls", False),
|
single_cls=cfg.get("single_cls", False),
|
||||||
stride=int(stride),
|
stride=int(stride),
|
||||||
pad=0.0 if mode == "train" else 0.5,
|
pad=0.0 if mode == "train" else 0.5,
|
||||||
|
@ -104,7 +104,6 @@ class BasePredictor:
|
|||||||
def setup(self, source=None, model=None):
|
def setup(self, source=None, model=None):
|
||||||
# source
|
# source
|
||||||
source = str(source or self.args.source)
|
source = str(source or self.args.source)
|
||||||
self.save_img = not self.args.nosave and not source.endswith('.txt')
|
|
||||||
is_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)
|
is_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)
|
||||||
is_url = source.lower().startswith(('rtsp://', 'rtmp://', 'http://', 'https://'))
|
is_url = source.lower().startswith(('rtsp://', 'rtmp://', 'http://', 'https://'))
|
||||||
webcam = source.isnumeric() or source.endswith('.streams') or (is_url and not is_file)
|
webcam = source.isnumeric() or source.endswith('.streams') or (is_url and not is_file)
|
||||||
@ -168,10 +167,10 @@ class BasePredictor:
|
|||||||
p = Path(path)
|
p = Path(path)
|
||||||
s += self.write_results(i, preds, (p, im, im0s))
|
s += self.write_results(i, preds, (p, im, im0s))
|
||||||
|
|
||||||
if self.args.view_img:
|
if self.args.show:
|
||||||
self.show(p)
|
self.show(p)
|
||||||
|
|
||||||
if self.save_img:
|
if self.args.save:
|
||||||
self.save_preds(vid_cap, i, str(self.save_dir / p.name))
|
self.save_preds(vid_cap, i, str(self.save_dir / p.name))
|
||||||
|
|
||||||
# Print time (inference-only)
|
# Print time (inference-only)
|
||||||
@ -182,7 +181,7 @@ class BasePredictor:
|
|||||||
LOGGER.info(
|
LOGGER.info(
|
||||||
f'Speed: %.1fms pre-process, %.1fms inference, %.1fms postprocess per image at shape {(1, 3, *self.imgsz)}'
|
f'Speed: %.1fms pre-process, %.1fms inference, %.1fms postprocess per image at shape {(1, 3, *self.imgsz)}'
|
||||||
% t)
|
% t)
|
||||||
if self.args.save_txt or self.save_img:
|
if self.args.save_txt or self.args.save:
|
||||||
s = f"\n{len(list(self.save_dir.glob('labels/*.txt')))} labels saved to {self.save_dir / 'labels'}" if self.args.save_txt else ''
|
s = f"\n{len(list(self.save_dir.glob('labels/*.txt')))} labels saved to {self.save_dir / 'labels'}" if self.args.save_txt else ''
|
||||||
LOGGER.info(f"Results saved to {colorstr('bold', self.save_dir)}{s}")
|
LOGGER.info(f"Results saved to {colorstr('bold', self.save_dir)}{s}")
|
||||||
|
|
||||||
|
@ -244,12 +244,12 @@ class BaseTrainer:
|
|||||||
for i, batch in pbar:
|
for i, batch in pbar:
|
||||||
self.trigger_callbacks("on_train_batch_start")
|
self.trigger_callbacks("on_train_batch_start")
|
||||||
|
|
||||||
# update dataloader attributes (optional)
|
# Update dataloader attributes (optional)
|
||||||
if epoch == (self.epochs - self.args.close_mosaic) and hasattr(self.train_loader.dataset, 'mosaic'):
|
if epoch == (self.epochs - self.args.close_mosaic) and hasattr(self.train_loader.dataset, 'mosaic'):
|
||||||
LOGGER.info("Closing dataloader mosaic")
|
LOGGER.info("Closing dataloader mosaic")
|
||||||
self.train_loader.dataset.mosaic = False
|
self.train_loader.dataset.mosaic = False
|
||||||
|
|
||||||
# warmup
|
# Warmup
|
||||||
ni = i + nb * epoch
|
ni = i + nb * epoch
|
||||||
if ni <= nw:
|
if ni <= nw:
|
||||||
xi = [0, nw] # x interp
|
xi = [0, nw] # x interp
|
||||||
@ -261,7 +261,7 @@ class BaseTrainer:
|
|||||||
if 'momentum' in x:
|
if 'momentum' in x:
|
||||||
x['momentum'] = np.interp(ni, xi, [self.args.warmup_momentum, self.args.momentum])
|
x['momentum'] = np.interp(ni, xi, [self.args.warmup_momentum, self.args.momentum])
|
||||||
|
|
||||||
# forward
|
# Forward
|
||||||
with torch.cuda.amp.autocast(self.amp):
|
with torch.cuda.amp.autocast(self.amp):
|
||||||
batch = self.preprocess_batch(batch)
|
batch = self.preprocess_batch(batch)
|
||||||
preds = self.model(batch["img"])
|
preds = self.model(batch["img"])
|
||||||
@ -271,15 +271,15 @@ class BaseTrainer:
|
|||||||
self.tloss = (self.tloss * i + self.loss_items) / (i + 1) if self.tloss is not None \
|
self.tloss = (self.tloss * i + self.loss_items) / (i + 1) if self.tloss is not None \
|
||||||
else self.loss_items
|
else self.loss_items
|
||||||
|
|
||||||
# backward
|
# Backward
|
||||||
self.scaler.scale(self.loss).backward()
|
self.scaler.scale(self.loss).backward()
|
||||||
|
|
||||||
# optimize - https://pytorch.org/docs/master/notes/amp_examples.html
|
# Optimize - https://pytorch.org/docs/master/notes/amp_examples.html
|
||||||
if ni - last_opt_step >= self.accumulate:
|
if ni - last_opt_step >= self.accumulate:
|
||||||
self.optimizer_step()
|
self.optimizer_step()
|
||||||
last_opt_step = ni
|
last_opt_step = ni
|
||||||
|
|
||||||
# log
|
# Log
|
||||||
mem = f'{torch.cuda.memory_reserved() / 1E9 if torch.cuda.is_available() else 0:.3g}G' # (GB)
|
mem = f'{torch.cuda.memory_reserved() / 1E9 if torch.cuda.is_available() else 0:.3g}G' # (GB)
|
||||||
loss_len = self.tloss.shape[0] if len(self.tloss.size()) else 1
|
loss_len = self.tloss.shape[0] if len(self.tloss.size()) else 1
|
||||||
losses = self.tloss if loss_len > 1 else torch.unsqueeze(self.tloss, 0)
|
losses = self.tloss if loss_len > 1 else torch.unsqueeze(self.tloss, 0)
|
||||||
@ -298,17 +298,17 @@ class BaseTrainer:
|
|||||||
self.trigger_callbacks("on_train_epoch_end")
|
self.trigger_callbacks("on_train_epoch_end")
|
||||||
|
|
||||||
if rank in {-1, 0}:
|
if rank in {-1, 0}:
|
||||||
# validation
|
# Validation
|
||||||
self.trigger_callbacks('on_val_start')
|
self.trigger_callbacks('on_val_start')
|
||||||
self.ema.update_attr(self.model, include=['yaml', 'nc', 'args', 'names', 'stride', 'class_weights'])
|
self.ema.update_attr(self.model, include=['yaml', 'nc', 'args', 'names', 'stride', 'class_weights'])
|
||||||
final_epoch = (epoch + 1 == self.epochs)
|
final_epoch = (epoch + 1 == self.epochs)
|
||||||
if not self.args.noval or final_epoch:
|
if self.args.val or final_epoch:
|
||||||
self.metrics, self.fitness = self.validate()
|
self.metrics, self.fitness = self.validate()
|
||||||
self.trigger_callbacks('on_val_end')
|
self.trigger_callbacks('on_val_end')
|
||||||
self.save_metrics(metrics={**self.label_loss_items(self.tloss), **self.metrics, **lr})
|
self.save_metrics(metrics={**self.label_loss_items(self.tloss), **self.metrics, **lr})
|
||||||
|
|
||||||
# save model
|
# Save model
|
||||||
if (not self.args.nosave) or (epoch + 1 == self.epochs):
|
if self.args.save or (epoch + 1 == self.epochs):
|
||||||
self.save_model()
|
self.save_model()
|
||||||
self.trigger_callbacks('on_model_save')
|
self.trigger_callbacks('on_model_save')
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ class BaseTrainer:
|
|||||||
# TODO: termination condition
|
# TODO: termination condition
|
||||||
|
|
||||||
if rank in {-1, 0}:
|
if rank in {-1, 0}:
|
||||||
# do the last evaluation with best.pt
|
# Do final val with best.pt
|
||||||
self.log(f'\n{epoch - self.start_epoch + 1} epochs completed in '
|
self.log(f'\n{epoch - self.start_epoch + 1} epochs completed in '
|
||||||
f'{(time.time() - self.train_time_start) / 3600:.3f} hours.')
|
f'{(time.time() - self.train_time_start) / 3600:.3f} hours.')
|
||||||
self.final_eval()
|
self.final_eval()
|
||||||
|
@ -43,7 +43,7 @@ class ClassificationPredictor(BasePredictor):
|
|||||||
|
|
||||||
# write
|
# write
|
||||||
text = '\n'.join(f'{prob[j]:.2f} {self.model.names[j]}' for j in top5i)
|
text = '\n'.join(f'{prob[j]:.2f} {self.model.names[j]}' for j in top5i)
|
||||||
if self.save_img or self.args.view_img: # Add bbox to image
|
if self.args.save or self.args.show: # Add bbox to image
|
||||||
self.annotator.text((32, 32), text, txt_color=(255, 255, 255))
|
self.annotator.text((32, 32), text, txt_color=(255, 255, 255))
|
||||||
if self.args.save_txt: # Write to file
|
if self.args.save_txt: # Write to file
|
||||||
with open(f'{self.txt_path}.txt', 'a') as f:
|
with open(f'{self.txt_path}.txt', 'a') as f:
|
||||||
|
@ -66,7 +66,7 @@ class DetectionPredictor(BasePredictor):
|
|||||||
with open(f'{self.txt_path}.txt', 'a') as f:
|
with open(f'{self.txt_path}.txt', 'a') as f:
|
||||||
f.write(('%g ' * len(line)).rstrip() % line + '\n')
|
f.write(('%g ' * len(line)).rstrip() % line + '\n')
|
||||||
|
|
||||||
if self.save_img or self.args.save_crop or self.args.view_img: # Add bbox to image
|
if self.args.save or self.args.save_crop or self.args.show: # Add bbox to image
|
||||||
c = int(cls) # integer class
|
c = int(cls) # integer class
|
||||||
label = None if self.args.hide_labels else (
|
label = None if self.args.hide_labels else (
|
||||||
self.model.names[c] if self.args.hide_conf else f'{self.model.names[c]} {conf:.2f}')
|
self.model.names[c] if self.args.hide_conf else f'{self.model.names[c]} {conf:.2f}')
|
||||||
|
@ -81,7 +81,7 @@ class SegmentationPredictor(DetectionPredictor):
|
|||||||
with open(f'{self.txt_path}.txt', 'a') as f:
|
with open(f'{self.txt_path}.txt', 'a') as f:
|
||||||
f.write(('%g ' * len(line)).rstrip() % line + '\n')
|
f.write(('%g ' * len(line)).rstrip() % line + '\n')
|
||||||
|
|
||||||
if self.save_img or self.args.save_crop or self.args.view_img:
|
if self.args.save or self.args.save_crop or self.args.show:
|
||||||
c = int(cls) # integer class
|
c = int(cls) # integer class
|
||||||
label = None if self.args.hide_labels else (
|
label = None if self.args.hide_labels else (
|
||||||
self.model.names[c] if self.args.hide_conf else f'{self.model.names[c]} {conf:.2f}')
|
self.model.names[c] if self.args.hide_conf else f'{self.model.names[c]} {conf:.2f}')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user