2023-简单点-yolox-pytorch代码解析(一)-nets/darknet.py

yolox-pytorch: nets/darknet.py

  • yolox网络结构
  • yolox-pytorch目录
  • 今天解析注释net/darknet.py
  • Focus
  • BaseConv
  • DWConv
  • SPPBottleneck
  • Darknet
  • 未完待续。。。

yolox网络结构

这里是引用

yolox-pytorch目录

在这里插入图片描述

今天解析注释net/darknet.py

#!/usr/bin/env python3  # 指定使用python3来执行此脚本  
# -*- coding:utf-8 -*-  # 声明脚本使用的编码是utf-8  
# Copyright (c) Megvii, Inc. and its affiliates.  # 版权信息,标注了归属公司为Megvii, Inc.及其附属公司  # 导入torch库,torch是PyTorch的主体库,提供了张量计算和神经网络构建等基础功能  
import torch  # 从torch库中导入nn模块,nn是PyTorch的神经网络模块,提供了各种神经网络层和损失函数等  
from torch import nn  ##########################################################################################
# 定义一个名为SiLU的类,继承自nn.Module,这个类代表Sigmoid线性单元,一种非线性激活函数  
class SiLU(nn.Module):  # 定义一个静态方法forward,此方法用于定义SiLU类的运算过程,参数x是输入数据  @staticmethod  def forward(x):   # 返回输入数据x乘以sigmoid函数的结果,实现SiLU运算  return x * torch.sigmoid(x)  
##########################################################################################  
# 定义一个函数get_activation,用于获取不同类型的激活函数模块  
def get_activation(name="silu", inplace=True):  # 根据传入的name参数判断要返回的激活函数类型,默认为SiLU类型  if name == "silu":   # 如果name为"silu",则创建一个SiLU类型的模块并赋值给module变量  module = SiLU()  elif name == "relu":   # 如果name为"relu",则创建一个ReLU类型的模块,inplace参数表示原地操作,是否会修改输入数据,默认为True  module = nn.ReLU(inplace=inplace)  elif name == "lrelu":   # 如果name为"lrelu",则创建一个LeakyReLU类型的模块,0.1表示负斜率,inplace参数表示原地操作,是否会修改输入数据,默认为True  module = nn.LeakyReLU(0.1, inplace=inplace)  else:   # 如果name不是上述任何一种类型,则抛出一个AttributeError异常,提示"Unsupported act type: {}".format(name)错误信息  raise AttributeError("Unsupported act type: {}".format(name))  # 返回获取到的激活函数模块  return module  
##########################################################################################  
# 定义一个名为Focus的类,继承自nn.Module,这个类代表焦点模块,用于对输入数据进行空间上的重新构造  
class Focus(nn.Module):  # 定义一个构造函数__init__,此方法用于初始化Focus类的实例对象  def __init__(self, in_channels, out_channels, ksize=1, stride=1, act="silu"):  # 调用父类的构造函数,进行基本的初始化操作  super().__init__()  # 定义变量pad为(ksize - 1) // 2,表示卷积操作的填充大小  pad = (ksize - 1) // 2  # 创建一个BaseConv类型的模块,参数为in_channels * 4(输入通道数变为原来的四倍),out_channels(输出通道数),ksize(卷积核大小),stride(步长),pad(填充大小),act(激活函数类型默认为SiLU)  self.conv = BaseConv(in_channels * 4, out_channels, ksize, stride, act=act)  # 定义一个forward方法,此方法用于定义Focus类的运算过程,参数x是输入数据  def forward(self, x):   # 从输入数据x中获取四个位置的patch并进行拼接,形成一个新的数据x并返回给conv进行卷积操作#考虑2 x 2的四个方格,左上,左下,右上和右下为起始点,各一个元素采样  patch_top_left = x[..., ::2, ::2]  # 从左上角开始每隔一个像素取一个像素点形成左上角patch  patch_bot_left = x[..., 1::2, ::2]  # 从左下角开始每隔一个像素取一个像素点形成左下角patch  patch_top_right = x[..., ::2, 1::2]  # 从右上角开始每隔一个像素取一个像素点形成右上角patch  patch_bot_right = x[..., 1::2, 1::2]  # 从右下角开始每隔一个像素取一个像素点形成右下角patch  x = torch.cat((patch_top_left, patch_bot_left, patch_top_right,patch_bot_right), dim=1)  # 将四个patch在通道维度上进行拼接  # 返回经过conv卷积操作后的结果  return self.conv(x)  
##########################################################################################  
# 定义一个名为BaseConv的类,继承自nn.Module,这个类代表基础卷积模块,用于构建卷积神经网络的基础模块  
class BaseConv(nn.Module):  # 定义一个构造函数__init__,此方法用于初始化BaseConv类的实例对象  def __init__(self, in_channels, out_channels, ksize, stride, groups=1, bias=False, act="silu"):  # 调用父类的构造函数,进行基本的初始化操作  super().__init__()  # 定义变量pad为(ksize - 1) // 2,表示卷积操作的填充大小  pad = (ksize - 1) // 2  # 创建一个Conv2d类型的卷积层,参数依次为输入通道数,输出通道数,卷积核大小,步长,填充大小,分组数,是否使用偏置  self.conv = nn.Conv2d(in_channels, out_channels, ksize, stride, pad, groups=groups, bias=bias)# 定义一个批归一化层,用于加速训练和提高模型稳定性。  self.bn   = nn.BatchNorm2d(out_channels, eps=0.001, momentum=0.03)   # 如果传入的act参数不为空字符串,则根据act参数创建一个激活函数模块并赋值给self.act变量  if act is not None:  self.act = get_activation(act, inplace=True)  else:  self.act = nn.Identity()  # 如果act参数为空字符串,则使用恒等映射作为激活函数  # 定义一个forward方法,此方法用于定义BaseConv类的运算过程,参数x是输入数据  def forward(self, x):   # 返回经过conv卷积操作和act激活函数处理后的结果  return self.act(self.conv(x))
########################################################################################## 定义一个名为DWConv的类,继承自nn.Module,这是一个深度可分离卷积模块。  
class DWConv(nn.Module):  # 初始化函数,用于设置该模块所需的各种参数和子模块。  def __init__(self, in_channels, out_channels, ksize, stride=1, act="silu"):  # 调用父类的初始化函数。  super().__init__()  # 定义一个深度卷积层(逐通道卷积),其输出通道数与输入通道数相同,并且使用给定的核大小和步长。  # 注意这里的groups参数设置为in_channels,意味着每个输入通道都有独立的卷积核。  self.dconv = BaseConv(in_channels, in_channels, ksize=ksize, stride=stride, groups=in_channels, act=act,)  # 定义一个逐点卷积层(1x1卷积),用于改变通道数。这里的groups参数设置为1,表示是普通的卷积操作。  self.pconv = BaseConv(in_channels, out_channels, ksize=1, stride=1, groups=1, act=act)  # 定义前向传播函数,输入数据x会首先经过深度卷积层处理,然后再经过逐点卷积层处理。  def forward(self, x):  x = self.dconv(x)  # 数据经过深度卷积层处理。  return self.pconv(x)  # 经过逐点卷积层处理后输出结果。
##########################################################################################
# 定义一个名为SPPBottleneck的类,继承自nn.Module,这是一个包含空间金字塔池化(Spatial Pyramid Pooling, SPP)的瓶颈模块。  
class SPPBottleneck(nn.Module):  # 初始化函数,用于设置该模块所需的各种参数和子模块。  def __init__(self, in_channels, out_channels, kernel_sizes=(5, 9, 13), activation="silu"):  # 调用父类的初始化函数。  super().__init__()  # 计算隐藏层的通道数,为输入通道数的一半。  hidden_channels = in_channels // 2  # 定义第一个卷积层,用于降低通道数。这里使用1x1的卷积核。  self.conv1      = BaseConv(in_channels, hidden_channels, 1, stride=1, act=activation)  # 定义一个包含多个最大池化层的模块列表,用于生成不同尺度的空间金字塔特征。  self.m          = nn.ModuleList([nn.MaxPool2d(kernel_size=ks, stride=1, padding=ks // 2) for ks in kernel_sizes])  # 计算第二个卷积层的输入通道数,为隐藏层通道数与空间金字塔层数的和。  conv2_channels  = hidden_channels * (len(kernel_sizes) + 1)  # 定义第二个卷积层,用于增加通道数并整合空间金字塔特征。这里使用1x1的卷积核。  self.conv2      = BaseConv(conv2_channels, out_channels, 1, stride=1, act=activation)  # 定义前向传播函数,输入数据x会首先经过第一个卷积层处理,然后生成空间金字塔特征并拼接在一起,最后经过第二个卷积层处理并输出结果。  def forward(self, x):  x = self.conv1(x)  # 数据经过第一个卷积层处理。  x = torch.cat([x] + [m(x) for m in self.m], dim=1)  # 生成空间金字塔特征并将它们拼接在一起。  x = self.conv2(x)  # 经过第二个卷积层处理后输出结果。  return x##########################################################################################
# 定义一个名为Darknet的类,继承自nn.Module,这个类代表Darknet网络模型,用于构建Darknet系列的目标检测模型  
class Darknet(nn.Module):  # 定义一个构造函数__init__,此方法用于初始化Darknet类的实例对象  def __init__(self, in_channels, out_channels, **kwargs):  # 调用父类的构造函数,进行基本的初始化操作  super().__init__()  # 根据传入的参数创建多个BaseConv类型的模块并依次添加到self.layers列表中  self.layers = nn.ModuleList([BaseConv(in_channels, out_channels, **kwargs) for _ in range(len(kwargs["out_channels"]))])  # 将最后一个BaseConv模块的输出通道数赋值给self.out_channels变量  self.out_channels = kwargs["out_channels"][-1]  # 定义一个forward方法,此方法用于定义Darknet类的运算过程,参数x是输入数据  def forward(self, x):  # 依次将输入数据x传入self.layers列表中的每个BaseConv模块进行处理,并将结果赋值给x  for layer in self.layers:  x = layer(x)  # 返回经过所有BaseConv模块处理后的结果x  return x  
##########################################################################################  
# 定义一个名为CSPDarknet的类,继承自nn.Module,这个类代表CSPDarknet网络模型,用于构建CSPDarknet系列的目标检测模型  
class CSPDarknet(nn.Module):  # 定义一个构造函数__init__,此方法用于初始化CSPDarknet类的实例对象  def __init__(self, in_channels, out_channels, **kwargs):  # 调用父类的构造函数,进行基本的初始化操作  super().__init__()  # 根据传入的参数创建多个BaseConv类型的模块和多个Darknet类型的模块,并依次添加到self.conv和self.blocks列表中  self.conv = BaseConv(in_channels, out_channels, **kwargs)  self.blocks = nn.ModuleList([Darknet(out_channels, out_channels * 2, **kwargs) for _ in range(len(kwargs["out_channels"]))])  # 将最后一个Darknet模块的输出通道数赋值给self.out_channels变量  self.out_channels = kwargs["out_channels"][-1] * 2  # 定义一个forward方法,此方法用于定义CSPDarknet类的运算过程,参数x是输入数据  def forward(self, x):  # 将输入数据x传入self.conv模块进行处理,并将结果赋值给x  x = self.conv(x)  # 将处理后的结果x分别传入self.blocks列表中的每个Darknet模块进行处理,并将结果拼接在一起形成一个新的结果x  x = torch.cat([block(x) for block in self.blocks], dim=1)  # 返回经过所有Darknet模块处理后的结果x  return x

Focus

在这里插入图片描述

BaseConv

简而言之:卷积 + 激活【是否】

BaseConv是一个基础卷积类,它继承了PyTorch中的nn.Module类,并实现了卷积、批归一化(Batch Normalization)和激活函数等核心操作。BaseConv类的主要参数包括:

  • in_channels:输入通道数。
  • out_channels:输出通道数。
  • ksize:卷积核大小。
  • stride:步长。
  • groups:分组卷积中的组数,默认为1。
  • bias:是否使用bias(偏差),默认为False。
  • act:激活函数类型,默认为"silu"。

在BaseConv类中,主要实现了以下三个方法:

  • __init__:构造函数,用于初始化BaseConv对象。在构造函数中,会创建一个nn.Conv2d对象(卷积层),一个nn.BatchNorm2d对象(批归一化层)和一个激活函数对象。
  • forward:前向传播函数。输入数据x首先经过卷积层和批归一化层,然后通过激活函数进行激活,最终输出结果。
  • get_activation:获取激活函数。该函数用于获取指定名称的激活函数对象。

总体来说,BaseConv是一个简单但实用的卷积类,可以作为构建其他复杂卷积网络的基础组件。

DWConv

在这里插入图片描述

SPPBottleneck

在这里插入图片描述

Darknet

未完待续。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/180880.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

主要分布式文件系统架构对比分析:GFS vs. Tectonic vs. JuiceFS

随着技术的进步和数据的不断爆炸,传统的磁盘文件系统已经暴露出它们的局限性。为了满足不断增长的存储需求,分布式文件系统作为动态且可扩展的解决方案应运而生。在本文中,我们探讨了三种代表性分布式文件系统的设计原则、创新和解决的挑战&a…

SEO工具-免费功能最全的5款SEO工具

随着互联网的蓬勃发展,搜索引擎优化(SEO)已经成为许多企业和个人网站必备的关键技能。然而,对于初学者或者运营小型网站的人来说,使用专业的SEO工具可能涉及较高的成本。在这篇文章中,我们将向您推荐五款高…

西南科技大学模拟电子技术实验二(二极管特性测试及其应用电路)预习报告

目录 一、计算/设计过程 二、画出并填写实验指导书上的预表 三、画出并填写实验指导书上的虚表 四、粘贴原理仿真、工程仿真截图 一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入…

基于单片机的烟雾检测报警装置(论文+源码)

1.系统设计 (1)利用传感器实现环境中温度、烟雾浓度的实时检测; (2)系统检测的各项数据信息通过液晶模块进行显示,提高设计可视化; (3)系统可以根据实际情况利用按键模…

Mysql单表查询练习

一、单表查询 素材: 表名:worker-- 表中字段均为中文,比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker (部门号 int(11) NOT NULL,职工号 int(11) NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌 varchar(10…

双十二有什么好物是值得推荐?智能家居好物推荐

都知十一月份跟十二月份都有两个大促的时间,那就是双十一跟双十二,距离双十一过去已经半个月了,是不是还有很多朋友在双十一的时候也没有买尽兴,别慌!错过了双十一咱还有双十二,双十二的优惠力度也不会低于…

短视频账号矩阵系统源码/saas独立源头技术开发

一、批量剪辑(采用php语言,数学建模) 短视频合成批量剪辑的算法主要有以下几种: 1. 帧间插值算法:通过对多个视频的帧进行插帧处理,从而合成一段平滑的短视频。 2. 特征提取算法:提取多个视频中…

【开发实践】使用POI实现导出带有复杂表头的的excel文件

一、需求分析 公司业务部门需要&#xff0c;根据一些数据&#xff0c;加上表头&#xff0c;导出需要的excel表格。效果如下&#xff1a; 二、代码实现 【依赖准备】 <!-- POI --><dependency><groupId>org.apache.poi</groupId><artifactId>po…

【esp32】可变时间的定时器中断的开启和关闭

前言 回忆若能下酒&#xff0c;往事便可作一场宿醉。醒来时&#xff0c;天依旧清亮&#xff0c;风仍然分明&#xff0c;而光阴的两岸&#xff0c;终究无法以一苇杭之。我知你心意。无须更多言语&#xff0c;我必与你相忘于江湖&#xff0c;以沧桑为饮&#xff0c;年华果腹&…

倾斜摄影三维模型的根节点合并的轻量化技术方法分析

倾斜摄影三维模型的根节点合并的轻量化技术方法分析 倾斜摄影三维模型的根节点合并是一种轻量化技术&#xff0c;旨在减小模型数据的大小&#xff0c;提高渲染效率和加载速度。在本文中&#xff0c;我们将探讨关于倾斜摄影三维模型根节点合并的轻量化技术方法。 1、LOD&#x…

SpringBoot+网易邮箱登录注册

文章目录 SpringBoot网易邮箱登录注册pom.xmlapplication.ymlsqlUserEmail.javaUserEmailMapper.javaUserEmailMapper.xmlEmailService.javaUserEmailService.javaUserEmailServiceImpl.javaUserEmailController.javaregister1.html 编写前参考 SpringBoot网易邮箱登录注册 po…

PPSSPP (PSP游戏模拟器)最新版安装使用教程

PPSSPP优势 1、目前唯一的也是最好的psp模拟器 可运行绝大多数psp游戏且运行高速&#xff0c;即使是低配手机也能游玩经典大作。 2、支持自定义调节虚拟手柄和实体手柄连接 ppsspp模拟器支持使用虚拟手柄或者连接实体手柄游玩&#xff0c;同时还可以自定义调节按键选项。 …

使用Git客户端向gitee免密推送项目代码(保姆级流程哦)

1.进入Git官网手动下载git的客户端可执行程序 一路next即可 2.找到安装路径下的3.进入git-bash 根据如下的代码一次执行只需要修改对应的username和自己再gitee中绑定的邮箱 4.分发私钥到邮箱 产生私钥的时候回车三次即可&#xff1b;查看私钥如下图及正常&#xff1b; 5.进…

文生图领域经典-ControlNet介绍

引言 2023年的计算机视觉领域顶级学术会议ICCV上&#xff0c;一篇颠覆文生图AI领域的论文《Adding Conditional Control to Text-to-Image Diffusion Models》——ControlNet 荣膺最佳论文奖(Marr奖)。 自开源以来&#xff0c;ControlNet已经在GitHub上揽获25k星。无论是对扩…

vue项目多个不同的服务器请求地址管理

vue项目多个不同的服务器请求地址管理 在vue项目开发过程中&#xff0c;获取不同的数据可能会出现需要请求多个不同服务器地址的域名&#xff0c;这个时候需要对不同域名的请求地址进行管理以及跨域的代理。 一、单服务器域名地址的跨域代理和请求配置&#xff1a; 跨域配置&…

C#:程序发布的大小控制

.net不讨喜有个大原因就是.net平台本身太大了&#xff0c;不同版本没有兼容性&#xff0c;程序依赖哪个版本用户就要安装哪个版本&#xff0c;除非你恰好用的是操作系统默认安装的版本——问题是不同版本操作系统默认安装的不一样。 所以打包程序就很头疼&#xff0c;不打包平台…

深度解读:为什么要做数据合规?如何做到数据合规?

数据资源“入表”在即&#xff0c;企业更需筑牢数据合规防线。但企业主企业购买数据、获取数据到底是否合法合规&#xff0c;入表如何防范合规风险&#xff1f;上周三&#xff0c;亿信华辰邀请到北京鑫诺律师事务所高级合伙人、管委会副主任武婕将和大家分享《数据入表法律合规…

每天五分钟计算机视觉:经典架构的力量与启示

在深度学习和计算机视觉领域,卷积神经网络(Convolutional Neural Networks,简称CNN)无疑是最为经典的架构之一。近年来,随着研究的不断深入和新架构的不断涌现,许多初学者可能会忽视这些经典架构的重要性。然而,理解并学习这些经典架构,对于我们深入理解卷积神经网络的…

Docker+Anaconda+CUDA+cuDNN

一、导语 因为要复现文献的需求和实验室里师兄想要给我提升能力的多方面因素在一起&#xff0c;所以学习并实现了相关安装。在这里做一个记录&#xff0c;方便日后查看&#xff0c;如果能给其他同学带来便捷就更好了。 在这篇文章中&#xff0c;我的目标是搭建一个可以使用Py…

鸿蒙4.0开发笔记之ArkTS语法的基础数据类型[DevEco Studio开发](七)

文章目录 一、基本数据类型的定义1、变量声明2、数字类型3、字符串类型4、布尔类型5、数组类型6、元组类型7、枚举类型8、联合类型&#xff08;少用&#xff09;9、未知Unkown类型10、未定义和空值类型 二、数据类型的使用1、组件内部声明变量不需要使用let关键字2、使用Divide…