Yolo v8代码解析(二)

1.callbacks.run('on_pretrain_routine_start')

        会调用回调函数中的run函数。通常用于训练开始前的一些:模型初始化、创建日志等操作。

2.遍历已注册的操作并在主线程中触发所有回调,参数:hook:要检查的钩子的名称,默认为所有。args:从 YOLOv5 接收的参数。线程:(布尔值)在守护线程中运行回调。kwargs:从 YOLOv5 接收的关键字参数。

def run(self, hook, *args, thread=False, **kwargs):
        """
        Loop through the registered actions and fire all callbacks on main thread

        Args:
            hook: The name of the hook to check, defaults to all
            args: Arguments to receive from YOLOv5
            thread: (boolean) Run callbacks in daemon thread
            kwargs: Keyword Arguments to receive from YOLOv5
        """

        assert hook in self._callbacks, f"hook '{hook}' not found in callbacks {self._callbacks}"
        for logger in self._callbacks[hook]:
            if thread:
                threading.Thread(target=logger['callback'], args=args, kwargs=kwargs, daemon=True).start()
            else:
                logger['callback'](*args, **kwargs)

3.PosixPath类型路径可以通过"/"进行拼接。使用Path库将其转换为Path对象。

    w = save_dir / 'weights'  # weights dir
    (w.parent if evolve else w).mkdir(parents=True, exist_ok=True)  # make dir
    last, best = w / 'last.pt', w / 'best.pt'

4.读取超参数配置文件,如果超参数是字符串,则读取yaml文件,在加载为字典格式。超参数从传入trian()函数获得其为字典格式,从命令行参数获得为文件路径,即yaml格式。

if isinstance(hyp, str):
        with open(hyp, errors='ignore') as f:
            hyp = yaml.safe_load(f)  # load hyps dict

5.setattr(self, k, None)置为空,init empty logger dictionary。

       setattr() 函数对应函数 getattr(),用于设置属性值,该属性不一定是存在的。

setattr(object, name, value)

 object:对象,name:字符串,对象属性,value:属性值,函数并无返回值。

6.静态函数:torch.distributed.barrier()

def torch_distributed_zero_first(local_rank: int):
    # Decorator to make all processes in distributed training wait for each local_master to do something
    if local_rank not in [-1, 0]:
        dist.barrier(device_ids=[local_rank])
    yield
    if local_rank == 0:
        dist.barrier(device_ids=[0])

        pytorch多卡训练中,有单机多卡(存在一个节点,通过torch.nn.DataParallel(model)实现)和多机多卡模式,一种是多机多卡(存在一个节点或者多个节点,通torch.nn.parallel(model))。pytorch在训练过程中,对数据采用的是主进程预读取缓存,然后其他进程从缓存中读取,不同进程之间数据同步通过torch.distributed.barrier()实现。

     (1)进程号rank理解

       在多进程上下文中,我们通常假定rank 0是第一个进程或者主进程,其它进程分别具有0,1,2...不同rank号,这样总共具有4个进程。

     (2)单一进程数据处理

       有一些操作是没有必要以并行的方式进行处理的,如数据读取与处理操作只需要一个进程进行处理并缓存,然后与其它进程共享缓存处理数据,但是由于不同进程是同步执行的,单一进程处理数据必然会导致进程之间出现不同步的现象,为此,torch中采用了barrier()函数对其它非主进程进行阻塞,来达到同步的目的。

     (3)barrier()具体原理

       当rank不等于0或者-1,上下文管理器会执行相应的torch.distributed.barrier(),设置一个阻塞栅栏,让此进程处于等待状态,等待所有进程到达栅栏处(包括主进程数据处理完毕);如果执行函数的进程是主进程,会遇到torch.distributed.barrier(),所有进程都到达了当前的栅栏处,这样所有进程就达到了同步,并同时得到释放。

        在多处理环境中,通常假设 0 级是第一个进程或基本进程。然后对其他进程进行不同的排序,例如1、2、3,总共四个进程。 有些操作不需要并行完成,或者只需要一个进程进行一些预处理或缓存,以便其他进程可以使用该数据。 在上述代码中,如果第一个 if 语句由非基本进程(等级 1、2、3)输入,它们将阻塞(或“等待”),因为它们遇到屏障。他们在那里等待,因为barrier()阻塞直到所有进程都到达屏障,但基本进程尚未到达屏障。 所以此时非基本进程(1,2,3)被阻塞,但基本进程(0)继续。基本进程将执行一些操作,直到到达第二个 if 语句,基本进程将遇到障碍。此时,所有流程都已停止在障碍处,这意味着当前所有障碍都可以解除,所有流程都可以继续。

         当进程遇到障碍时,它会阻塞屏障的位置并不重要(并非所有进程都必须输入相同的 if 语句) 进程被屏障阻塞,直到所有进程都遇到屏障,此时所有进程的这些屏障都会被解除。

你可能感兴趣的:(神经网络,YOLO)