yolo_v5 代码部分-1

if __name__ == "__main__":
    opt = parse_opt() ##part1
    main(opt) ##part2

part1

def parse_opt(known=False):
    parser = argparse.ArgumentParser()

    # ?
    parser.add_argument('--hyp', type=str, default='data/hyps/hyp.scratch.yaml', help='hyperparameters path')
    parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')


    # ***** Rectangular training/inference去除这些原图仿射变换到(640,640)的冗余信息
    parser.add_argument('--rect', action='store_true', help='rectangular training')
    # ***** 它可能允许在较低 --img 尺寸下进行更高 --img 尺寸训练的一些好处
    parser.add_argument('--quad', action='store_true', help='quad dataloader')
    # ***** one hot -> label-smoothing
    parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')
    # ***** 超参数进化
    parser.add_argument('--evolve', type=int, nargs='?', const=300, help='evolve hyperparameters for x generations')
    parser.add_argument('--linear-lr', action='store_true', help='linear LR')

    # resume参数
    parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')

    # 默认就行
    parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
    parser.add_argument('--cache', type=str, nargs='?', const='ram', help='--cache images in "ram" (default) or "disk"')
    parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
    parser.add_argument('--multi-scale', default=1, help='vary img-size +/- 50%%')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--bbox_interval', type=int, default=-1, help='Set bounding-box image logging interval for W&B')
    parser.add_argument('--save_period', type=int, default=-1, help='Log model after every "save_period" epoch')
    parser.add_argument('--artifact_alias', type=str, default="latest", help='version of dataset artifact to be used')
    parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
    #parser.add_argument('--upload_dataset', action='store_true', help='Upload dataset as W&B artifact table')

    opt = parser.parse_known_args()[0] if known else parser.parse_args()

    opt.nosave = opt.noval = opt.noautoanchor = False # nothing
    opt.device = opt.workers = opt.freeze = opt.adam = 0
    opt.weights = 'runs/train/exp4/weights/best.pt'
    # opt.cfg = 'models/yolov5s.yaml'
    opt.cfg = ''
    opt.data = r'data\nc4dataset.yaml'
    ## 设置 cfg 从头开始 设置weights 迁移学习 data里面将yaml的nc改为需要的nc
    opt.epochs = 500
    opt.batch_size = 4
    opt.imgsz = 640
    opt.name = 'exp'
    opt.project = 'runs/train'
    opt.change_nc = False
    opt.restart = False
    return opt

part2

LOGGER = logging.getLogger(__name__)
LOCAL_RANK = int(os.getenv('LOCAL_RANK', -1))
RANK = int(os.getenv('RANK', -1))
WORLD_SIZE = int(os.getenv('WORLD_SIZE', 1))
------------------------------------------------------------------------------------------------
local_rank和rank是一个意思,即代表第几个进程,world_size表示总共有n个进程
比如有2块gpu ,world_size = 5 , rank = 3,local_rank = 0 表示总共5个进程第 3 个进程内的第 1 块 GPU(不一定是0号gpu)。
local_rank和rank的取值范围是从0到n-1
------------------------------------------------------------------------------------------------
def main(opt):
    set_logging(RANK) 
------------------------------------------------------------------------------------------------
> def set_logging(rank=-1, verbose=True):
   >     logging.basicConfig(
   >         format="%(message)s",
   >         level=logging.INFO if (verbose and rank in [-1, 0]) else logging.WARN)
  设置不同得日志等级,不用print出所有信息 
------------------------------------------------------------------------------------------------
    # Resume
    if opt.resume and not check_wandb_resume(opt) and not opt.evolve:  # resume an interrupted run
        ckpt = opt.resume if isinstance(opt.resume, str) else get_latest_run()  # specified or most recent path
        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.safe_load(f))  # replace
        opt.cfg, opt.weights, opt.resume = '', ckpt, True  # reinstate
        LOGGER.info(f'Resuming training from {ckpt}')
    else:
        opt.data, opt.cfg, opt.hyp = check_file(opt.data), check_file(opt.cfg), check_file(opt.hyp)  # check files
        assert len(opt.cfg) or len(opt.weights), 'either --cfg or --weights must be specified'
        if opt.evolve:
            opt.project = 'runs/evolve'
            opt.exist_ok = opt.resume
        opt.save_dir = str(increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok))
------------------------------------------------------------------------------------------------
	resume 在yolov5训练的pt模型中存储了ckpt['epoch'](好像是这个) 好像不太需要resume模块 目前还没用上
------------------------------------------------------------------------------------------------
# DDP mode 好像根本用不上
device = select_device(opt.device, batch_size=opt.batch_size)
# if LOCAL_RANK != -1:
#     from datetime import timedelta
#     assert torch.cuda.device_count() > LOCAL_RANK, 'insufficient CUDA devices for DDP command'
#     assert opt.batch_size % WORLD_SIZE == 0, '--batch-size must be multiple of CUDA device count'
#     assert not opt.image_weights, '--image-weights argument is not compatible with DDP training'
#     assert not opt.evolve, '--evolve argument is not compatible with DDP training'
#     assert not opt.sync_bn, '--sync-bn known training issue, see https://github.com/ultralytics/yolov5/issues/3998'
#     torch.cuda.set_device(LOCAL_RANK)
#     device = torch.device('cuda', LOCAL_RANK)
#     dist.init_process_group(backend="nccl" if dist.is_nccl_available() else "gloo")
------------------------------------------------------------------------------------------------
						DDP mode 多卡训练还是什么 目前我用不上
------------------------------------------------------------------------------------------------
    # Train
    if not opt.evolve:
        train(opt.hyp, opt, device)
        if WORLD_SIZE > 1 and RANK == 0:
            _ = [print('Destroying process group... ', end=''), dist.destroy_process_group(), print('Done.')]
------------------------------------------------------------------------------------------------
						如果不evlove 会将hyp opt device传入train
				同时,train的所有预加载代码在这里结束了,下面全部是evolve相关代码
------------------------------------------------------------------------------------------------
    # Evolve hyperparameters (optional)
    else:
        # Hyperparameter evolution metadata (mutation scale 0-1, lower_limit, upper_limit)
        meta = {'lr0': (1, 1e-5, 1e-1),  # initial learning rate (SGD=1E-2, Adam=1E-3)
                'lrf': (1, 0.01, 1.0),  # final OneCycleLR learning rate (lr0 * lrf)
                'momentum': (0.3, 0.6, 0.98),  # SGD momentum/Adam beta1
                'weight_decay': (1, 0.0, 0.001),  # optimizer weight decay
                'warmup_epochs': (1, 0.0, 5.0),  # warmup epochs (fractions ok)
                'warmup_momentum': (1, 0.0, 0.95),  # warmup initial momentum
                'warmup_bias_lr': (1, 0.0, 0.2),  # warmup initial bias lr
                'box': (1, 0.02, 0.2),  # box loss gain
                'cls': (1, 0.2, 4.0),  # cls loss gain
                'cls_pw': (1, 0.5, 2.0),  # cls BCELoss positive_weight
                'obj': (1, 0.2, 4.0),  # obj loss gain (scale with pixels)
                'obj_pw': (1, 0.5, 2.0),  # obj BCELoss positive_weight
                'iou_t': (0, 0.1, 0.7),  # IoU training threshold
                'anchor_t': (1, 2.0, 8.0),  # anchor-multiple threshold
                'anchors': (2, 2.0, 10.0),  # anchors per output grid (0 to ignore)
                'fl_gamma': (0, 0.0, 2.0),  # focal loss gamma (efficientDet default gamma=1.5)
                'hsv_h': (1, 0.0, 0.1),  # image HSV-Hue augmentation (fraction)
                'hsv_s': (1, 0.0, 0.9),  # image HSV-Saturation augmentation (fraction)
                'hsv_v': (1, 0.0, 0.9),  # image HSV-Value augmentation (fraction)
                'degrees': (1, 0.0, 45.0),  # image rotation (+/- deg)
                'translate': (1, 0.0, 0.9),  # image translation (+/- fraction)
                'scale': (1, 0.0, 0.9),  # image scale (+/- gain)
                'shear': (1, 0.0, 10.0),  # image shear (+/- deg)
                'perspective': (0, 0.0, 0.001),  # image perspective (+/- fraction), range 0-0.001
                'flipud': (1, 0.0, 1.0),  # image flip up-down (probability)
                'fliplr': (0, 0.0, 1.0),  # image flip left-right (probability)
                'mosaic': (1, 0.0, 1.0),  # image mixup (probability)
                'mixup': (1, 0.0, 1.0),  # image mixup (probability)
                'copy_paste': (1, 0.0, 1.0)}  # segment copy-paste (probability)
------------------------------------------------------------------------------------------------
			如果evlove 会用上面的遗传算法边进化边训练(上面存储的应该是遗传算法的训练超参数)
------------------------------------------------------------------------------------------------
        with open(opt.hyp) as f:
            hyp = yaml.safe_load(f)  # load hyps dict
            if 'anchors' not in hyp:  # anchors commented in hyp.yaml
                hyp['anchors'] = 3
------------------------------------------------------------------------------------------------
			这里用上了opt.hyp ,hyp中存储的是过往训练保留的一些可能有效的参数作为初始参数
------------------------------------------------------------------------------------------------
        opt.noval, opt.nosave, save_dir = True, True, Path(opt.save_dir)  # only val/save final epoch
        # ei = [isinstance(x, (int, float)) for x in hyp.values()]  # evolvable indices
        evolve_yaml, evolve_csv = save_dir / 'hyp_evolve.yaml', save_dir / 'evolve.csv'
        if opt.bucket:
            os.system(f'gsutil cp gs://{opt.bucket}/evolve.csv {save_dir}')  # download evolve.csv if exists
------------------------------------------------------------------------------------------------
									不太理解这一句是在干什么
								下面就是参数的更新,暂时用不上
------------------------------------------------------------------------------------------------
        for _ in range(opt.evolve):  # generations to evolve 迭代次数
            if evolve_csv.exists():  # if evolve.csv exists: select best hyps and mutate
                # Select parent(s)
                parent = 'single'  # parent selection method: 'single' or 'weighted'
                x = np.loadtxt(evolve_csv, ndmin=2, delimiter=',', skiprows=1)
                n = min(5, len(x))  # number of previous results to consider
                x = x[np.argsort(-fitness(x))][:n]  # top n mutations
                w = fitness(x) - fitness(x).min() + 1E-6  # weights (sum > 0)
                if parent == 'single' or len(x) == 1:
                    # x = x[random.randint(0, n - 1)]  # random selection
                    x = x[random.choices(range(n), weights=w)[0]]  # weighted selection
                elif parent == 'weighted':
                    x = (x * w.reshape(n, 1)).sum(0) / w.sum()  # weighted combination

                # Mutate
                mp, s = 0.8, 0.2  # mutation probability, sigma
                npr = np.random
                npr.seed(int(time.time()))
                g = np.array([x[0] for x in meta.values()])  # gains 0-1
                ng = len(meta)
                v = np.ones(ng)
                while all(v == 1):  # mutate until a change occurs (prevent duplicates)
                    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()):  # plt.hist(v.ravel(), 300)
                    hyp[k] = float(x[i + 7] * v[i])  # mutate

            # Constrain to limits
            for k, v in meta.items():
                hyp[k] = max(hyp[k], v[1])  # lower limit
                hyp[k] = min(hyp[k], v[2])  # upper limit
                hyp[k] = round(hyp[k], 5)  # significant digits

            # Train mutation
            results = train(hyp.copy(), opt, device)

            # Write mutation results
            print_mutation(results, hyp.copy(), save_dir, opt.bucket)

        # Plot results
        plot_evolve(evolve_csv)
        print(f'Hyperparameter evolution finished\n'
              f"Results saved to {colorstr('bold', save_dir)}\n"
              f'Use best hyperparameters example: $ python train.py --hyp {evolve_yaml}')


你可能感兴趣的:(Computer,Vision,caffe,自动驾驶,深度学习)