【改进YOLOv8】融合可扩张残差(DWR)注意力模块的小麦病害检测系统

1.研究背景与意义

项目参考AAAI Association for the Advancement of Artificial Intelligence

研究背景与意义:

随着计算机视觉技术的快速发展,深度学习在图像识别和目标检测领域取得了巨大的突破。其中,YOLO(You Only Look Once)是一种非常流行的目标检测算法,以其快速且准确的特点受到了广泛关注。然而,YOLO算法在小目标检测和遮挡目标检测方面仍然存在一些挑战。

在农业领域,小麦病害的检测对于保障粮食安全和提高农作物产量具有重要意义。传统的小麦病害检测方法需要大量的人力和时间,效率低下且易受主观因素的影响。因此,开发一种高效准确的小麦病害检测系统对于农业生产具有重要意义。

目前,基于YOLO算法的小麦病害检测系统已经取得了一定的成果。然而,由于小麦病害通常具有较小的目标尺寸和复杂的纹理特征,传统的YOLO算法在小麦病害检测中仍然存在一些问题。例如,由于YOLO算法的多尺度特性,较小的目标往往容易被忽略或错误分类。此外,遮挡目标的检测也是一个具有挑战性的问题。

因此,本研究旨在改进YOLOv8算法,提出一种融合可扩张残差(DWR)注意力模块的小麦病害检测系统。该系统将利用DWR注意力模块来增强YOLOv8算法对小目标和遮挡目标的检测能力。DWR注意力模块通过引入可扩张残差结构,能够更好地捕捉目标的细节信息,并提高目标的检测精度。

本研究的意义主要体现在以下几个方面:

首先,通过改进YOLOv8算法,提出一种融合DWR注意力模块的小麦病害检测系统,可以提高小目标和遮挡目标的检测准确率。这将有助于农业生产中对小麦病害的快速准确检测,提高农作物的产量和质量。

其次,DWR注意力模块的引入可以增强目标的细节信息捕捉能力,提高目标的检测精度。这对于小麦病害的检测尤为重要,因为小麦病害通常具有复杂的纹理特征,传统的目标检测算法往往难以准确识别。

此外,本研究的成果还可以为其他农作物的病害检测提供借鉴和参考。虽然本研究主要关注小麦病害检测,但所提出的改进算法和注意力模块可以应用于其他农作物的病害检测,提高农业生产的效率和质量。

综上所述,本研究旨在改进YOLOv8算法,提出一种融合DWR注意力模块的小麦病害检测系统。该系统的研究意义主要体现在提高小目标和遮挡目标的检测准确率,增强目标的细节信息捕捉能力,以及为其他农作物的病害检测提供借鉴和参考。这将有助于提高农业生产的效率和质量,保障粮食安全。

2.图片演示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.视频演示

【改进YOLOv8】融合可扩张残差(DWR)注意力模块的小麦病害检测系统_哔哩哔哩_bilibili

4.数据集的采集&标注和整理

图片的收集

首先,我们需要收集所需的图片。这可以通过不同的方式来实现,例如使用现有的公开数据集WheatDatasets。

在这里插入图片描述

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
from ultralytics.engine.predictor import BasePredictor
from ultralytics.engine.results import Results
from ultralytics.utils import ops

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方法用于后处理预测结果并返回Results对象的列表。

在postprocess方法中,首先对预测结果进行非最大抑制操作,根据设定的置信度阈值和IOU阈值进行筛选,并根据设定的参数进行类别筛选和边界框缩放操作。然后,将原始图像、图像路径、类别名称和筛选后的边界框信息作为参数,创建Results对象并添加到结果列表中。

该文件还包含了一个示例用法,通过创建DetectionPredictor对象并传入相关参数,可以进行预测操作。

该程序文件使用了Ultralytics YOLO库,遵循AGPL-3.0许可证。

5.4 backbone\convnextv2.py
import torch
import torch.nn as nn
import torch.nn.functional as F
from timm.models.layers import trunc_normal_, DropPath

class LayerNorm(nn.Module):
    def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last"):
        super().__init__()
        self.weight = nn.Parameter(torch.ones(normalized_shape))
        self.bias = nn.Parameter(torch.zeros(normalized_shape))
        self.eps = eps
        self.data_format = data_format
        if self.data_format not in ["channels_last", "channels_first"]:
            raise NotImplementedError 
        self.normalized_shape = (normalized_shape, )
    
    def forward(self, x):
        if self.data_format == "channels_last":
            return F.layer_norm(x, self.normalized_shape, self.weight, self.bias, self.eps)
        elif self.data_format == "channels_first":
            u = x.mean(1, keepdim=True)
            s = (x - u).pow(2).mean(1, keepdim=True)
            x = (x - u) / torch.sqrt(s + self.eps)
            x = self.weight[:, None, None] * x + self.bias[:, None, None]
            return x

class GRN(nn.Module):
    def __init__(self, dim):
        super().__init__()
        self.gamma = nn.Parameter(torch.zeros(1, 1, 1, dim))
        self.beta = nn.Parameter(torch.zeros(1, 1, 1, dim))

    def forward(self, x):
        Gx = torch.norm(x, p=2, dim=(1,2), keepdim=True)
        Nx = Gx / (Gx.mean(dim=-1, keepdim=True) + 1e-6)
        return self.gamma * (x * Nx) + self.beta + x

class Block(nn.Module):
    def __init__(self, dim, drop_path=0.):
        super().__init__()
        self.dwconv = nn.Conv2d(dim, dim, kernel_size=7, padding=3, groups=dim)
        self.norm = LayerNorm(dim, eps=1e-6)
        self.pwconv1 = nn.Linear(dim, 4 * dim)
        self.act = nn.GELU()
        self.grn = GRN(4 * dim)
        self.pwconv2 = nn.Linear(4 * dim, dim)
        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()

    def forward(self, x):
        input = x
        x = self.dwconv(x)
        x = x.permute(0, 2, 3, 1)
        x = self.norm(x)
        x = self.pwconv1(x)
        x = self.act(x)
        x = self.grn(x)
        x = self.pwconv2(x)
        x = x.permute(0, 3, 1, 2)

        x = input + self.drop_path(x)
        return x

class ConvNeXtV2(nn.Module):
    def __init__(self, in_chans=3, num_classes=1000, 
                 depths=[3, 3, 9, 3], dims=[96, 192, 384, 768], 
                 drop_path_rate=0., head_init_scale=1.
                 ):
        super().__init__()
        self.depths = depths
        self.downsample_layers = nn.ModuleList()
        stem = nn.Sequential(
            nn.Conv2d(in_chans, dims[0], kernel_size=4, stride=4),
            LayerNorm(dims[0], eps=1e-6, data_format="channels_first")
        )
        self.downsample_layers.append(stem)
        for i in range(3):
            downsample_layer = nn.Sequential(
                    LayerNorm(dims[i], eps=1e-6, data_format="channels_first"),
                    nn.Conv2d(dims[i], dims[i+1], kernel_size=2, stride=2),
            )
            self.downsample_layers.append(downsample_layer)

        self.stages = nn.ModuleList()
        dp_rates=[x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] 
        cur = 0
        for i in range(4):
            stage = nn.Sequential(
                *[Block(dim=dims[i], drop_path=dp_rates[cur + j]) for j in range(depths[i])]
            )
            self.stages.append(stage)
            cur += depths[i]

        self.norm = nn.LayerNorm(dims[-1], eps=1e-6)
        self.head = nn.Linear(dims[-1], num_classes)

        self.apply(self._init_weights)
        self.channel = [i.size(1) for i in self.forward(torch.randn(1, 3, 640, 640))]

    def _init_weights(self, m):
        if isinstance(m, (nn.Conv2d, nn.Linear)):
            trunc_normal_(m.weight, std=.02)
            nn.init.constant_(m.bias, 0)

    def forward(self, x):
        res = []
        for i in range(4):
            x = self.downsample_layers[i](x)
            x = self.stages[i](x)
            res.append(x)
        return res

该程序文件是一个用于构建ConvNeXt V2模型的Python脚本。它定义了一系列的类和函数,用于构建不同规模的ConvNeXt V2模型。

文件中定义了以下类和函数:

  1. LayerNorm类:支持两种数据格式(channels_last和channels_first)的LayerNorm层。

  2. GRN类:全局响应归一化(Global Response Normalization)层。

  3. Block类:ConvNeXtV2模型的基本块。

  4. ConvNeXtV2类:ConvNeXt V2模型的主体部分。

  5. update_weight函数:用于更新模型权重。

  6. convnextv2_atto函数:构建ConvNeXt V2模型(规模为atto)的函数。

  7. convnextv2_femto函数:构建ConvNeXt V2模型(规模为femto)的函数。

  8. convnextv2_pico函数:构建ConvNeXt V2模型(规模为pico)的函数。

  9. convnextv2_nano函数:构建ConvNeXt V2模型(规模为nano)的函数。

  10. convnextv2_tiny函数:构建ConvNeXt V2模型(规模为tiny)的函数。

  11. convnextv2_base函数:构建ConvNeXt V2模型(规模为base)的函数。

  12. convnextv2_large函数:构建ConvNeXt V2模型(规模为large)的函数。

  13. convnextv2_huge函数:构建ConvNeXt V2模型(规模为huge)的函数。

这些函数可以根据输入的参数构建不同规模的ConvNeXt V2模型,并且可以选择加载预训练的权重。

5.5 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.feature_info = [dict(num_chs=embed_dim, reduction=0, module='head')]
        self.head = nn.Linear(embed_dim, num_classes) if num_classes > 0 else nn.Identity()

        trunc_normal_(self.head.weight, std=.02)
        zeros_(self.head.bias)

    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)  # B C
        if self.num_classes > 0:
            x = self.head(x)
        return x

这个程序文件是一个用于图像分类的CSWin Transformer模型。它实现了CSWinBlock和LePEAttention两个模块,并定义了Mlp和Merge_Block两个辅助模块。CSWinBlock模块是CSWin Transformer的基本构建块,它包含了一个多头注意力机制和一个多层感知机,用于处理输入特征。LePEAttention模块是一个特殊的注意力机制,它使用了局部位置编码(Local Position Encoding)来增强注意力的表达能力。Mlp模块是一个多层感知机,用于对输入特征进行非线性变换。Merge_Block模块是一个用于特征融合的模块,它使用了一个卷积层和一个归一化层来将多个分支的特征融合成一个输出特征。整个模型的输入是一个图像,输出是图像的分类结果。

5.6 backbone\EfficientFormerV2.py
import torch
import torch.nn as nn
import torch.nn.functional as F
import math
from typing import Dict
import itertools
import numpy as np
from timm.models.layers import DropPath, trunc_normal_, to_2tuple

class Attention4D(torch.nn.Module):
    def __init__(self, dim=384, key_dim=32, num_heads=8,
                 attn_ratio=4,
                 resolution=7,
                 act_layer=nn.ReLU,
                 stride=None):
        super().__init__()
        self.num_heads = num_heads
        self.scale = key_dim ** -0.5
        self.key_dim = key_dim
        self.nh_kd = nh_kd = key_dim * num_heads

        if stride is not None:
            self.resolution = math.ceil(resolution / stride)
            self.stride_conv = nn.Sequential(nn.Conv2d(dim, dim, kernel_size=3, stride=stride, padding=1, groups=dim),
                                             nn.BatchNorm2d(dim), )
            self.upsample = nn.Upsample(scale_factor=stride, mode='bilinear')
        else:
            self.resolution = resolution
            self.stride_conv = None
            self.upsample = None

        self.N = self.resolution ** 2
        self.N2 = self.N
        self.d = int(attn_ratio * key_dim)
        self.dh = int(attn_ratio * key_dim) * num_heads
        self.attn_ratio = attn_ratio
        h = self.dh + nh_kd * 2
        self.q = nn.Sequential(nn.Conv2d(dim, self.num_heads * self.key_dim, 1),
                               nn.BatchNorm2d(self.num_heads * self.key_dim), )
        self.k = nn.Sequential(nn.Conv2d(dim, self.num_heads * self.key_dim, 1),
                               nn.BatchNorm2d(self.num_heads * self.key_dim), )
        self.v = nn.Sequential(nn.Conv2d(dim, self.num_heads * self.d, 1),
                               nn.BatchNorm2d(self.num_heads * self.d),
                               )
        self.v_local = nn.Sequential(nn.Conv2d(self.num_heads * self.d, self.num_heads * self.d,
                                               kernel_size=3, stride=1, padding=1, groups=self.num_heads * self.d),
                                     nn.BatchNorm2d(self.num_heads * self.d), )
        self.talking_head1 = nn.Conv2d(self.num_heads, self.num_heads, kernel_size=1, stride=1, padding=0)
        self.talking_head2 = nn.Conv2d(self.num_heads, self.num_heads, kernel_size=1, stride=1, padding=0)

        self.proj = nn.Sequential(act_layer(),
                                  nn.Conv2d(self.dh, dim, 1),
                                  nn.BatchNorm2d(dim), )

        points = list(itertools.product(range(self.resolution), range(self.resolution)))
        N = len(points)
        attention_offsets = {}

EfficientFormerV2.py是一个用于图像分类的模型文件。该文件定义了EfficientFormerV2模型的结构和各个组件的实现。

EfficientFormerV2模型是基于EfficientNet和Transformer的结构进行改进的。它包含了一个Embedding模块、多个EfficientFormerBlock模块和一个分类头部。

Embedding模块用于将输入图像进行特征提取和编码。它包含了一个卷积层和一个归一化层。

EfficientFormerBlock模块是EfficientFormerV2模型的核心组件,用于构建多层的Transformer模块。每个EfficientFormerBlock模块包含了多个Attention4D模块和一个MLP模块。

Attention4D模块是一个四维的注意力机制模块,用于捕捉图像特征之间的关系。它包含了多个卷积层和归一化层。

MLP模块是一个多层感知机模块,用于对特征进行非线性变换和映射。

分类头部用于将特征映射到类别概率分布。

整个EfficientFormerV2模型的结构是一个串联的模块序列,其中每个EfficientFormerBlock模块之间使用残差连接进行连接。最后一个EfficientFormerBlock模块的输出经过分类头部进行分类。

EfficientFormerV2模型的输入是一个图像张量,输出是一个类别概率分布张量。

6.系统整体结构

根据以上分析,该程序是一个用于视觉项目中小麦病害检测系统的工程。它包含了多个文件,每个文件都有不同的功能,用于实现整个系统的各个模块和功能。

下面是每个文件的功能的整理:

文件路径功能
export.py导出YOLOv8模型为其他格式的文件
predict.py进行目标检测的预测操作
ui.py创建图形用户界面,并实现与用户的交互
backbone\convnextv2.py构建ConvNeXt V2模型
backbone\CSwomTramsformer.py构建CSWin Transformer模型
backbone\EfficientFormerV2.py构建EfficientFormerV2模型
backbone\efficientViT.py构建EfficientViT模型
backbone\fasternet.py构建FasterNet模型
backbone\lsknet.py构建LSKNet模型
backbone\repvit.py构建RepVIT模型
backbone\revcol.py构建RevCoL模型
backbone\SwinTransformer.py构建Swin Transformer模型
backbone\VanillaNet.py构建VanillaNet模型
extra_modules\afpn.py实现AFPN模块
extra_modules\attention.py实现注意力机制模块
extra_modules\block.py实现基本块模块
extra_modules\dynamic_snake_conv.py实现动态蛇形卷积模块
extra_modules\head.py实现模型的头部模块
extra_modules\kernel_warehouse.py存储不同模型的卷积核
extra_modules\orepa.py实现OREPA模块
extra_modules\rep_block.py实现REP模块
extra_modules\RFAConv.py实现RFAConv模块
extra_modules_init_.py初始化extra_modules模块
extra_modules\ops_dcnv3\setup.py安装DCNv3模块
extra_modules\ops_dcnv3\test.py测试DCNv3模块
extra_modules\ops_dcnv3\functions\dcnv3_func.py实现DCNv3模块的函数
extra_modules\ops_dcnv3\functions_init_.py初始化DCNv3模块的函数
extra_modules\ops_dcnv3\modules\dcnv3.py实现DCNv3模块
extra_modules\ops_dcnv3\modules_init_.py初始化DCNv3模块
models\common.py包含通用的模型函数和类
models\experimental.py包含实验性的模型函数和类
models\tf.py包含TensorFlow模型函数和类
models\yolo.py包含YOLO模型函数和类
models_init_.py初始化models模块
utils\activations.py包含各种激活函数
utils\augmentations.py包含数据增强函数
utils\autoanchor.py包含自动锚框生成函数
utils\autobatch.py包含自动批处理函数
utils\callbacks.py包含回调函数
utils\datasets.py包含数据集处理函数
utils\downloads.py包含下载函数
utils\general.py包含通用的辅助函数
utils\loss.py包含损失函数
utils\metrics.py包含评估指标函数
utils\plots.py包含绘图函数
utils\torch_utils.py包含PyTorch的辅助函数
utils_init_.py初始化utils模块
utils\aws\resume.py实现AWS的恢复函数
utils\aws_init_.py初始化AWS模块
utils\flask_rest_api\example_request.py实现Flask REST API的示例请求
utils\flask_rest_api\restapi.py实现Flask REST API的功能
utils\loggers_init_.py初始化log

7.YOLOv8简介

Yolov8网络模型

Yolov8n的网络分为输入端、主干网( Back-bone) 、Neck模块和输出端4个部分(图4)。输
人端主要有马赛克( Mosaic)数据增强、自适应锚框计算和自适应灰度填充。主干网有Conv、C2和SPPF结构,其中,C2r模块是对残差特征进行学习的主要模块,该模块仿照Yolov7的ELAN结构,通过更多的分支跨层连接,丰富了模型的梯度流,可形成一个具有更强特征表示能力的神经网络模
块。Neck模块采用PAN ( path aggregation nelwOrk ,结构,可加强网络对不同缩放尺度对象特征融合的
能力。输出端将分类和检测过程进行解耦,主要包括损失计算和目标检测框筛选,其中,损失计算过程主要包括正负样本分配策略和 Loss计算,Yolov8n 网络主要使用TaskAlignedAssignerl 10]方法,即根据分类与回归的分数加权结果选择正样本;Loss计算包括分类和回归2个分支,无Ob-jecIness分支。分类分支依然采用BCE Loss,回归分支则使用了Distribution Focal Loss!11〕和CIOU( complele inlersection over union)损失函数。
在这里插入图片描述

8.可扩张残差(DWR)注意力模块

当前的许多工作直接采用多速率深度扩张卷积从一个输入特征图中同时捕获多尺度上下文信息,从而提高实时语义分割的特征提取效率。 然而,这种设计可能会因为结构和超参数的不合理而导致多尺度上下文信息的访问困难。 为了降低绘制多尺度上下文信息的难度,我们提出了一种高效的多尺度特征提取方法,该方法分解了原始的单步特征提取方法方法分为两个步骤,区域残差-语义残差。 在该方法中,多速率深度扩张卷积在特征提取中发挥更简单的作用:根据第一步提供的每个简明区域形式特征图,在第二步中使用一个所需的感受野执行简单的基于语义的形态过滤 一步,提高他们的效率。 此外,扩张率和扩张卷积的容量每个网络阶段都经过精心设计,以充分利用所有可以实现的区域形式的特征图。 因此,我们分别为高层和低层网络设计了一种新颖的扩张式残差(DWR)模块和简单倒置残差(SIR)模块。
在这里插入图片描述

首先,该博客引入了一个Dilation-wise Residual(DWR)模块,用于提取网络高层的特征,如图2a所示。多分支结构用于扩展感受野,其中每个分支采用不同空洞率的空洞深度卷积。
然后,专门设计了一个Simple Inverted Residual(SIR)模块来提取网络低层的特征,如图2b所示。该模块仅具有3×3的微小感受野,但使用inverted bottleneck式结构来扩展通道数量,确保更强的特征提取能力。
最后,基于DWR和SIR模块,构建了一个编码器-解码器风格的网络DWRSeg,其中解码器采用了简单的类似FCN的结构。解码器使用来自最后两个阶段的强语义信息直接对特征图进行上采样,然后将它们与来自较低阶段的特征图(包含丰富的详细信息)拼接起来,以进行最终预测。
在这里插入图片描述

9.训练结果可视化分析

评价指标

epoch:训练过程中的epoch号。
train/box_loss、、、train/obj_loss:train/cls_loss训练期间边界框、对象和类预测的损失。
metrics/precision、metrics/recall、metrics/mAP_0.5、metrics/mAP_0.5:0.95:不同 IoU(并集交集)阈值下的精度、召回率和平均精度 (mAP)。
val/box_loss、val/obj_loss、val/cls_loss:边界框、对象和类的验证损失。
x/lr0, x/lr1, x/lr2:网络不同部分的学习率。

训练结果可视化

我将通过为这些指标创建可视化来进行详细分析,以了解模型在训练期间的性能和行为。这将包括损失指标的趋势、精确度、召回率和 mAP 分数的改进,以及学习率在不同时期的变化。让我们首先可视化训练和验证损失。

import matplotlib.pyplot as plt

# Setting up the plots
fig, ax = plt.subplots(3, 1, figsize=(12, 18))

# Plotting training losses
ax[0].plot(data['epoch'], data['train/box_loss'], label='Box Loss', color='blue')
ax[0].plot(data['epoch'], data['train/obj_loss'], label='Object Loss', color='red')
ax[0].plot(data['epoch'], data['train/cls_loss'], label='Class Loss', color='green')
ax[0].set_xlabel('Epoch')
ax[0].set_ylabel('Training Loss')
ax[0].set_title('Training Losses per Epoch')
ax[0].legend()

# Plotting validation losses
ax[1].plot(data['epoch'], data['val/box_loss'], label='Box Loss', color='blue')
ax[1].plot(data['epoch'], data['val/obj_loss'], label='Object Loss', color='red')
ax[1].plot(data['epoch'], data['val/cls_loss'], label='Class Loss', color='green')
ax[1].set_xlabel('Epoch')
ax[1].set_ylabel('Validation Loss')
ax[1].set_title('Validation Losses per Epoch')
ax[1].legend()

# Plotting precision, recall, and mAP
ax[2].plot(data['epoch'], data['metrics/precision'], label='Precision', color='purple')
ax[2].plot(data['epoch'], data['metrics/recall'], label='Recall', color='orange')
ax[2].plot(data['epoch'], data['metrics/mAP_0.5'], label='mAP at 0.5 IoU', color='cyan')
ax[2].plot(data['epoch'], data['metrics/mAP_0.5:0.95'], label='mAP at 0.5:0.95 IoU', color='magenta')
ax[2].set_xlabel('Epoch')
ax[2].set_ylabel('Metrics')
ax[2].set_title('Precision, Recall, and mAP per Epoch')
ax[2].legend()

plt.tight_layout()
plt.show()

在这里插入图片描述

每个时期的训练损失:

该图显示了训练过程中框、对象和类损失的趋势。理想情况下,这些应该随着时间的推移而减少,表明学习和收敛。
每个时期的验证损失:

与训练损失类似,这些反映了模型在未见过的数据上的性能。重要的是要看看这些损失是否随着训练损失而减少,这表明具有良好的泛化性。

每个 Epoch 的精度、召回率和 mAP:

精度和召回率是对象检测任务的关键指标,分别表示检测到的对象的准确性和完整性。
不同 IoU 阈值下的平均精度 (mAP) 提供了模型性能的全面视图,结合了精度和召回率方面。
分析和观察:
损失:如果训练和验证损失正在减少,则表明模型正在有效地学习。然而,如果验证损失与训练损失不同,这可能表明过度拟合。
精确率和召回率:这些指标的增长趋势是可取的。精度侧重于模型预测的准确性,而召回率则衡量模型识别所有相关案例的能力。
mAP(平均精度):这是对象检测任务中的一个关键指标。mAP 跨时代的改进表明,该模型在准确检测具有正确边界框的对象方面变得越来越好。

10.系统整合

下图完整源码&数据集&环境部署视频教程&自定义UI界面

在这里插入图片描述

参考博客《【改进YOLOv8】融合可扩张残差(DWR)注意力模块的小麦病害检测系统》

11.参考文献


[1]王书献,张胜茂,朱文斌,等.基于深度学习YOLOV5网络模型的金枪鱼延绳钓电子监控系统目标检测应用[J].大连海洋大学学报.2021,(5).DOI:10.16535/j.cnki.dlhyxb.2020-333 .

[2]佚名.Deep neural networks for analysis of fisheries surveillance video and automated monitoring of fish discards[J].ICES Journal of Marine Science.2020,77(4).1340-1353.DOI:10.1093/icesjms/fsz149 .

[3]Aloysius T.M. van Helmond,Lars O. Mortensen,Kristian S. Plet&#x2010,等.Electronic monitoring in fisheries: Lessons from global experiences and future opportunities[J].Fish & Fisheries.2020,21(1).162-189.DOI:10.1111/faf.12425 .

[4]Needle, Coby L.,Dinsdale, Rosanne,Buch, Tanja B.,等.Scottish science applications of Remote Electronic Monitoring[J].ICES journal of marine science.2015,72(4).1214-1229.DOI:10.1093/icesjms/fsu225 .

[5]François Chollet.Xception: Deep Learning with Depthwise Separable Convolutions[C].

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《opencv实用探索·八》图像模糊之均值滤波、高斯滤波的简单理解

1、前言 什么是噪声&#xff1f; 该像素与周围像素的差别非常大&#xff0c;导致从视觉上就能看出该像素无法与周围像素组成可识别的图像信息&#xff0c;降低了整个图像的质量。这种“格格不入”的像素就被称为图像的噪声。如果图像中的噪声都是随机的纯黑像素或者纯白像素&am…

短剧分销平台搭建:短剧变现新模式

短剧作为今年大热的行业&#xff0c;深受大众追捧&#xff01;短剧剧情紧凑&#xff0c;几乎每一集都有高潮剧情&#xff0c;精准击中了当下网友的碎片化时间。 短剧的形式较为灵活&#xff0c;可以轻松融入各种的元素&#xff0c;比如喜剧、悬疑、爱情等&#xff0c;可以满足…

工业 4.0 | 数字孪生入门指南

工业 4.0 在多年热议后悄然落地&#xff0c;如今&#xff0c;制造、能源和运输企业正在越来越多地从中受益。 仿真未来场景 公司可以使用数字孪生仿真未来场景&#xff0c;以了解天气、车队规模或工况差异等因素对性能的影响。该方法可为维护计划提供决策支撑&#xff0c;并可…

[陇剑杯 2021]简单日志分析

[陇剑杯 2021]简单日志分析 题目做法及思路解析&#xff08;个人分享&#xff09; 问一&#xff1a;某应用程序被攻击&#xff0c;请分析日志后作答&#xff1a; 黑客攻击的参数是______。&#xff08;如有字母请全部使用小写&#xff09;。 题目思路&#xff1a; 分析…

探索Python中封装的概念与实践

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 封装是面向对象编程中的核心概念&#xff0c;它能够帮助程序员隐藏类的内部细节&#xff0c;并限制对类成员的直接访问。本文将深入探讨Python中封装的机制&#xff0c;介绍封装的类型和优势&#xff0c;并提供详…

重写 AppiumService 类,添加默认启动参数,并实时显示启动日志

一、前置说明 在Appium的1.6.0版本中引入了AppiumService类&#xff0c;可以很方便的通过该类来管理Appium服务器的启动和停止。经过测试&#xff0c;使用该类的实例执行关闭server时&#xff0c;并没有释放端口号&#xff0c;会导致第二次启动时失败。另外&#xff0c;使用该…

什么是MyBatis、什么是MyBatis-Plus、简单详细上手案例

什么是MyBatis MyBatis是一个开源的Java持久层框架&#xff0c;用于简化与关系型数据库的交互。它通过将SQL语句与Java代码进行分离&#xff0c;提供了一种优雅的方式来处理数据库操作。 MyBatis的核心思想是将SQL语句与Java方法进行映射&#xff0c;使得开发人员可以通过配置…

Java LeetCode篇-深入了解二叉树的经典解法(多种方式实现:构造二叉树)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 从前序与中序遍历序列来构造二叉树 1.1 实现从前序与中序遍历序列来构造二叉树思路 1.2 代码实现从前序与中序遍历序列来构造二叉树 2.0 从中序与后序遍历序…

实用篇 | 一文学会人工智能中API的Flask编写(内含模板)

----------------------- &#x1f388;API 相关直达 &#x1f388;-------------------------- &#x1f680;Gradio: 实用篇 | 关于Gradio快速构建人工智能模型实现界面&#xff0c;你想知道的都在这里-CSDN博客 &#x1f680;Streamlit :实用篇 | 一文快速构建人工智能前端展…

【优选算法系列】【专题二滑动窗口】第三节.904. 水果成篮和438. 找到字符串中所有字母异位词

文章目录 前言一、水果成篮 1.1 题目描述 1.2 题目解析 1.2.1 算法原理 1.2.2 代码编写 1.2.3 题目总结二、找到字符串中所有字母异位词 2.1 题目描述 2.2 题目解析 2.2.1 算法原理 2.2.2 代码编写 …

OpenAI 首席运营官(COO)Brad Lightcap认为商业人工智能被夸大了

美国消费者新闻与商业频道&#xff08;CNBC&#xff09;是美国NBC环球集团持有的全球性财经有线电视卫星新闻台&#xff0c;是全球财经媒体中的佼佼者&#xff0c;其深入的分析和实时报导赢得了全球企业界的信任。在1991年前&#xff0c;使用消费者新闻与商业频道&#xff08;C…

node.js和npm的安装与环境配置(2023最新版)

目录 安装node.js测试是否安装成功测试npm环境配置更改环境变量新建系统变量 安装node.js 1、进入官网下载&#xff1a;node.js官网 我选择的是windows64位的&#xff0c;你可以根据自己的实际情况选择对应的版本。 2、下载完成&#xff0c;安装。 打开安装程序 接受协议 选…

链表OJ—环形链表的约瑟夫问题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 世上有两种耀眼的光芒&#xff0c;一种是正在升起的太阳&#xff0c;一种是正在努力学习编程的你!一个爱学编程的人。各位看官&#xff0c;我衷心的希望这篇博客能对你…

操作系统———磁盘调度算法模拟

实验目的 磁盘是可供多个进程共享的设备&#xff0c;当有多个进程都要求访问磁盘是&#xff0c;应采用一种最佳调度算法&#xff0c;以使各进程对磁盘的平均访问时间最小。目前最成用的磁盘调度算法有先来先服务&#xff08;FCFS&#xff09;&#xff0c;最短寻道时间优先&…

增加网站流量的方法

如果您的网站没有获得足够的流量&#xff0c;您可能会错过在线发展业务的重要机会。搜索引擎优化&#xff08;SEO&#xff09;可以帮助提高您网站的知名度&#xff0c;从而吸引更多客户。 SEO的重点是识别高价值的关键词&#xff0c;并将它们整合到网站的内容中&#xff0c;使…

【设计模式-3.2】结构型——适配器模式

说明&#xff1a;本文介绍设计模式中结构型设计模式中的&#xff0c;适配器模式&#xff1b; 插头转换器 适配器模式属于结构型设计模式&#xff0c;设计思想体现在结构上的。以插头转换器为例&#xff0c;当你需要给手机充电&#xff0c;但是眼前只有一个三孔插座&#xff0…

MES管理系统在非标制造企业中的应用

在当今制造业中&#xff0c;非标制造企业逐渐成为一种重要的存在。与传统的批量生产制造企业不同&#xff0c;非标制造企业主要特点是能够根据客户需求进行定制化生产。这种定制化的生产模式对企业的管理提出了更高的要求&#xff0c;同时也带来了更多的挑战。在非标制造企业中…

Emacs之Plantuml用于复杂UML类图(Markdown用于简单类图)(一百三十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

MQTT主题、通配符和最佳实践

MQTT主题在MQTT生态系统非常重要&#xff0c;因为代理&#xff08;broker&#xff09;依赖主题确定哪个客户端接收指定的主题。本文我们将聚集MQTT主题、MQTT通配符&#xff0c;详细讨论使用它们的最佳实践&#xff0c;也会探究SYS主题&#xff0c;提供给代理&#xff08;broke…

超越极限!如何进行高效分布式性能测试,让Jmeter揭示并发下系统的真正实力

一、为什么要进行分布式性能测试 当进行高并发性能测试的时候&#xff0c;受限于Jmeter工具本身和电脑硬件的原因&#xff0c;无法满足我们对大并发性能测试的要求。 基于这种场景下&#xff0c;我们就需要采用分布式的方式来实现我们高并发的性能测试要求。 二、分布式性能测…