当前位置: 首页 > news >正文

YOLOv6-4.0部分代码阅读笔记-yolo_lite.py

yolo_lite.py

yolov6\models\yolo_lite.py

所需的库和模块

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
from yolov6.layers.common import *
from yolov6.utils.torch_utils import initialize_weights
from yolov6.models.reppan import *
from yolov6.models.efficientrep import *
from yolov6.utils.events import LOGGER
from yolov6.models.heads.effidehead_lite import Detect, build_effidehead_layer

class Model(nn.Module): 

class Model(nn.Module):# 具有主干、颈部和头部的 YOLOv6 模型。# 默认部件是 EfficientRep Backbone , Rep-PAN 和 Efficient Decoupled Head 。'''YOLOv6 model with backbone, neck and head.The default parts are EfficientRep Backbone, Rep-PAN andEfficient Decoupled Head.'''# 1.config :模型配置对象,包含了模型结构和训练相关的参数。# 2.channels :输入图像的通道数,默认为3(彩色图像)。# 3.num_classes :目标检测任务中的类别数。def __init__(self, config, channels=3, num_classes=None):  # model, input channels, number of classes    模型、输入通道、类别数量# 调用父类初始化方法,调用 nn.Module 的初始化方法,这是 PyTorch 中定义模型类时的标准做法。super().__init__()# Build network    建立网络# def build_network(config, in_channels, num_classes): -> 函数返回构建好的 骨干网络 、 颈部网络 和 头部网络 。 -> return backbone, neck, headself.backbone, self.neck, self.detect = build_network(config, channels, num_classes)# Init Detect head    初始检测头# 从头部网络(detect)获取模型的步长(stride),步长是目标检测中的一个重要参数,它决定了检测的精度和召回率。self.stride = self.detect.stride# def initialize_biases(self): -> 它用于初始化神经网络中特定层的偏置(biases)。这个方法特别针对于类别预测层( self.cls_preds )和边界框回归预测层( self.reg_preds )的偏置和权重进行初始化。# 对检测头的偏置进行初始化,这通常是根据特定的初始化策略来设置偏置值,以帮助模型在训练初期更快地收敛。self.detect.initialize_biases()# Init weights    初始权重# def initialize_weights(model): -> 它用于初始化传入的模型( model )中的权重和偏置。这个函数遍历模型中的所有模块,并根据模块的类型应用特定的初始化策略。# 对整个模型的权重进行初始化,这通常包括对卷积层、全连接层等的权重进行初始化,以确保模型在训练开始时有一个良好的起点。initialize_weights(self)def forward(self, x):# 检查当前是否处于将 PyTorch 模型导出为 ONNX 格式的过程。# ONNX(Open Neural Network Exchange)是一种开放的格式,用于表示深度学习模型,以便在不同的框架和工具之间进行模型的交换和部署。export_mode = torch.onnx.is_in_onnx_export()# 输入数据 x 首先通过骨干网络(backbone)进行处理。x = self.backbone(x)# 骨干网络的输出接着被送入颈部网络(neck)进行进一步的处理。x = self.neck(x)# 如果当前不在 ONNX 导出模式,那么代码会执行以下操作。if export_mode == False:# 初始化一个空列表 featmaps ,用于存储特征图。featmaps = []# 将颈部网络的输出( x )添加到 featmaps 列表中。这里的 x 可能包含多个特征图,这些特征图可以用于后续的目标检测或其他任务。featmaps.extend(x)# 颈部网络的输出被送入检测头(detect),进行目标检测。x = self.detect(x)# 根据是否处于 ONNX 导出模式返回不同的结果。# 如果处于 ONNX 导出模式( export_mode is True ),则只返回检测头的输出 x 。# 如果不在 ONNX 导出模式,返回一个包含检测头输出 x 和特征图列表 featmaps 的列表。return x if export_mode is True else [x, featmaps]# 这段代码定义了 Model 类的 _apply 方法,这个方法在 PyTorch 中用于对模型中的参数应用一个函数 fn 。这通常用于模型的变换,比如参数的修改或者参数的复制等。def _apply(self, fn):# 首先调用 nn.Module 的 _apply 方法,这个方法会对模型中的所有参数和缓存应用函数 fn 。这里的 self 被重新赋值为 _apply 方法的返回值,这意味着模型的参数已经被 fn 函数处理过了。self = super()._apply(fn)# 对检测头中的 stride 属性应用函数 fn 。 stride 是一个重要的参数,它决定了模型输出的空间分辨率。通过 fn 函数,可以对 stride 进行调整或变换。self.detect.stride = fn(self.detect.stride)# 对检测头中的 grid 属性应用函数 fn 。 grid 属性通常是一个列表或者张量,包含了在不同尺度上的目标位置信息。通过 map 函数, fn 被应用到 grid 的每一个元素上,然后返回一个新的列表。self.detect.grid = list(map(fn, self.detect.grid))# 返回经过参数变换后的模型实例。return self

def build_network(config, in_channels, num_classes): 

def build_network(config, in_channels, num_classes):width_mul = config.model.width_multiple    # 控制网络结构宽度的缩放因子。num_repeat_backbone = config.model.backbone.num_repeats    # 主干网络每个stage中基础模块的重复个数。out_channels_backbone = config.model.backbone.out_channels    # 主干网络每个stage中输出的通道数。# scale_size_backbone :骨干网络尺度缩放因子。scale_size_backbone = config.model.backbone.scale_size# in_channels_neck :颈部网络输入通道数的列表。in_channels_neck = config.model.neck.in_channels# unified_channels_neck :颈部网络统一通道数。unified_channels_neck = config.model.neck.unified_channelsin_channels_head = config.model.head.in_channels    # 检测头每个特征层的输入通道数。num_layers = config.model.head.num_layers    # 检测头的特征层数量, P6模型此值为4。BACKBONE = eval(config.model.backbone.type)    # 主干网络的类别,目前可支持'EfficientRep', 'CSPBepBackbone','EfficientRep6','CSPBepBackbone_P6' 4种。NECK = eval(config.model.neck.type)    # 检测器 Neck 的类别,目前可选用'RepPANNeck', 'CSPRepPANNeck','RepBiFPANNeck','CSPRepBiFPANNeck','RepBiFPANNeck6','CSPRepBiFPANNeck_P6' 6种。# def make_divisible(v, divisor=16): -> return new_v# 使用 make_divisible 函数调整骨干网络和颈部网络的通道数,使其可以被特定的除数整除,这里通常是 16 或 8,以优化模型的性能和参数数量。# out_channels_backbone :骨干网络输出通道数调整后的结果。out_channels_backbone = [make_divisible(i * width_mul)for i in out_channels_backbone]# mid_channels_backbone :骨干网络中间通道数,根据 scale_size_backbone 缩放后的结果。mid_channels_backbone = [make_divisible(int(i * scale_size_backbone), divisor=8) for i in out_channels_backbone]# in_channels_neck :颈部网络输入通道数调整后的结果。in_channels_neck = [make_divisible(i * width_mul)for i in in_channels_neck]# 实例化骨干网络,传入输入 通道数 、 中间通道数 、 输出通道数 和 重复次数 。backbone = BACKBONE(in_channels,mid_channels_backbone,out_channels_backbone,num_repeat=num_repeat_backbone)# 实例化颈部网络,传入颈部网络 输入通道数 和 统一通道数 。neck = NECK(in_channels_neck, unified_channels_neck)# def build_effidehead_layer(channels_list, num_anchors, num_classes, num_layers): -> 用于构建头部网络的层结构。 -> return head_layershead_layers = build_effidehead_layer(in_channels_head, 1, num_classes, num_layers)# class Detect(nn.Module): -> def __init__(self, num_classes=80, num_layers=3, inplace=True, head_layers=None):# head :实例化头部网络 , 传入类别数 、 层数 和 头部网络的层结构 。head = Detect(num_classes, num_layers, head_layers=head_layers)# 函数返回构建好的 骨干网络 、 颈部网络 和 头部网络 。return backbone, neck, head

def build_model(cfg, num_classes, device): 

def build_model(cfg, num_classes, device):model = Model(cfg, channels=3, num_classes=num_classes).to(device)return model

def make_divisible(v, divisor=16): 

# 这个函数的作用是将一个给定的数值 v 调整为最接近的、可以被 divisor 整除的数值。在深度学习模型中,这样的函数通常用于确保模型的某些参数(比如卷积层的输出通道数)可以被某个特定的数整除,以便于优化内存使用和计算效率。
def make_divisible(v, divisor=16):# 首先, v 是需要调整的原始数值。# divisor / 2 是为了避免在四舍五入时产生误差,所以先加上 divisor 的一半。# int(v + divisor / 2) 将加上 divisor 一半后的值转换为整数。# // divisor 是整数除法,确保结果可以被 divisor 整除。# * divisor 将结果乘以 divisor ,以确保数值是 divisor 的整数倍。# max(divisor, ...) 确保 new_v 至少为 divisor ,避免结果太小。new_v = max(divisor, int(v + divisor / 2) // divisor * divisor)# 这个条件检查调整后的 new_v 是否小于原始 v 的 90%。 如果是,说明调整后的数值相对于原始数值减少得太多,可能对模型性能有影响。if new_v < 0.9 * v:# 如果 new_v 小于 0.9 * v ,则将 divisor 加到 new_v 上,以确保调整后的数值不会比原始数值小太多。new_v += divisor# 函数返回调整后的 new_v 。return new_v

相关文章:

YOLOv6-4.0部分代码阅读笔记-yolo_lite.py

yolo_lite.py yolov6\models\yolo_lite.py 所需的库和模块 #!/usr/bin/env python3 # -*- coding:utf-8 -*- import math import torch import torch.nn as nn import torch.nn.functional as F from yolov6.layers.common import * from yolov6.utils.torch_utils import i…...

奇瑞汽车:降阶模型在新能源汽车热管理仿真上的应用

随着新能源汽车的发展&#xff0c;对仿真技术的要求也越来越高。那么奇瑞汽车利用降阶模型在新能源汽车热管理仿真上做了哪些应用呢&#xff1f;本次内容主要从四个方面展开介绍&#xff1a; 1、 奇瑞汽车简介&#xff1b; 2、 热管理降阶模型开发的背景&#xff1b; 3、 高低…...

传统的自然语言处理评估指标

目录 传统的自然语言处理评估指标 EM(Exact Match) BLEU(Bilingual Evaluation Understudy) 传统的自然语言处理评估指标 传统评估指标 EM(Exact Match) 计算方式:如果生成的答案与参考答案完全相同(字符级完全匹配),则 EM 得分为 1,否则为 0。这是一种比较严格的…...

WPF+MVVM案例实战(十七)- 自定义字体图标按钮的封装与实现(ABC类)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1、案例效果1、按钮分类2、ABC类按钮实现1、文件创建2、字体图标资源3、自定义依赖属性4、按钮特效样式实现 3、按钮案例演示1、页面实现与文件创建2、依赖注入3 运…...

Redis数据结构:List类型全面解析

文章目录 一、List数据类型1.1 简介1.2 应用场景1.3 底层结构 二、数据结构2.1 压缩列表ZipList2.2 双向链表LinkedList&#xff08;后续已废弃&#xff09;2.3 快速链表QuickList 三、List常见命令 一、List数据类型 1.1 简介 详细介绍&#xff1a;Redis五种数据类型、Strin…...

人工智能证书合集

本文将对目前市面上主流官方机构颁发的人工智能证书进行整理和介绍&#xff0c;由于整理的证书较多&#xff0c;本文共一万八千多字&#xff0c;请根据自己的考证需求阅读对应部分的内容&#xff0c;希望本文对人工智能行业的从业人员和计划从事人工智能相关岗位工作的人员有所…...

php开发实战分析(8):优化MySQL分页查询与数量统计,提升数据库性能

在开发过程中&#xff0c;我们遇到了一段用于从数据库中查询部门信息的PHP代码。该代码负责根据不同的条件&#xff08;如部门名称和来源&#xff09;筛选数据&#xff0c;并返回分页结果及总记录数。然而&#xff0c;原始代码存在一些问题&#xff0c;包括重复的查询条件构建逻…...

shell脚本案例:RAC配置多路径时获取磁盘设备WWID和磁盘大小

使用场景 在RAC配置多路径时&#xff0c;需要获取到磁盘设备的wwid。因为RAC的磁盘配置是提前规划好的&#xff0c;只知道wwid&#xff0c;不知道磁盘对应大小&#xff0c;是不知道应该如何配置多路径的mutipath.conf文件的&#xff1b;而凭借肉眼手工去对应磁盘设备的wwid和大…...

Android Framework AMS(10)广播组件分析-1

该系列文章总纲链接&#xff1a;专题总纲目录 Android Framework 总纲 本章关键点总结 & 说明&#xff1a; 说明&#xff1a;本章节主要解读应用层广播组件的发送广播和接收处理广播 2个过程&#xff0c;以及从APP层到AMS调用之间的打通。关注思维导图中左上部分即可。 有…...

在 Node.js 中使用 .env 文件

什么是 .env 文件&#xff1f; 文件.env是包含环境变量键值对的简单文本文件。此文件的内容不会被签入源代码管理&#xff0c;从而确保敏感数据的安全。 示例 PORT 4000 DATABASE_URL mongodb://localhost: 27017 /mydb API_KEY abcd1234 NODE_ENV development 在 Node.…...

CesiumJS 案例 P19:添加矩形、监听鼠标左击、监听鼠标右击、监听鼠标移动

CesiumJS CesiumJS API&#xff1a;https://cesium.com/learn/cesiumjs/ref-doc/index.html CesiumJS 是一个开源的 JavaScript 库&#xff0c;它用于在网页中创建和控制 3D 地球仪&#xff08;地图&#xff09; 一、添加矩形 <!DOCTYPE html> <html lang"en&…...

路测毫米波雷达标定和目标跟踪

1 2 3 4 5 6 查找匹配时&#xff0c;先对数据排序。逐帧对数据处理&#xff0c;运行速度快。单帧有噪点&#xff0c;多帧处理&#xff0c;准确率更高一些。 7 8 9 10 参考 路侧毫米波雷达标定与目标跟踪哔哔哩_bilibili路侧毫米波雷达标定与目标跟踪, 视频播放量 5855、弹幕量…...

【sqlmap使用手册-持续更新中】

SQLMap 简介 SQLMap 是一个开源的渗透测试工具&#xff0c;用于自动化检测和利用 SQL 注入漏洞。它支持多种数据库&#xff0c;包括 MySQL、PostgreSQL、Oracle、SQL Server 等。 可以通过以下命令安装sqlmap git clone https://github.com/sqlmapproject/sqlmap.git最常用的…...

面向对象三大特征之一:封 装

1、特点 封装是面向对象的核心思想&#xff0c;两层含义&#xff1a;一是一个整体&#xff08;把对象的属性和行为看成一个整体&#xff0c;即封装在一个对象种&#xff09;&#xff0c;二是信息隐藏&#xff0c;对外隐藏&#xff0c;但可以通过某种方式进行调用。 2、访问权…...

qt QMenuBar详解

1、概述 QMenuBar是Qt框架中用于创建菜单栏的类&#xff0c;它继承自QWidget。QMenuBar通常位于QMainWindow对象的标题栏下方&#xff0c;用于组织和管理多个QMenu&#xff08;菜单&#xff09;和QAction&#xff08;动作&#xff09;。菜单栏提供了一个水平排列的容器&#x…...

ESP32的下的蓝牙应用笔记(1)——Beacon蓝牙信标

Beacon蓝牙信标简介 ‌Beacon蓝牙信标‌是一种基于蓝牙低功耗&#xff08;BLE&#xff09;技术的设备&#xff0c;主要用于提供位置信息和数据传输服务。它通过周期性地广播信号&#xff0c;能够在一定范围内与其他蓝牙设备进行通信&#xff0c;从而提供精准的位置信息和相关服…...

控制台安全内部:创新如何塑造未来的硬件保护

在 Help Net Security 的采访中&#xff0c;安全研究人员 Specter 和 ChendoChap 讨论了游戏机独特的安全模型&#xff0c;并强调了它与其他消费设备的不同之处。 他们还分享了对游戏机安全性的进步将如何影响未来消费者和企业硬件设计的看法。 斯佩克特 (Specter) 是本周在阿…...

如何选择适合自己的 Python IDE

集成开发环境&#xff08;IDE&#xff09;是指提供广泛软件开发能力的软件应用程序。IDE 通常包括源代码编辑器、构建自动化工具和调试器。大多数现代 IDE 都配备了智能代码补全功能。在本文中&#xff0c;你将发现目前市场上最好的 Python IDE。 什么是 IDE&#xff1f; IDE…...

Matlab车牌识别课程设计报告模板(附源代码)

目 录 一&#xff0e;课程设计目的……………………………………………3 二&#xff0e;设计原理…………………………………………………3 三&#xff0e;详细设计步骤……………………………………………3 四. 设计结果及分析…………………………………………18 五. …...

kubesphere jenkins自动重定向 http://ks-apiserver:30880/oauth/authorize

问题&#xff1a;登陆kubesphere的jenkins Nodeport IP :Port 46.XXX.XXX.16:30180 自动跳转失败 http://ks-apiserver:30880/oauth/authorize?client_idjenkins&redirect_urihttp://46.XXX.XXX.16:30180/securityRealm/finishLogin&response_typecode&scopeopen…...

Vue3访问页面时自动获取数据

1. 使用生命周期钩子函数 # 后端代码--使用pywebview class Api:def greet(self):greet_text pywebview and vue3response {}response[text] greet_textreturn responseif __name__ __main__:# 前后端通信测试api Api()window webview.create_window(Vue app in pywebvie…...

go语言回调函数的使用

前言 在 Go 语言中&#xff0c;回调函数是一种将一个函数作为参数传递给另一个函数&#xff0c;在特定的事件发生时被调用的编程模式。 一、回调函数的定义 type OnTaskHandler func(r []byte)type remoteTaskClient struct {sync.RWMutexonTask OnTaskHandler } 以上定义了…...

区块链学习笔记(一)

区块链技术实现了去中心化的货币系统&#xff0c;与中心化记账方式不同&#xff0c;它消除了中间第三方&#xff0c;允许用户进行点对点交易&#xff0c;并确保了货币的真正所有权。此外&#xff0c;区块链的代码完全公开且不可篡改&#xff0c;保障了系统的透明度和安全性。 …...

解决QT打包发布App Store时(90238)错误

Invalid signature. The main app bundle, xxxx at the “xxxx.app” path, has the following signing error(s): [a sealed resource is missing or invalid. In subcomponent: xxxx.app/Contents/Frameworks/QtWebEngineCore.framework]. For details about signing Mac cod…...

使用Vite构建现代化前端应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Vite构建现代化前端应用 引言 Vite 简介 安装 Vite 创建项目 启动开发服务器 项目结构 配置 Vite 开发模式 生产构建 使用插…...

PyQt入门指南三十八 QWizard向导组件

在PyQt中&#xff0c;QWizard 是一个用于创建向导式应用程序的组件。向导是一种用户界面模式&#xff0c;它通过一系列逐步的页面引导用户完成某个任务。每个页面通常包含一些输入字段和选项&#xff0c;用户需要在每个页面上完成相应的操作&#xff0c;然后才能进入下一个页面…...

【数学二】线性代数-矩阵-矩阵的概念及运算

考试要求 1、理解矩阵的概念&#xff0c;了解单位矩阵、数量矩阵、对角矩阵、三角矩阵、对称矩阵、反对称矩阵和正交矩阵以及它们的性质. 2、掌握矩阵的线性运算、乘法、转置以及它们的运算规律&#xff0c;了解方阵的幂与方阵乘积的行列式的性质. 3、理解逆矩阵的概念&#x…...

近期学习前端的心得

1.如果你这一行的编辑权利在于你这一行的某个字段的值&#xff0c;你可以使用这样:disabled"scope.row.某字段 ! 某字段的值" 2.如果你不想使用弹出框的形式来修改数据库&#xff0c;可以采用 对“某字段”列使用了 el-input&#xff0c;并绑定了 v-model 到 sco…...

qt QMenu详解

1、概述 QMenu是Qt框架中的一个类&#xff0c;用于创建和管理菜单。它提供了丰富的接口来添加菜单项&#xff08;通常是QAction对象&#xff09;、子菜单以及分隔符。QMenu可以嵌入到菜单栏&#xff08;QMenuBar&#xff09;中&#xff0c;也可以作为弹出菜单&#xff08;通过…...

HTMLCSS:旋转的动态卡片

效果演示 这段代码创建了一个具有动态背景和渐变效果的卡片。卡片背景有一个无限循环的旋转动画&#xff0c;增加了视觉吸引力。这种效果可以用于展示个人信息、项目介绍或其他需要吸引用户注意的内容。 HTML <div class"card"><h3>前端Hardy</h3&…...