0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

YOLOv5 Callback机制解读

jf_pmFSk4VX 来源:GiantPandaCV 2023-02-09 15:12 次阅读

前言

代码仓库地址:https://github.com/Oneflow-Inc/one-yolov5欢迎star one-yolov5项目 获取最新的动态。如果您有问题,欢迎在仓库给我们提出宝贵的意见。如果对您有帮助,欢迎来给我Star呀~

源码解读:https://github.com/Oneflow-Inc/one-yolov5/blob/main/utils/callbacks.py 。文章里面的超链接可能被公众号吃掉,可以考虑到我们的文档网站阅读获得更好的体验:https://start.oneflow.org/oneflow-yolo-doc/source_code_interpretation/callbacks_py.html

这个文件是yolov5的Callback utils

钩子

Hook

hook(钩子)是一个编程机制,与语言无关,通常用于在不修改原始代码的情况下,捕获或替换程序的一些函数或API调用。

个人观点:钩子是指将代码插入到其他代码的执行流程中的技术,从而实现在执行原有代码之前或之后执行额外代码的目的,下面是一个简单demo。

defhook_function(original_function):
#定义钩子函数
defnew_function(*args,**kwargs):
print("Beforeoriginalfunction")
result=original_function(*args,**kwargs)
print("Afteroriginalfunction")
returnresult

returnnew_function

@hook_function
deforiginal_function():
#@hook_function(python语法)等价于hook_function(original_function)
print("Originalfunction")

if__name__=="__main__":
original_function()
输出
Beforeoriginalfunction
Originalfunction
Afteroriginalfunction

回调函数

来源网络的例子,有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数(to register a callback function)。如下图所示(图片来源:维基百科):

32ad9a96-a848-11ed-bfe3-dac502259ad0.pngcallback

从上图可以看到,回调函数通常和应用处于同一抽象层(因为传入什么样的回调函数是在应用级别决定的)。而回调就成了一个高层调用底层,底层再回过头来调用高层的过程。

简单来说:

  • 一般函数:function a(int a, String b),接收的参数是一般类型。
  • 特殊函数:function b(function c),接收的参数是一个函数,c这个函数就叫回调函数

个人观点:回调函数是指在代码中被调用的一个函数,它会对其他代码的执行造成影响,并在适当的时间进行回调,下面是一个简单demo。

defcallback_function(input_data):
#在回调函数中处理输入数据
print("Inputdata:",input_data)

defmain(callback):
#调用回调函数
callback("HelloWorld")

if__name__=="__main__":
main(callback_function)
输出
Inputdata:HelloWorld

总之,钩子和回调函数是实现代码间通信和协作的不同技术,它们都可以用于实现代码级别的自定义行为,只是函数的触发时机有差异。

hook实现例子

hook函数是程序中预定义好的函数,这个函数处于原有程序流程当中(暴露一个钩子出来)。我们需要再在有流程中钩子定义的函数块中实现某个具体的细节,需要把我们的实现,挂接或者注册(register)到钩子里,使得hook函数对目标可用。

hook函数最常使用在某种流程处理当中。这个流程往往有很多步骤。hook函数常常挂载在这些步骤中,为增加额外的一些操作,提供灵活性。

下面举一个简单的例子,这个例子的目的是实现一个通过钩子调用函数判断字符串是否是"good"

#YOLOv5byUltralytics,GPL-3.0license
"""
Callbackutils
"""
classCallbacks:
""""
HandlesallregisteredcallbacksforYOLOv5Hooks
"""

def__init__(self):
#Definetheavailablecallbacks
self._callbacks={
"on_pretrain_routine_start":[],
}
self.stop_training=False#setTruetointerrupttraining

defregister_action(self,hook,name="",callback=None):
"""
Registeranewactiontoacallbackhook

Args:
hook:Thecallbackhooknametoregistertheactionto要向其注册操作的回调钩子名称
name:Thenameoftheactionforlaterreference动作的名称,供以后参考
callback:Thecallbacktofire对fire的回调
"""
asserthookinself._callbacks,f"hook'{hook}'notfoundincallbacks{self._callbacks}"
assertcallable(callback),f"callback'{callback}'isnotcallable"
self._callbacks[hook].append({"name":name,"callback":callback})

defget_registered_actions(self,hook=None):
""""
Returnsalltheregisteredactionsbycallbackhook

Args:
hook:Thenameofthehooktocheck,defaultstoall
"""
returnself._callbacks[hook]ifhookelseself._callbacks

defrun(self,hook,*args,**kwargs):
"""
Loopthroughtheregisteredactionsandfireallcallbacks

Args:
hook:Thenameofthehooktocheck,defaultstoall
args:ArgumentstoreceivefromYOLOv5
kwargs:KeywordArgumentstoreceivefromYOLOv5
"""

asserthookinself._callbacks,f"hook'{hook}'notfoundincallbacks{self._callbacks}"

forloggerinself._callbacks[hook]:
logger["callback"](*args,**kwargs)
defon_pretrain_routine_start(good:str):
ifgood=="good":
print("isgood!")
else:
print("isbad!")
#初始化Callbacks对象
callbacks=Callbacks()
#要向其注册操作的回调钩子名称
callbacks.register_action(hook="on_pretrain_routine_start",name="ss",callback=on_pretrain_routine_start)
#调用hook
callbacks.run("on_pretrain_routine_start","good")
#打印hook信息
callbacks.get_registered_actions("on_pretrain_routine_start")
is good





[{'name': 'ss',
  'callback': }]

yolov5项目中

在yolov5训练流程中,hook函数体现在一个训练过程(不包括数据准备),会轮询多次训练集,每次称为一个epoch,每个epoch又分为多个batch来训练。流程先后拆解成:

  • 开始训练
  • 训练一个epoch前
  • 训练一个batch前
  • 训练一个batch后
  • 训练一个epoch后。
  • 评估验证集
  • 结束训练

这些步骤是穿插在训练一个batch数据的过程中,这些可以理解成是钩子函数,我们可能需要在这些钩子函数中实现一些定制化的东西,比如在训练一个epoch后我们要保存下训练的损失。

#在train.py中hook注册操作代码
#Registeractions
forkinmethods(loggers):
callbacks.register_action(k,callback=getattr(loggers,k))
#YOLOv5byUltralytics,GPL-3.0license
"""
Callbackutils
"""


classCallbacks:
""""
HandlesallregisteredcallbacksforYOLOv5Hooks
"""

def__init__(self):
#Definetheavailablecallbacks
#定义些回调函数,函数实现在utils/loggers/__init__.py
#github链接:https://github.com/Oneflow-Inc/one-yolov5/blob/main/utils/loggers/__init__.py
self._callbacks={
"on_pretrain_routine_start":[],
#https://github.com/Oneflow-Inc/one-yolov5/blob/88864544cd9fa9ddcbe35a28a0bcf2c674daeb97/utils/loggers/__init__.py#L118
"on_pretrain_routine_end":[],
"on_train_start":[],
"on_train_epoch_start":[],
"on_train_batch_start":[],
"optimizer_step":[],
"on_before_zero_grad":[],
"on_train_batch_end":[],
"on_train_epoch_end":[],
"on_val_start":[],
"on_val_batch_start":[],
"on_val_image_end":[],
"on_val_batch_end":[],
"on_val_end":[],
"on_fit_epoch_end":[],#fit=train+val
"on_model_save":[],
"on_train_end":[],
"on_params_update":[],
"teardown":[],
}
self.stop_training=False#setTruetointerrupttraining

defregister_action(self,hook,name="",callback=None):
"""
Registeranewactiontoacallbackhook

Args:
hook:Thecallbackhooknametoregistertheactionto
name:Thenameoftheactionforlaterreference
callback:Thecallbacktofire
"""
asserthookinself._callbacks,f"hook'{hook}'notfoundincallbacks{self._callbacks}"
assertcallable(callback),f"callback'{callback}'isnotcallable"
self._callbacks[hook].append({"name":name,"callback":callback})

defget_registered_actions(self,hook=None):
""""
Returnsalltheregisteredactionsbycallbackhook

Args:
hook:Thenameofthehooktocheck,defaultstoall
"""
returnself._callbacks[hook]ifhookelseself._callbacks

defrun(self,hook,*args,**kwargs):
"""
Loopthroughtheregisteredactionsandfireallcallbacks

Args:
hook:Thenameofthehooktocheck,defaultstoall
args:ArgumentstoreceivefromYOLOv5
kwargs:KeywordArgumentstoreceivefromYOLOv5
"""

asserthookinself._callbacks,f"hook'{hook}'notfoundincallbacks{self._callbacks}"

forloggerinself._callbacks[hook]:
logger["callback"](*args,**kwargs)


审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    3882

    浏览量

    61310
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66800
  • HOOK
    +关注

    关注

    0

    文章

    15

    浏览量

    8309

原文标题:《YOLOv5全面解析教程》​十五,YOLOv5 Callback机制解读

文章出处:【微信号:GiantPandaCV,微信公众号:GiantPandaCV】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    YOLOv5】LabVIEW+YOLOv5快速实现实时物体识别(Object Detection)含源码

    前面我们给大家介绍了基于LabVIEW+YOLOv3/YOLOv4的物体识别(对象检测),今天接着上次的内容再来看看YOLOv5。本次主要是和大家分享使用LabVIEW快速实现yolov5
    的头像 发表于 03-13 16:01 1660次阅读

    Yolov5算法解读

    yolov5于2020年由glenn-jocher首次提出,直至今日yolov5仍然在不断进行升级迭代。 Yolov5YOLOv5s、YOLOv
    的头像 发表于 05-17 16:38 4317次阅读
    <b class='flag-5'>Yolov5</b>算法<b class='flag-5'>解读</b>

    YOLOv5】LabVIEW+TensorRT的yolov5部署实战(含源码)

    今天主要和大家分享在LabVIEW中使用纯TensoRT工具包快速部署并实现yolov5的物体识别
    的头像 发表于 08-21 22:20 834次阅读
    【<b class='flag-5'>YOLOv5</b>】LabVIEW+TensorRT的<b class='flag-5'>yolov5</b>部署实战(含源码)

    龙哥手把手教你学视觉-深度学习YOLOV5

    步数的课程,希望学员学习后能在实际工业项目中落地应用。本次课程将重点讲解《YOLOv5》篇,让没有任何深度学习基础的小白学员,通过视频课程能动手配置好yolov5环境,能利用自己的数据集训练模型,能
    发表于 09-03 09:39

    求大佬分享RK3399运行瑞芯微官方yolov5 C++代码

    求大佬分享RK3399运行瑞芯微官方yolov5 C++代码
    发表于 03-07 06:33

    怎样使用PyTorch Hub去加载YOLOv5模型

    在Python>=3.7.0环境中安装requirements.txt,包括PyTorch>=1.7。模型和数据集从最新的 YOLOv5版本自动下载。简单示例此示例从
    发表于 07-22 16:02

    YOLOv5网络结构解析

    1、YOLOv5 网络结构解析  YOLOv5针对不同大小(n, s, m, l, x)的网络整体架构都是一样的,只不过会在每个子模块中采用不同的深度和宽度,  分别应对yaml文件中
    发表于 10-31 16:30

    使用Yolov5 - i.MX8MP进行NPU错误检测是什么原因?

    的时机(yolov5s 模型,输入为 448x448 ~ 70ms)。 现在我正在尝试使用 Yolov5(uint8 量化),但我尝试使用不同的预训练模型获得相同的行为,在 CPU 上进行良好检测,在
    发表于 03-31 07:38

    如何YOLOv5测试代码?

    使用文档“使用 YOLOv5 进行对象检测”我试图从文档第 10 页访问以下链接(在 i.MX8MP 上部署 yolov5s 的步骤 - NXP 社区) ...但是这样做时会被拒绝访问。该文档没有说明需要特殊许可才能下载 test.zip 文件。NXP 的人可以提供有关如
    发表于 05-18 06:08

    yolov5模型onnx转bmodel无法识别出结果如何解决?

    问题描述: 1. yolov5模型pt转bmodel可以识别出结果。(转化成功,结果正确) 2. yolov5模型pt转onnx转bmodel可以无法识别出结果。(转化成功,结果没有) 配置: 1.
    发表于 09-15 07:30

    基于YOLOv5的目标检测文档进行的时候出错如何解决?

    你好: 按Milk-V Duo开发板实战——基于YOLOv5的目标检测 安装好yolov5环境,在执行main.py的时候会出错,能否帮忙看下 main.py: import torch
    发表于 09-18 07:47

    yolov5训练部署全链路教程

    本教程针对目标检测算法yolov5的训练和部署到EASY-EAI-Nano(RV1126)进行说明。
    的头像 发表于 01-05 18:00 2333次阅读
    <b class='flag-5'>yolov5</b>训练部署全链路教程

    使用旭日X3派的BPU部署Yolov5

    本次主要介绍在旭日x3的BPU中部署yolov5。首先在ubuntu20.04安装yolov5,并运行yolov5并使用pytoch的pt模型文件转ONNX。
    的头像 发表于 04-26 14:20 544次阅读
    使用旭日X3派的BPU部署<b class='flag-5'>Yolov5</b>

    【教程】yolov5训练部署全链路教程

    本教程针对目标检测算法yolov5的训练和部署到EASY-EAI-Nano(RV1126)进行说明,而数据标注方法可以参考我们往期的文章《Labelimg的安装与使用》。
    的头像 发表于 01-29 15:25 2838次阅读
    【教程】<b class='flag-5'>yolov5</b>训练部署全链路教程

    YOLOv5网络结构训练策略详解

    前面已经讲过了Yolov5模型目标检测和分类模型训练流程,这一篇讲解一下yolov5模型结构,数据增强,以及训练策略。
    的头像 发表于 09-11 11:15 1123次阅读
    <b class='flag-5'>YOLOv5</b>网络结构训练策略详解