import argparse
import logging
import math
import os
import random
import time
from pathlib import Path
from warnings import warn
import numpy as np
import torch
if torch.__version__ >= '1.8':
import torch_npu
import torch.distributed as dist
import torch.nn.functional as F
import torch.optim as optim
import torch.optim.lr_scheduler as lr_scheduler
import torch.utils.data
import yaml
from torch.nn.parallel import DistributedDataParallel as DDP
from torch.utils.tensorboard import SummaryWriter
import torch.multiprocessing as mp
import test
from models.models import *
from utils.autoanchor import check_anchors
from utils.datasets import create_dataloader
from utils.general import labels_to_class_weights, increment_path, labels_to_image_weights, init_seeds, \
fitness, fitness_p, fitness_r, fitness_ap50, fitness_ap, fitness_f, strip_optimizer, get_latest_run,\
check_dataset, check_file, check_git_status, check_img_size, print_mutation, set_logging
from utils.google_utils import attempt_download
from utils.loss import compute_loss
from utils.plots import plot_images, plot_labels, plot_results, plot_evolution, output_to_target
from utils.torch_utils import ModelEMA, select_device, intersect_dicts, torch_distributed_zero_first
logger = logging.getLogger(__name__)
mixed_precision = True
try:
import apex
from apex import amp
except:
print('Apex recommended for faster mixed precision training: https://github.com/NVIDIA/apex')
mixed_precision = False
use_wandb = False
if use_wandb:
try:
import wandb
except:
print("Install Weights & Biases for experiment logging via 'pip install wandb' (recommended)")
else:
wandb = None
def train(hyp, opt, device, tb_writer=None, wandb=None):
print(f'Hyperparameters {hyp}')
save_dir, epochs, batch_size, total_batch_size, weights, rank = \
Path(opt.save_dir), opt.epochs, opt.batch_size, opt.total_batch_size, opt.weights, opt.local_rank
wdir = save_dir / 'weights'
wdir.mkdir(parents=True, exist_ok=True)
last = wdir / 'last.pt'
best = wdir / 'best.pt'
results_file = save_dir / 'results.txt'
with open(save_dir / 'hyp.yaml', 'w') as f:
yaml.dump(hyp, f, sort_keys=False)
with open(save_dir / 'opt.yaml', 'w') as f:
yaml.dump(vars(opt), f, sort_keys=False)
plots = not opt.evolve
cuda = device.type != 'cpu'
init_seeds(2 + rank)
with open(opt.data) as f:
data_dict = yaml.load(f, Loader=yaml.FullLoader)
with torch_distributed_zero_first(rank):
check_dataset(data_dict)
train_path = data_dict['train']
test_path = data_dict['val']
nc, names = (1, ['item']) if opt.single_cls else (int(data_dict['nc']), data_dict['names'])
assert len(names) == nc, '%g names found for nc=%g dataset in %s' % (len(names), nc, opt.data)
pretrained = weights.endswith('.pt')
if pretrained:
with torch_distributed_zero_first(rank):
attempt_download(weights)
ckpt = torch.load(weights, map_location=device)
model = Darknet(opt.cfg).to(device)
state_dict = {k: v for k, v in ckpt['model'].items() if model.state_dict()[k].numel() == v.numel()}
model.load_state_dict(state_dict, strict=False)
print('Transferred %g/%g items from %s' % (len(state_dict), len(model.state_dict()), weights))
else:
model = Darknet(opt.cfg).to(device)
gs = 64
imgsz, imgsz_test = [check_img_size(x, gs) for x in opt.img_size]
nbs = 64
accumulate = max(round(nbs / total_batch_size), 1)
hyp['weight_decay'] *= total_batch_size * accumulate / nbs
pg0, pg1, pg2 = [], [], []
for k, v in dict(model.named_parameters()).items():
if '.bias' in k:
pg2.append(v)
elif 'Conv2d.weight' in k:
pg1.append(v)
elif 'm.weight' in k:
pg1.append(v)
elif 'w.weight' in k:
pg1.append(v)
else:
pg0.append(v)
if opt.adam:
optimizer = optim.Adam(pg0, lr=hyp['lr0'], betas=(hyp['momentum'], 0.999))
else:
if device.type == 'npu':
optimizer = apex.optimizers.NpuFusedSGD(pg0, lr=hyp['lr0'], momentum=hyp['momentum'], nesterov=True)
else:
optimizer = optim.SGD(pg0, lr=hyp['lr0'], momentum=hyp['momentum'], nesterov=True)
optimizer.add_param_group({'params': pg1, 'weight_decay': hyp['weight_decay']})
optimizer.add_param_group({'params': pg2})
print('Optimizer groups: %g .bias, %g conv.weight, %g other' % (len(pg2), len(pg1), len(pg0)))
del pg0, pg1, pg2
if wandb and wandb.run is None:
opt.hyp = hyp
wandb_run = wandb.init(config=opt, resume="allow",
project='YOLOR' if opt.project == 'runs/train' else Path(opt.project).stem,
name=save_dir.stem,
id=ckpt.get('wandb_id') if 'ckpt' in locals() else None)
start_epoch = 0
if pretrained:
if ckpt['optimizer'] is not None:
optimizer.load_state_dict(ckpt['optimizer'])
if ckpt.get('training_results') is not None:
with open(results_file, 'w') as file:
file.write(ckpt['training_results'])
start_epoch = ckpt['epoch'] + 1
if opt.resume:
assert start_epoch > 0, '%s training to %g epochs is finished, nothing to resume.' % (weights, epochs)
if epochs < start_epoch:
print('%s has been trained for %g epochs. Fine-tuning for %g additional epochs.' %
(weights, ckpt['epoch'], epochs))
epochs += ckpt['epoch']
del ckpt, state_dict
if mixed_precision:
if device.type == 'npu':
model, optimizer = amp.initialize(model, optimizer, opt_level='O1', verbosity=0, loss_scale=64, combine_grad=True)
else:
model, optimizer = amp.initialize(model, optimizer, opt_level='O1', verbosity=0, loss_scale=64)
lf = lambda x: ((1 + math.cos(x * math.pi / epochs)) / 2) * (1 - hyp['lrf']) + hyp['lrf']
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lf)
if opt.sync_bn and cuda and rank != -1:
model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(model).to(device)
print('Using SyncBatchNorm()')
ema = ModelEMA(model) if rank in [-1, 0] else None
if device.type == 'cuda' and rank != -1:
model = DDP(model, device_ids=[rank], output_device=rank)
elif device.type == 'npu' and rank != -1:
model = DDP(model, device_ids=[rank], broadcast_buffers=False)
dataloader, dataset = create_dataloader(train_path, imgsz, batch_size, gs, opt,
hyp=hyp, augment=True, cache=opt.cache_images, rect=opt.rect,
rank=rank, world_size=opt.world_size, workers=opt.workers)
mlc = np.concatenate(dataset.labels, 0)[:, 0].max()
nb = len(dataloader)
assert mlc < nc, 'Label class %g exceeds nc=%g in %s. Possible class labels are 0-%g' % (mlc, nc, opt.data, nc - 1)
hyp['cls'] *= nc / 80.
model.nc = nc
model.hyp = hyp
model.gr = 1.0
model.class_weights = labels_to_class_weights(dataset.labels, nc).to(device)
model.names = names
if rank in [-1, 0]:
ema.updates = start_epoch * nb // accumulate
testloader = create_dataloader(test_path, imgsz_test, batch_size*2, gs, opt,
hyp=hyp, cache=opt.cache_images and not opt.notest, rect=True,
rank=-1, world_size=opt.world_size, workers=opt.workers)[0]
if not opt.resume:
labels = np.concatenate(dataset.labels, 0)
c = torch.tensor(labels[:, 0])
if plots:
plot_labels(labels, save_dir=save_dir)
if tb_writer:
tb_writer.add_histogram('classes', c, 0)
if wandb:
wandb.log({"Labels": [wandb.Image(str(x), caption=x.name) for x in save_dir.glob('*labels*.png')]})
t0 = time.time()
nw = max(round(hyp['warmup_epochs'] * nb), 1000)
maps = np.zeros(nc)
results = (0, 0, 0, 0, 0, 0, 0)
scheduler.last_epoch = start_epoch - 1
if rank in [0, -1]:
print('Image sizes %g train, %g test\n'
'Using %g dataloader workers\nLogging results to %s\n'
'Starting training for %g epochs...' % (imgsz, imgsz_test, dataloader.num_workers, save_dir, epochs))
for epoch in range(start_epoch, epochs):
model.train()
if opt.image_weights:
if rank in [-1, 0]:
cw = model.class_weights.cpu().numpy() * (1 - maps) ** 2
iw = labels_to_image_weights(dataset.labels, nc=nc, class_weights=cw)
dataset.indices = random.choices(range(dataset.n), weights=iw, k=dataset.n)
if rank != -1:
indices = (torch.tensor(dataset.indices) if rank == 0 else torch.zeros(dataset.n)).int()
dist.broadcast(indices, 0)
if rank != 0:
dataset.indices = indices.cpu().numpy()
mloss = torch.zeros(4, device=device)
if rank != -1:
dataloader.sampler.set_epoch(epoch)
optimizer.zero_grad()
start_time = time.time()
d_1 = time.time()
PERF_MAX_STEPS = os.environ.get("PERF_MAX_STEPS", None)
for i, (imgs, targets, paths, _) in enumerate(dataloader):
t_time = time.time()
d_time = t_time - d_1
ni = i + nb * epoch
imgs = imgs.to(device, non_blocking=True).float() / 255.0
if ni <= nw:
xi = [0, nw]
accumulate = max(1, np.interp(ni, xi, [1, nbs / total_batch_size]).round())
for j, x in enumerate(optimizer.param_groups):
x['lr'] = np.interp(ni, xi, [hyp['warmup_bias_lr'] if j == 2 else 0.0, x['initial_lr'] * lf(epoch)])
if 'momentum' in x:
x['momentum'] = np.interp(ni, xi, [hyp['warmup_momentum'], hyp['momentum']])
if opt.multi_scale:
sz = random.randrange(imgsz * 0.5, imgsz * 1.5 + gs) // gs * gs
sf = sz / max(imgs.shape[2:])
if sf != 1:
ns = [math.ceil(x * sf / gs) * gs for x in imgs.shape[2:]]
imgs = F.interpolate(imgs, size=ns, mode='bilinear', align_corners=False)
pred = model(imgs)
loss, loss_items = compute_loss(pred, targets.to(device), model)
if rank != -1:
loss *= opt.world_size
if not torch.isfinite(loss):
print('WARNING: non-finite loss, ending training ', loss_items)
return results
if mixed_precision:
with amp.scale_loss(loss, optimizer) as scaled_loss:
scaled_loss.backward()
else:
loss.backward()
if ni % accumulate == 0:
optimizer.step()
optimizer.zero_grad()
if ema is not None:
x = torch.tensor([1.]).to(device)
if device.type == 'npu':
params_fp32_fused = optimizer.get_model_combined_params()
ema.update(model, x, params_fp32_fused[0])
else:
ema.update(model, x)
if i <= 10:
sum_time = (time.time() - start_time) / (i + 1)
if i == 10:
start_time = time.time()
else:
sum_time = (time.time() - start_time) / (i - 10)
ptime = time.time() - d_1
if rank in [-1, 0]:
mloss = (mloss * i + loss_items) / (i + 1)
mem = '%.3gG' % (torch.cuda.memory_cached() / 1E9 if torch.cuda.is_available() else 0)
s = ('%10s' * 2 + '%10.4g' * 6) % (
'%g/%g' % (epoch, epochs - 1), mem, *mloss, targets.shape[0], imgs.shape[-1])
print(
'Epoch:[%2g][%4g/%4g][%s][FPS:%3.1f][mTime:%3.3f][pTime:%3.3f][dTime:%3.3f] GIoU:%.3f objectness:%.3f classfication:%.3f totalLoss:%.3f' % (
epoch, i, nb, device, opt.total_batch_size / sum_time, sum_time, ptime, d_time, *mloss))
if plots and ni < 3:
f = save_dir / f'train_batch{ni}.jpg'
plot_images(images=imgs, targets=targets, paths=paths, fname=f)
elif plots and ni == 3 and wandb:
wandb.log({"Mosaics": [wandb.Image(str(x), caption=x.name) for x in save_dir.glob('train*.jpg')]})
if PERF_MAX_STEPS and i > int(PERF_MAX_STEPS):
break
d_1 = time.time()
lr = [x['lr'] for x in optimizer.param_groups]
scheduler.step()
if rank in [-1, 0]:
if ema:
ema.update_attr(model)
final_epoch = epoch + 1 == epochs
if False:
results, maps, _ = test.test(opt.data,
batch_size=batch_size*2,
imgsz=imgsz_test,
model=ema.ema.module if hasattr(ema.ema, 'module') else ema.ema,
single_cls=opt.single_cls,
dataloader=testloader,
save_dir=save_dir,
plots=True)
with open(results_file, 'a') as f:
f.write(s + '%10.4g' * 7 % results + '\n')
if len(opt.name) and opt.bucket:
os.system('gsutil cp %s gs://%s/results/results%s.txt' % (results_file, opt.bucket, opt.name))
tags = ['train/box_loss', 'train/obj_loss', 'train/cls_loss',
'metrics/precision', 'metrics/recall', 'metrics/mAP_0.5', 'metrics/mAP_0.5:0.95',
'val/box_loss', 'val/obj_loss', 'val/cls_loss',
'x/lr0', 'x/lr1', 'x/lr2']
for x, tag in zip(list(mloss[:-1]) + list(results) + lr, tags):
if tb_writer:
tb_writer.add_scalar(tag, x, epoch)
if wandb:
wandb.log({tag: x})
save = (not opt.nosave) or (final_epoch and not opt.evolve)
if save:
with open(results_file, 'r') as f:
ckpt = {'epoch': epoch,
'training_results': f.read(),
'model': ema.ema.module.state_dict() if hasattr(ema, 'module') else ema.ema.state_dict(),
'optimizer': None if final_epoch else optimizer.state_dict(),
'wandb_id': wandb_run.id if wandb else None}
torch.save(ckpt, last)
if epoch == 0:
torch.save(ckpt, wdir / 'epoch_{:03d}.pt'.format(epoch))
if ((epoch+1) % 25) == 0:
torch.save(ckpt, wdir / 'epoch_{:03d}.pt'.format(epoch))
if epoch >= (epochs-5):
torch.save(ckpt, wdir / 'last_{:03d}.pt'.format(epoch))
elif epoch >= 420:
torch.save(ckpt, wdir / 'last_{:03d}.pt'.format(epoch))
del ckpt
if rank in [-1, 0]:
n = opt.name if opt.name.isnumeric() else ''
fresults, flast, fbest = save_dir / f'results{n}.txt', wdir / f'last{n}.pt', wdir / f'best{n}.pt'
for f1, f2 in zip([wdir / 'last.pt', wdir / 'best.pt', results_file], [flast, fbest, fresults]):
if f1.exists():
os.rename(f1, f2)
if str(f2).endswith('.pt'):
strip_optimizer(f2)
os.system('gsutil cp %s gs://%s/weights' % (f2, opt.bucket)) if opt.bucket else None
if plots:
plot_results(save_dir=save_dir)
if wandb:
wandb.log({"Results": [wandb.Image(str(save_dir / x), caption=x) for x in
['results.png', 'precision-recall_curve.png']]})
print('%g epochs completed in %.3f hours.\n' % (epoch - start_epoch + 1, (time.time() - t0) / 3600))
wandb.run.finish() if wandb and wandb.run else None
torch.cuda.empty_cache()
return results
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--weights', type=str, default='yolor_p6.pt', help='initial weights path')
parser.add_argument('--cfg', type=str, default='', help='model.yaml path')
parser.add_argument('--data', type=str, default='data/coco.yaml', help='data.yaml path')
parser.add_argument('--hyp', type=str, default='data/hyp.scratch.1280.yaml', help='hyperparameters path')
parser.add_argument('--epochs', type=int, default=300)
parser.add_argument('--batch-size', type=int, default=8, help='total batch size for all GPUs')
parser.add_argument('--img-size', nargs='+', type=int, default=[1280, 1280], help='[train, test] image sizes')
parser.add_argument('--rect', action='store_true', help='rectangular training')
parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
parser.add_argument('--notest', action='store_true', help='only test final epoch')
parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
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('--image-weights', action='store_true', help='use weighted image selection for training')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu or npu')
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('--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('--full', action='store_true', help='full mode')
parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')
parser.add_argument('--log-imgs', type=int, default=16, 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('--project', default='runs/train', help='save to project/name')
parser.add_argument('--name', default='exp', help='save to project/name')
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
parser.add_argument('--npu', default=-1, type=int, help='NPU id to use.')
parser.add_argument('--world-size', default=1, type=int, help='number of nodes for distributed training')
parser.add_argument('--device-num', default=1, type=int, help='multi NPU parameter, GPU or CPU do not modify')
parser.add_argument('--addr', default='127.0.0.1', type=str, help='DDP master node IP')
parser.add_argument('--dist-url', default='tcp://127.0.0.1:29501', type=str,
help='url used to set up distributed training')
opt = parser.parse_args()
if opt.dist_url == "env://":
opt.world_size = int(os.environ["WORLD_SIZE"])
ngpus_per_node = opt.device_num
opt.npu_ddp = (opt.device_num > 1 or opt.world_size > 1)
opt.save_dir = increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok | opt.evolve)
if opt.npu_ddp:
print('multi npu training')
os.environ['MASTER_ADDR'] = opt.addr
os.environ['MASTER_PORT'] = '29501'
os.environ['KERNEL_NAME_ID'] = str(0)
opt.world_size = ngpus_per_node * opt.world_size
mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, opt))
else:
print('1p training')
main_worker(opt.npu, ngpus_per_node, opt)
if opt.full and opt.local_rank in [-1, 0]:
wdir = Path(opt.save_dir) / 'weights' / 'last.pt'
os.system(f"python3 test.py \
--data data/coco.yaml \
--img 1280 \
--batch 32 \
--conf 0.001 \
--iou 0.65 \
--cfg cfg/yolor_p6.cfg \
--weights {wdir} \
--name yolor_val \
--device npu \
--npu 1 \
2>&1 | tee -a npu_8p_full.log")
def main_worker(npu, ngpus_per_node, opt):
if opt.resume:
ckpt = opt.resume if isinstance(opt.resume, str) else get_latest_run()
assert os.path.isfile(ckpt), 'ERROR: --resume checkpoint does not exist'
with open(Path(ckpt).parent.parent / 'opt.yaml') as f:
opt = argparse.Namespace(**yaml.load(f, Loader=yaml.FullLoader))
opt.cfg, opt.weights, opt.resume = '', ckpt, True
print('Resuming training from %s' % ckpt)
else:
opt.data, opt.cfg, opt.hyp = check_file(opt.data), check_file(opt.cfg), check_file(opt.hyp)
assert len(opt.cfg) or len(opt.weights), 'either --cfg or --weights must be specified'
opt.img_size.extend([opt.img_size[-1]] * (2 - len(opt.img_size)))
opt.name = 'evolve' if opt.evolve else opt.name
opt.save_dir = increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok | opt.evolve)
with open(opt.hyp) as f:
hyp = yaml.load(f, Loader=yaml.FullLoader)
if 'box' not in hyp:
warn('Compatibility: %s missing "box" which was renamed from "giou" in %s' %
(opt.hyp, 'https://github.com/ultralytics/yolov5/pull/1120'))
hyp['box'] = hyp.pop('giou')
if opt.npu_ddp:
opt.npu = npu
os.environ['KERNEL_NAME_ID'] = str(npu)
print("[npu id:", opt.npu, "]", "+++++++++++++++++++++++++++KERNEL_NAME_ID:", os.environ['KERNEL_NAME_ID'])
opt.local_rank = opt.local_rank * ngpus_per_node + npu
global mixed_precision
device = torch_utils.select_device(opt.device, opt.npu, apex=mixed_precision, batch_size=opt.batch_size)
opt.total_batch_size = opt.batch_size
if device.type == 'cpu':
mixed_precision = False
elif opt.local_rank != -1 and device.type == 'cuda':
assert torch.cuda.device_count() > opt.local_rank
torch.cuda.set_device(opt.local_rank)
device = torch.device("cuda", opt.local_rank)
dist.init_process_group(backend='nccl', init_method='env://')
opt.world_size = dist.get_world_size()
assert opt.batch_size % opt.world_size == 0, "Batch size is not a multiple of the number of devices given!"
opt.batch_size = opt.total_batch_size // opt.world_size
elif opt.local_rank != -1 and device.type == 'npu':
dist.init_process_group(backend='hccl', world_size=opt.world_size, rank=opt.local_rank)
assert opt.batch_size % opt.world_size == 0, "Batch size is not a multiple of the number of devices given!"
opt.batch_size = opt.total_batch_size // opt.world_size
print(opt)
if not opt.evolve:
tb_writer = None
if opt.local_rank in [-1, 0]:
print(f'Start Tensorboard with "tensorboard --logdir {opt.project}", view at http://localhost:6006/')
tb_writer = SummaryWriter(opt.save_dir)
train(hyp, opt, device, tb_writer, wandb)
else:
meta = {'lr0': (1, 1e-5, 1e-1),
'lrf': (1, 0.01, 1.0),
'momentum': (0.3, 0.6, 0.98),
'weight_decay': (1, 0.0, 0.001),
'warmup_epochs': (1, 0.0, 5.0),
'warmup_momentum': (1, 0.0, 0.95),
'warmup_bias_lr': (1, 0.0, 0.2),
'box': (1, 0.02, 0.2),
'cls': (1, 0.2, 4.0),
'cls_pw': (1, 0.5, 2.0),
'obj': (1, 0.2, 4.0),
'obj_pw': (1, 0.5, 2.0),
'iou_t': (0, 0.1, 0.7),
'anchor_t': (1, 2.0, 8.0),
'anchors': (2, 2.0, 10.0),
'fl_gamma': (0, 0.0, 2.0),
'hsv_h': (1, 0.0, 0.1),
'hsv_s': (1, 0.0, 0.9),
'hsv_v': (1, 0.0, 0.9),
'degrees': (1, 0.0, 45.0),
'translate': (1, 0.0, 0.9),
'scale': (1, 0.0, 0.9),
'shear': (1, 0.0, 10.0),
'perspective': (0, 0.0, 0.001),
'flipud': (1, 0.0, 1.0),
'fliplr': (0, 0.0, 1.0),
'mosaic': (1, 0.0, 1.0),
'mixup': (1, 0.0, 1.0)}
assert opt.local_rank == -1, 'DDP mode not implemented for --evolve'
opt.notest, opt.nosave = True, True
yaml_file = Path(opt.save_dir) / 'hyp_evolved.yaml'
if opt.bucket:
os.system('gsutil cp gs://%s/evolve.txt .' % opt.bucket)
for _ in range(300):
if Path('evolve.txt').exists():
parent = 'single'
x = np.loadtxt('evolve.txt', ndmin=2)
n = min(5, len(x))
x = x[np.argsort(-fitness(x))][:n]
w = fitness(x) - fitness(x).min()
if parent == 'single' or len(x) == 1:
x = x[random.choices(range(n), weights=w)[0]]
elif parent == 'weighted':
x = (x * w.reshape(n, 1)).sum(0) / w.sum()
mp, s = 0.8, 0.2
npr = np.random
npr.seed(int(time.time()))
g = np.array([x[0] for x in meta.values()])
ng = len(meta)
v = np.ones(ng)
while all(v == 1):
v = (g * (npr.random(ng) < mp) * npr.randn(ng) * npr.random() * s + 1).clip(0.3, 3.0)
for i, k in enumerate(hyp.keys()):
hyp[k] = float(x[i + 7] * v[i])
for k, v in meta.items():
hyp[k] = max(hyp[k], v[1])
hyp[k] = min(hyp[k], v[2])
hyp[k] = round(hyp[k], 5)
results = train(hyp.copy(), opt, device, wandb=wandb)
print_mutation(hyp.copy(), results, yaml_file, opt.bucket)
plot_evolution(yaml_file)
print(f'Hyperparameter evolution complete. Best results saved as: {yaml_file}\n'
f'Command to train a new model with these hyperparameters: $ python train.py --hyp {yaml_file}')
if __name__ == '__main__':
option = {}
option["ACL_OP_COMPILER_CACHE_MODE"] = "enable"
option["ACL_OP_COMPILER_CACHE_DIR"] = "./cache"
print("option:",option)
torch.npu.set_option(option)
main()