口罩类型分类检测系统:融合FasterNet的改进YOLOv8
1.研究背景与意义
项目参考AAAI Association for the Advancement of Artificial Intelligence
研究背景与意义
近年来,随着全球范围内的突发公共卫生事件的频繁发生,如SARS、H1N1流感和COVID-19等,人们对于个人防护意识的提高以及口罩的广泛使用已成为常态。口罩作为一种重要的个人防护装备,对于预防病毒和细菌的传播具有重要意义。然而,随着市场上口罩种类的不断增多,如医用口罩、N95口罩、普通口罩等,如何准确地对不同类型的口罩进行分类和检测成为了一个重要的问题。
传统的口罩分类和检测方法主要依赖于人工视觉,即由专业人员对口罩进行目测判断。然而,这种方法存在着主观性强、效率低、易受环境和人为因素影响等问题。因此,开发一种自动化的口罩类型分类检测系统具有重要的实际意义。
近年来,深度学习技术的快速发展为解决这一问题提供了新的思路和方法。特别是目标检测领域的YOLO(You Only Look Once)算法,以其高效的实时性和准确性而受到广泛关注。然而,传统的YOLO算法在小目标检测方面存在一定的局限性,而且对于不同类型的口罩进行准确分类的能力也有待提高。
本研究旨在改进YOLOv8算法,结合FasterNet的思想,实现一种高效准确的口罩类型分类检测系统。具体来说,本研究将通过以下几个方面的工作来达到目标:
通过对YOLOv8算法的改进,提高其对小目标的检测能力。传统的YOLO算法在小目标检测方面存在一定的问题,容易漏检或误检。因此,本研究将通过改进网络结构、调整参数设置等方式,提高YOLOv8算法对小目标的检测准确性和稳定性。
引入FasterNet的思想,加速口罩类型分类检测系统的运行速度。FasterNet是一种轻量级的目标检测网络,具有较快的推理速度和较小的模型体积。通过将FasterNet与YOLOv8算法相结合,可以在保证检测准确性的同时,提高系统的实时性和效率。
通过大量的实验验证和评估,验证所提出的改进方法的有效性和可行性。本研究将使用大规模的口罩数据集进行训练和测试,评估系统在口罩类型分类和检测方面的性能表现。同时,与传统的口罩分类和检测方法进行对比,验证所提出方法的优越性和实用性。
本研究的成果将具有重要的实际应用价值。一方面,口罩类型分类检测系统可以广泛应用于公共场所、医疗机构、交通枢纽等地方,实现对不同类型口罩的自动化检测和分类,提高口罩的使用效果和防护效果。另一方面,本研究的方法和思路也可以为其他目标检测领域的研究提供借鉴和参考,推动深度学习技术在实际应用中的发展和应用。
2.图片演示
3.视频演示
口罩类型分类检测系统:融合FasterNet的改进YOLOv8_哔哩哔哩_bilibili
4.数据集的采集&标注和整理
图片的收集
首先,我们需要收集所需的图片。这可以通过不同的方式来实现,例如使用现有的公开数据集MaskDatasets。
labelImg是一个图形化的图像注释工具,支持VOC和YOLO格式。以下是使用labelImg将图片标注为VOC格式的步骤:
(1)下载并安装labelImg。
(2)打开labelImg并选择“Open Dir”来选择你的图片目录。
(3)为你的目标对象设置标签名称。
(4)在图片上绘制矩形框,选择对应的标签。
(5)保存标注信息,这将在图片目录下生成一个与图片同名的XML文件。
(6)重复此过程,直到所有的图片都标注完毕。
由于YOLO使用的是txt格式的标注,我们需要将VOC格式转换为YOLO格式。可以使用各种转换工具或脚本来实现。
下面是一个简单的方法是使用Python脚本,该脚本读取XML文件,然后将其转换为YOLO所需的txt格式。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
classes = [] # 初始化为空列表
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
def convert(size, box):
dw = 1. / size[0]
dh = 1. / size[1]
x = (box[0] + box[1]) / 2.0
y = (box[2] + box[3]) / 2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x * dw
w = w * dw
y = y * dh
h = h * dh
return (x, y, w, h)
def convert_annotation(image_id):
in_file = open('./label_xml\%s.xml' % (image_id), encoding='UTF-8')
out_file = open('./label_txt\%s.txt' % (image_id), 'w') # 生成txt格式文件
tree = ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
classes.append(cls) # 如果类别不存在,添加到classes列表中
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
float(xmlbox.find('ymax').text))
bb = convert((w, h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
xml_path = os.path.join(CURRENT_DIR, './label_xml/')
# xml list
img_xmls = os.listdir(xml_path)
for img_xml in img_xmls:
label_name = img_xml.split('.')[0]
print(label_name)
convert_annotation(label_name)
print("Classes:") # 打印最终的classes列表
print(classes) # 打印最终的classes列表
整理数据文件夹结构
我们需要将数据集整理为以下结构:
-----data
|-----train
| |-----images
| |-----labels
|
|-----valid
| |-----images
| |-----labels
|
|-----test
|-----images
|-----labels
确保以下几点:
所有的训练图片都位于data/train/images目录下,相应的标注文件位于data/train/labels目录下。
所有的验证图片都位于data/valid/images目录下,相应的标注文件位于data/valid/labels目录下。
所有的测试图片都位于data/test/images目录下,相应的标注文件位于data/test/labels目录下。
这样的结构使得数据的管理和模型的训练、验证和测试变得非常方便。
模型训练
Epoch gpu_mem box obj cls labels img_size
1/200 20.8G 0.01576 0.01955 0.007536 22 1280: 100%|██████████| 849/849 [14:42<00:00, 1.04s/it]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|██████████| 213/213 [01:14<00:00, 2.87it/s]
all 3395 17314 0.994 0.957 0.0957 0.0843
Epoch gpu_mem box obj cls labels img_size
2/200 20.8G 0.01578 0.01923 0.007006 22 1280: 100%|██████████| 849/849 [14:44<00:00, 1.04s/it]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|██████████| 213/213 [01:12<00:00, 2.95it/s]
all 3395 17314 0.996 0.956 0.0957 0.0845
Epoch gpu_mem box obj cls labels img_size
3/200 20.8G 0.01561 0.0191 0.006895 27 1280: 100%|██████████| 849/849 [10:56<00:00, 1.29it/s]
Class Images Labels P R mAP@.5 mAP@.5:.95: 100%|███████ | 187/213 [00:52<00:00, 4.04it/s]
all 3395 17314 0.996 0.957 0.0957 0.0845
5.核心代码讲解
5.2 predict.py
class DetectionPredictor(BasePredictor):
def postprocess(self, preds, img, orig_imgs):
preds = ops.non_max_suppression(preds,
self.args.conf,
self.args.iou,
agnostic=self.args.agnostic_nms,
max_det=self.args.max_det,
classes=self.args.classes)
if not isinstance(orig_imgs, list):
orig_imgs = ops.convert_torch2numpy_batch(orig_imgs)
results = []
for i, pred in enumerate(preds):
orig_img = orig_imgs[i]
pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], orig_img.shape)
img_path = self.batch[0][i]
results.append(Results(orig_img, path=img_path, names=self.model.names, boxes=pred))
return results
这个程序文件是一个名为predict.py的文件,它是一个用于预测基于检测模型的类DetectionPredictor的定义。这个类继承自BasePredictor类,并包含了一个postprocess方法用于后处理预测结果。在postprocess方法中,预测结果经过非最大抑制操作,然后将结果转换为Results对象的列表返回。这个文件还导入了一些必要的模块和函数,如BasePredictor类、Results类和ops模块。
5.3 train.py
# Ultralytics YOLO 🚀, AGPL-3.0 license
from copy import copy
import numpy as np
from ultralytics.data import build_dataloader, build_yolo_dataset
from ultralytics.engine.trainer import BaseTrainer
from ultralytics.models import yolo
from ultralytics.nn.tasks import DetectionModel
from ultralytics.utils import LOGGER, RANK
from ultralytics.utils.plotting import plot_images, plot_labels, plot_results
from ultralytics.utils.torch_utils import de_parallel, torch_distributed_zero_first
class DetectionTrainer(BaseTrainer):
def build_dataset(self, img_path, mode='train', batch=None):
gs = max(int(de_parallel(self.model).stride.max() if self.model else 0), 32)
return build_yolo_dataset(self.args, img_path, batch, self.data, mode=mode, rect=mode == 'val', stride=gs)
def get_dataloader(self, dataset_path, batch_size=16, rank=0, mode='train'):
assert mode in ['train', 'val']
with torch_distributed_zero_first(rank):
dataset = self.build_dataset(dataset_path, mode, batch_size)
shuffle = mode == 'train'
if getattr(dataset, 'rect', False) and shuffle:
LOGGER.warning("WARNING ?? 'rect=True' is incompatible with DataLoader shuffle, setting shuffle=False")
shuffle = False
workers = 0
return build_dataloader(dataset, batch_size, workers, shuffle, rank)
def preprocess_batch(self, batch):
batch['img'] = batch['img'].to(self.device, non_blocking=True).float() / 255
return batch
def set_model_attributes(self):
self.model.nc = self.data['nc']
self.model.names = self.data['names']
self.model.args = self.args
def get_model(self, cfg=None, weights=None, verbose=True):
model = DetectionModel(cfg, nc=self.data['nc'], verbose=verbose and RANK == -1)
if weights:
model.load(weights)
return model
def get_validator(self):
self.loss_names = 'box_loss', 'cls_loss', 'dfl_loss'
return yolo.detect.DetectionValidator(self.test_loader, save_dir=self.save_dir, args=copy(self.args))
def label_loss_items(self, loss_items=None, prefix='train'):
keys = [f'{prefix}/{x}' for x in self.loss_names]
if loss_items is not None:
loss_items = [round(float(x), 5) for x in loss_items]
return dict(zip(keys, loss_items))
else:
return keys
def progress_string(self):
return ('\n' + '%11s' *
(4 + len(self.loss_names))) % ('Epoch', 'GPU_mem', *self.loss_names, 'Instances', 'Size')
def plot_training_samples(self, batch, ni):
plot_images(images=batch['img'],
batch_idx=batch['batch_idx'],
cls=batch['cls'].squeeze(-1),
bboxes=batch['bboxes'],
paths=batch['im_file'],
fname=self.save_dir / f'train_batch{ni}.jpg',
on_plot=self.on_plot)
def plot_metrics(self):
plot_results(file=self.csv, on_plot=self.on_plot)
def plot_training_labels(self):
boxes = np.concatenate([lb['bboxes'] for lb in self.train_loader.dataset.labels], 0)
cls = np.concatenate([lb['cls'] for lb in self.train_loader.dataset.labels], 0)
plot_labels(boxes, cls.squeeze(), names=self.data['names'], save_dir=self.save_dir, on_plot=self.on_plot)
if __name__ == '__main__':
args = dict(model='./yolov8-C2f-Faster', data='coco8.yaml', epochs=100)
trainer = DetectionTrainer(overrides=args)
trainer.train()
这个程序文件是一个用于训练检测模型的程序。它使用了Ultralytics YOLO库,并继承了BaseTrainer类。主要包含以下几个部分:
- 导入所需的库和模块。
- 定义了一个名为DetectionTrainer的类,该类继承自BaseTrainer类,并用于训练基于检测模型的任务。
- 类中定义了一些方法,用于构建数据集、构建数据加载器、预处理数据、设置模型属性等。
- 类中还定义了一些用于可视化训练过程和结果的方法,如绘制训练样本、绘制指标、绘制训练标签等。
- 在程序的主函数中,创建了一个DetectionTrainer对象,并调用其train方法进行训练。
该程序文件使用了Ultralytics YOLO库来实现检测模型的训练任务,可以根据提供的参数进行训练,并提供了一些可视化方法来展示训练过程和结果。
5.6 backbone\CSwomTramsformer.py
class CSWinTransformer(nn.Module):
def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000, embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], mlp_ratio=4., qkv_bias=True, qk_scale=None, drop_rate=0., attn_drop_rate=0., drop_path_rate=0., norm_layer=nn.LayerNorm):
super().__init__()
self.num_classes = num_classes
self.depths = depths
self.num_features = self.embed_dim = embed_dim
self.patch_embed = PatchEmbed(
img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim)
self.pos_drop = nn.Dropout(p=drop_rate)
dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule
self.blocks = nn.ModuleList([
CSWinBlock(
dim=embed_dim, reso=img_size // patch_size, num_heads=num_heads[i], mlp_ratio=mlp_ratio,
qkv_bias=qkv_bias, qk_scale=qk_scale, drop=drop_rate, attn_drop=attn_drop_rate,
drop_path=dpr[sum(depths[:i]):sum(depths[:i + 1])], norm_layer=norm_layer,
last_stage=(i == len(depths) - 1))
for i in range(len(depths))])
self.norm = norm_layer(embed_dim)
self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity()
trunc_normal_(self.head.weight, std=0.02)
self.head.bias.data.fill_(0.0)
def forward_features(self, x):
x = self.patch_embed(x)
x = self.pos_drop(x)
for blk in self.blocks:
x = blk(x)
x = self.norm(x) # B L C
return x
def forward(self, x):
x = self.forward_features(x)
x = x.mean(dim=1) if x.ndim > 2 else x
x = self.head(x)
return x
该程序文件是一个用于图像分类的模型CSWin Transformer的实现。CSWin Transformer是一种基于Transformer的图像分类模型,它通过将图像划分为多个窗口,并在每个窗口上应用自注意力机制来捕捉图像的全局信息。该模型包含了CSWinBlock、Mlp、LePEAttention、Merge_Block等多个模块,用于构建CSWin Transformer的不同部分。其中,CSWinBlock是CSWin Transformer的基本块,它包含了自注意力机制和多层感知机。Mlp是多层感知机的实现,用于对输入进行非线性变换。LePEAttention是基于位置编码的注意力机制,用于计算输入的注意力权重。Merge_Block是用于将不同分辨率的特征图合并的模块。整个模型的输入是一张图像,输出是图像的分类结果。
6.系统整体结构
整体功能和构架概述:
该项目是一个口罩类型分类检测系统,主要包括以下几个部分:
-
模型训练:train.py文件用于训练口罩类型分类检测模型,使用了YOLOv8 PyTorch模型和Ultralytics YOLO库。
-
模型导出:export.py文件用于将训练好的模型导出为其他格式,如TorchScript、ONNX、OpenVINO等。
-
图形界面:ui.py文件使用PyQt5库实现了一个图形界面,用于展示口罩分类识别的结果。
-
模型架构:backbone文件夹中包含了多个模型架构的实现文件,如ConvNeXtV2、CSWin Transformer、EfficientFormerV2等。
-
辅助模块:extra_modules文件夹中包含了一些辅助模块的实现文件,如AFPN、Attention、Dynamic Snake Conv等。
-
模型相关:models文件夹中包含了一些模型相关的实现文件,如YOLO模型、TF模型等。
-
工具函数:utils文件夹中包含了多个工具函数的实现文件,如数据增强、损失函数、数据集处理等。
下表整理了每个文件的功能:
文件路径 | 功能 |
---|---|
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\export.py | 导出YOLOv8模型为其他格式的文件 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\predict.py | 对输入的图片进行口罩分类识别 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\train.py | 训练口罩类型分类检测模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\ui.py | 实现口罩分类系统的图形界面 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\convnextv2.py | 实现ConvNeXt V2模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\CSwomTramsformer.py | 实现CSWin Transformer模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\EfficientFormerV2.py | 实现EfficientFormer V2模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\efficientViT.py | 实现EfficientViT模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\fasternet.py | 实现FasterNet模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\lsknet.py | 实现LSKNet模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\repvit.py | 实现RepVIT模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\revcol.py | 实现RevCoL模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\SwinTransformer.py | 实现Swin Transformer模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\backbone\VanillaNet.py | 实现VanillaNet模型 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\extra_modules\afpn.py | 实现AFPN模块 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\extra_modules\attention.py | 实现注意力机制模块 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\extra_modules\block.py | 实现基本块模块 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\extra_modules\dynamic_snake_conv.py | 实现动态蛇形卷积模块 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\extra_modules\head.py | 实现模型的头部模块 |
E:\视觉项目\shop\口罩类型分类检测系统:融合FasterNet的改进YOLOv8\code\extra_modules\kernel_warehouse.py | 实现卷积核仓库模块 |
7.YOLOv8简介
YOLOv8网络架构
本文将以与YOLOv5做对比的方式,从四个部分介绍YOLOv8的网络结构,即主干网络(Backbone)、颈部(Neck)、头部(Head)和预测层(Prediction)。
主干网络部分:YOLOv8主干网络采用了CSP架构,但与YOLOv5不同的是,使用了C2f模块7替代C3模块,并将每个阶段的块数从[3,6,9,3]调整为[3,6,6,3]。此外,对于版本“x”,其深度因子也从常规的1.33调整为1.0,stem卷积也从k=6的卷积改为k=3的卷积,以进一步减轻模型负担。C2f模块的设计参考了C3模块和ELAN的思想,使得YOLOv8在保持轻量化的同时获得了更丰富的梯度流信息,如图所示。此外,YOLOv8仍然采用了在YOLOv5等架构中使用的SPPF模块,其负责对不同尺度的特征图进行处理,提取出更多丰富的特征信息。
颈部部分:YOLOv8的颈部部分仍然采用了PAN-FPN的思想。该架构结合了特征金字塔网络(FPN)和路径聚合网络(PAN),其中FPN通过自上而下的方式传递显著的语义特征,而PAN则通过自下而上的方式传递显著的定位特征。这种结合进一步提高了特征提取的能力。不过,YO-LOv8将top down上采样之前的l×1卷积去除,并将Back-bone不同阶段输出的特征直接送入上采样操作。同时,C3模块和RepBlock被替换为C2f模块,以实现更进一步的轻量化。其结构图如图所示。
头部部分:YOLOv8从原先的耦合头变成了解耦头I8],并且从 YOLOv5的Anchor-Based变成了Anchor-Free,不再有之前的objectness 分支,只有解耦的分类和回归分支,并且其回归分支使用了Distribution Focal Loss 中提出的积分形式表示法,同时由于使用了DFL的思想,因此回归头的通道数也变成了4*reg_max的形式。Head部分具体结构如图所示:
预测部分:YOLOv8主要有两点主要变化:
损失函数:YOLOv8和之前的版本使用不同的分类损失函数来训练目标检测模型。YOLOv8采用VFLLoss作为分类损失函数,而之前的版本则使用DFLLoss和CIOU Loss的组合作为分类损失函数。VFLLoss是一种基于向量余弦相似度的损失函数,能够有效地对齐模型输出和真实标签之间的向量表示。而 DFLLoss和CIOU Loss则是基于距离的损失函数,能够更好地优化物体边界框的位置和大小预测。通过采用不同的分类损失函数,YOLOv8能够在准确性和速度方面都取得很好的表现。
样本匹配:YOLOv8使用了Task-Aligned Assigner匹配方式来匹配正负样本,并且放弃了之前的IOU匹配或者单边比例的分配方式。这种匹配方式可以更好地适应各种形状和尺寸的物体,从而提高了模型的检测能力。同时,YO-LOv8也是一个无锚模型,即抛弃Anchor Base转而投身An-chor Free。它不再依赖预定义的锚框,而是直接预测对象的中心位置。这种无锚点检测方法可以减少盒预测的数量,从而加快非最大值抑制(NMS)的速度,并且能够更好地适应不同尺度的检测任务。而针对正负样本匹配的多尺度分配问题,YOLOv8采用了和YOLOv6相同的TOOD策略,即一种动态标签分配方法解决。
8.FasterNet简介
鉴于新型PConv和现成的PWConv作为主要的算子,进一步提出FasterNet,这是一个新的神经网络家族,运行速度非常快,对许多视觉任务非常有效。作者的目标是使体系结构尽可能简单,使其总体上对硬件友好。
在图中展示了整体架构。它有4个层次级,每个层次级前面都有一个嵌入层(步长为4的常规4×4卷积)或一个合并层(步长为2的常规2×2卷积),用于空间下采样和通道数量扩展。每个阶段都有一堆FasterNet块。作者观察到,最后两个阶段中的块消耗更少的内存访问,并且倾向于具有更高的FLOPS,因此,放置了更多FasterNet块,并相应地将更多计算分配给最后两个阶段。每个FasterNet块有一个PConv层,后跟2个PWConv(或Conv 1×1)层。它们一起显示为倒置残差块,其中中间层具有扩展的通道数量,并且放置了Shorcut以重用输入特征。
标准化和激活层对于高性能神经网络也是不可或缺的。然而,许多先前的工作在整个网络中过度使用这些层,这可能会限制特征多样性,从而损害性能。它还可以降低整体计算速度。相比之下,只将它们放在每个中间PWConv之后,以保持特征多样性并实现较低的延迟。
使用批次归一化(BN)代替其他替代方法。BN的优点是,它可以合并到其相邻的Conv层中,以便更快地进行推断,同时与其他层一样有效。对于激活层,根据经验选择了GELU用于较小的FasterNet变体,而ReLU用于较大的FasterNet变体,同时考虑了运行时间和有效性。最后三个层,即全局平均池化、卷积1×1和全连接层,一起用于特征转换和分类。
9.PConv
参考该博客提出的一种简单的PConv,以同时减少计算冗余和内存访问。图4中的左下角说明了PConv的工作原理。它只需在输入通道的一部分上应用常规Conv进行空间特征提取,并保持其余通道不变。对于连续或规则的内存访问,将第一个或最后一个连续的通道视为整个特征图的代表进行计算。在不丧失一般性的情况下认为输入和输出特征图具有相同数量的通道。因此,PConv的FLOPs仅对于典型的r=1/4 ,PConv的FLOPs只有常规Conv的1/16。此外,PConv的内存访问量较小,即:对于r=1/4,其仅为常规Conv的1/4。
为了充分有效地利用来自所有通道的信息,进一步将逐点卷积(PWConv)附加到PConv。它们在输入特征图上的有效感受野看起来像一个T形Conv,与均匀处理补丁的常规Conv相比,它更专注于中心位置。
为了证明这个T形感受野的合理性,首先通过计算位置的Frobenius范数来评估每个位置的重要性。假设,如果一个职位比其他职位具有更大的Frobenius范数,则该职位往往更重要。对于正则Conv滤波器,位置处的Frobenius范数由计算,其中,作者认为一个显著位置是具有最大Frobenius范数的位置。然后,在预训练的ResNet18中集体检查每个过滤器,找出它们的显著位置,并绘制显著位置的直方图。图6中的结果表明,中心位置是过滤器中最常见的突出位置。换句话说,中心位置的权重比周围的更重。这与集中于中心位置的T形计算一致。虽然T形卷积可以直接用于高效计算,但作者表明,将T形卷积分解为PConv和PWConv更好,因为该分解利用了滤波器间冗余并进一步节省了FLOPs。
10.训练结果可视化分析
评价指标
train损失:train/box_loss, train/obj_loss,train/cls_loss
精确率和召回率指标:metrics/precision,metrics/recall
平均精度 (mAP) : metrics/mAP_0.5,metrics/mAP_0.5:0.95
验证损失: val/box_loss, val/obj_loss,val/cls_loss
学习率: x/lr0, x/lr1,x/lr2
训练结果可视化
为了分析这些数据,我们将为这些指标创建可视化并讨论它们的含义。我将首先绘制各个时期的这些指标,以了解模型的性能在训练过程中如何变化。该分析将涵盖:
训练和验证阶段的损失减少趋势。
精度、召回率和 mAP 的变化,表明模型正确识别和分类口罩类型的能力。
跨时期的学习率调整。
让我们首先可视化这些指标。
import matplotlib.pyplot as plt
# Set up the figure and axes for multiple plots
fig, axes = plt.subplots(3, 2, figsize=(15, 15))
# Plotting training losses
axes[0, 0].plot(data['epoch'], data['train/box_loss'], label='Box Loss')
axes[0, 0].plot(data['epoch'], data['train/obj_loss'], label='Object Loss')
axes[0, 0].plot(data['epoch'], data['train/cls_loss'], label='Class Loss')
axes[0, 0].set_title('Training Losses')
axes[0, 0].set_xlabel('Epoch')
axes[0, 0].set_ylabel('Loss')
axes[0, 0].legend()
# Plotting precision and recall
axes[0, 1].plot(data['epoch'], data['metrics/precision'], label='Precision')
axes[0, 1].plot(data['epoch'], data['metrics/recall'], label='Recall')
axes[0, 1].set_title('Precision and Recall')
axes[0, 1].set_xlabel('Epoch')
axes[0, 1].set_ylabel('Value')
axes[0, 1].legend()
# Plotting mAP
axes[1, 0].plot(data['epoch'], data['metrics/mAP_0.5'], label='mAP@0.5')
axes[1, 0].plot(data['epoch'], data['metrics/mAP_0.5:0.95'], label='mAP@0.5:0.95')
axes[1, 0].set_title('Mean Average Precision (mAP)')
axes[1, 0].set_xlabel('Epoch')
axes[1, 0].set_ylabel('mAP')
axes[1, 0].legend()
# Plotting validation losses
axes[1, 1].plot(data['epoch'], data['val/box_loss'], label='Box Loss')
axes[1, 1].plot(data['epoch'], data['val/obj_loss'], label='Object Loss')
axes[1, 1].plot(data['epoch'], data['val/cls_loss'], label='Class Loss')
axes[1, 1].set_title('Validation Losses')
axes[1, 1].set_xlabel('Epoch')
axes[1, 1].set_ylabel('Loss')
axes[1, 1].legend()
# Plotting learning rates
axes[2, 0].plot(data['epoch'], data['x/lr0'], label='LR0')
axes[2, 0].plot(data['epoch'], data['x/lr1'], label='LR1')
axes[2, 0].plot(data['epoch'], data['x/lr2'], label='LR2')
axes[2, 0].set_title('Learning Rates')
axes[2, 0].set_xlabel('Epoch')
axes[2, 0].set_ylabel('Learning Rate')
axes[2, 0].legend()
# Adjust layout
plt.tight_layout()
# Show the plots
plt.show()
训练结果分析
训练损失:第一个图显示训练损失(框损失、对象损失和类损失)随着时间的推移而减少,这是一个积极的信号,表明模型正在有效地学习。损失值的稳定下降通常表明训练过程收敛良好。
精确率和召回率:这些指标对于评估模型的性能至关重要。精度衡量的是阳性预测的准确性,而召回率衡量的是模型正确识别的实际阳性的百分比。理想情况下,两者都应随着时间的推移而增加,表明模型准确性及其检测相关特征的能力得到提高。
平均精度 (mAP):mAP 是对象检测模型中使用的综合指标。它结合了精度和召回率,并针对不同的 IoU(并集交集)阈值进行计算。mAP@0.5 和 mAP@0.5:0.95 值概述了模型在这些阈值上的准确性。这些值的增长趋势是可取的,这表明模型在准确检测和分类对象方面越来越熟练。
验证损失:与训练损失类似,理想情况下验证损失应该减少。然而,它们可以让我们深入了解模型对未见过的数据的推广效果。训练和验证损失之间的显着差距可能表明过度拟合。
学习率:学习率(LR0、LR1、LR2)的变化可能是训练期间使用的学习率计划或自适应学习率方法的一部分。调整学习率是提高训练效率和收敛性的常用技术。
训练和验证指标之间的任何差异都可以提供对潜在过度拟合或欠拟合的洞察。学习率图提供了有关如何根据自适应学习策略管理训练过程的见解。
11.系统整合
参考博客《口罩类型分类检测系统:融合FasterNet的改进YOLOv8》
12.参考文献
[1]贾世娜.基于改进YOLOv5的小目标检测算法研究[D].2022.
[2]He, Kaiming,Zhang, Xiangyu,Ren, Shaoqing,等.Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition[J].IEEE Transactions on Pattern Analysis and Machine Intelligence.2015,37(9).1904-1916.DOI:10.1109/TPAMI.2015.2389824 .
[3]Everingham, Mark,Eslami, S. M. Ali,Van Gool, Luc,等.The PASCAL Visual Object Classes Challenge: A Retrospective[J].International Journal of Computer Vision.2015,111(1).98-136.DOI:10.1007/s11263-014-0733-5 .
[4]Felzenszwalb, Pedro F.,Girshick, Ross B.,McAllester, David,等.Object Detection with Discriminatively Trained Part-Based Models[J].IEEE Transactions on Pattern Analysis and Machine Intelligence.2010,32(9).1627-1645.
[5]Mark Everingham,Luc Van Gool,Christopher K. I. Williams,等.The Pascal Visual Object Classes (VOC) Challenge[J].International Journal of Computer Vision.2009,88(2).303-338.DOI:10.1007/s11263-009-0275-4 .
[6]Viola P,Jones MJ.Robust real-time face detection[J].International Journal of Computer Vision.2004,57(2).137-154.
[7]Ojala, T.,Pietikainen, M.,Maenpaa, T..Multiresolution gray-scale and rotation invariant texture classification with local binary patterns[J].Pattern Analysis & Machine Intelligence, IEEE Transactions on.2002,24(7).971-987.DOI:10.1109/TPAMI.2002.1017623 .
[8]Freund Y.,Schapire RE..A Decision-Theoretic Generalization of on-Line Learning and an Application to Boosting[J].Journal of Computer and System Sciences.1997,55(1).119-139.
[9]CorinnaCortes,VladimirVapnik.Support-Vector Networks[J].Machine Learning.1995,20(3).273-297.DOI:10.1023/A:1022627411411 .
[10]Dalai, N.,Triggs, B..Histograms of oriented gradients for human detection[C].2005.
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!