基于改进YOLOv5的小目标检测 | 添加CBAM注意机制 + 更换Neck网络之BiFPN + 增加高分辨率检测头

news2024/11/15 13:33:37

前言:Hello大家好,我是小哥谈。本文针对图像中小目标难以检测的问题,提出了一种基于YOLOv5的改进模型。在主干网络中,加入CBAM注意力模块增强网络特征提取能力;在颈部网络部分,使用BiFPN结构替换PANet结构,强化底层特征利用;在检测头部分,增加高分辨率检测头,改善对于微小目标的检测能力。本文算法在无人机数据集VisDrone2019数据集上进行了多次对比实验,结果表明本文算法可以有效地检测小目标。🌈

     目录

🚀1.基础概念

🚀2.网络结构

🚀3.添加步骤

🚀4.改进方法

🍀🍀步骤1:common.py文件修改

🍀🍀步骤2:yolo.py文件修改

🍀🍀步骤3:创建自定义yaml文件

🍀🍀步骤4:修改自定义yaml文件

🍀🍀步骤5:验证是否加入成功

🍀🍀步骤6:修改默认参数 

🍀🍀步骤7:实际训练测试 

🚀5.试验分析

🍀🍀5.1 数据集

🍀🍀5.2 评价指标

🍀🍀5.3 检测效果

🚀1.基础概念

目标检测是计算机视觉的重要研究方向,也是众多复杂视觉任务的基础,被广泛应用于工业、农业等领域。尽管深度学习技术的出现使得目标检测取得了较大的突破,但是现有的方法依然很难较好的检测小目标。小目标尺寸小特征不明显,在检测中误检率漏检率一般均较高,因此提升小目标检测性能仍然是 一个具有挑战性的研究方向。

本节贡献:

  1. 针对小目标对象提出了一种新的检测模型。
  2. 基于注意力机制,通过改进主干网络增强模型对于目标特征的提取。
  3. 基于双向交叉连接和加权融合的思想,引入额外特征分支,强化底层特征利用。
  4. 针对目标尺寸较小的特点,在检测头部分增加高分辨率检测分支,增强模型对于微小目标的检测能力。

小目标检测头:

原始YOLOv5模型主干网络一共进行5次下采样,得到5层特征表达(P1P2P3P4P5)。尽管在颈部网络中,通过自上而下自下而上的聚合路径实现了多尺度特征融合,但是并不影响特征图的尺度,最后检测头部分在通过P3P4P5这3级特征图引出的检测头上进行目标的检测,其特征图尺度分别为80×8040×40 20×20。为方便表达,通过Pi层特征图引出的检测头,以下简称为Pi层检测头。在小目标检测任务中,往往存在非常小的待检目标。在VisDrone2019公开无人机数据集中,甚至含有较多小于3×3像素的目标。这样的目标在经过多次下采样之后,其大部分特征信息已经丢失,尽管通过具有较高分辨率的P3层检测头依然难以检测到。

为了实现上述微小目标同样可以达到较好的检测效果,我们在YOLOv5模型上通过P2层特征引出了新的检测头。P2层检测头分辨率为160×160像素,相当于在主干网络中只进行了2次下采样操作,含有目标更为丰富的底层特征信息。颈部网络中自上而下自下而上得到的两个P2层特征与主干网络中的同尺度特征通过concat形式进行特征融合,输出的特征为3个输入特征的融合结果,这样使得P2层检测头应对微小目标时,能够快速有效的检测。P2层检测头加上原始的3个检测头,可以有效缓解尺度方差所带来的负面影响,增加的检测头是针对底层特征的,是通过低水平、高分辨率的特征图生成的,该检测头对微小目标更加敏感。尽管添加这个检测头增加了模型的计算量和内存开销,但是对于微小目标的检测能力有着不小的提升。

CBAM注意力模块:

CBAM是一种轻量的注意力模块,其简单有效,可以直接集成到CNN架构中,并且可以端到端的对其进行训练。在给定特征映射的情况下,CBAM会依次沿着通道空间两个独立维度推导注意映射,然后将注意映射与输入特征映射相乘,进行自适应特征细化。CBAM 模块的结构如下图所示,CBAM模块被集成到不同数据集和不同分类任务的不同模型中,模型性能均得到了较大提升,证明了CBAM模块的有效性。

小目标尺寸较小、特征少且不明显,在主干网络 中加入CBAM注意力模块,可以增强网络对于目标特征的提取能力,同时直接改善颈部网络部分的特征融合。在检测任务中,CBAM注意力模块可以帮助模型有效的提取注意区域,提高检测性能。

BiFPN网络:

BiFPN网络是集成双向交叉连接加权融合的一种高效的多尺度特征融合方法。自FPN被提出以来,FPN被广泛应用于多尺度特征融合。近些年来,PANet、M2det和NAS-FPN等更多的多尺度特征融合网络结构被研究学者们提出来,但是在融合不同层次的输入特征时,大部分工作都是不加区分的总结它们。然而,这些不同的输入特征有着不同分辨率,对融合的输出特征具有在不同的贡献。为此,提出了一种简单但高效的加权双向特征金字塔网络(BiFPN),它引入了可学习的权重因子来表征不同输入特征的重要程度,同时反复应用自顶向下和自底向上的多尺度特征融合。

为充分利用目标的底层特征,本节课对颈部网络进行了改进,将原始PANet网络换成BiFPN网络,以提高检测精度,其结构如下图所示。尽管YOLOv5中的PANet通过自顶向下自底向上的路径聚合实现了较好的多尺度特征融合结果,但计算量较大,且自底向上特征融合阶段的输入特征中并没有主干网络生成的原始输出特征。BiFPN采用跨连接去除PANet中对特征融合贡献度较小的节点,在同一尺度的输入节点和输出节点间增加一个跳跃连接,在不增加较多成本的同时,融合了更多的特征。在同一特征尺度上,把每一个双向路径看作一个特征网络层,并多次反复利用同一 层,以实现更高层次的特征融合。

通过上述三种改进方式后,本节课针对YOLOv5改进后的网络结构图如下所示:


🚀2.网络结构

本文的改进是基于YOLOv5-6.0版本,关于其网络结构具体如下图所示:

本文对YOLOv5的改进是添加CBAM注意机制 + 更换Neck网络之BiFPN + 增加高分辨率检测头,改进后的网络结构图具体如下图所示: 


🚀3.添加步骤

针对本文的改进,具体步骤如下所示:👇

步骤1:common.py文件修改

步骤2:yolo.py文件修改

步骤3:创建自定义yaml文件

步骤4:修改自定义yaml文件

步骤5:验证是否加入成功

步骤6:修改默认参数

步骤7:实际训练测试


🚀4.改进方法

🍀🍀步骤1:common.py文件修改

common.py添加CBAM注意力机制BiFPN模块代码,所要添加模块的代码如下所示,将其复制粘贴到common.py文件末尾的位置。

# 基于改进YOLOv5的小目标检测
# By CSDN 小哥谈
# CBAM注意力机制代码
class ChannelAttentionModule(nn.Module):
    def __init__(self, c1, reduction=16):
        super(ChannelAttentionModule, self).__init__()
        mid_channel = c1 // reduction
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)
        self.shared_MLP = nn.Sequential(
            nn.Linear(in_features=c1, out_features=mid_channel),
            nn.LeakyReLU(0.1, inplace=True),
            nn.Linear(in_features=mid_channel, out_features=c1)
        )
        self.act = nn.Sigmoid()
        # self.act=nn.SiLU()

    def forward(self, x):
        avgout = self.shared_MLP(self.avg_pool(x).view(x.size(0), -1)).unsqueeze(2).unsqueeze(3)
        maxout = self.shared_MLP(self.max_pool(x).view(x.size(0), -1)).unsqueeze(2).unsqueeze(3)
        return self.act(avgout + maxout)

class SpatialAttentionModule(nn.Module):
    def __init__(self):
        super(SpatialAttentionModule, self).__init__()
        self.conv2d = nn.Conv2d(in_channels=2, out_channels=1, kernel_size=7, stride=1, padding=3)
        self.act = nn.Sigmoid()

    def forward(self, x):
        avgout = torch.mean(x, dim=1, keepdim=True)
        maxout, _ = torch.max(x, dim=1, keepdim=True)
        out = torch.cat([avgout, maxout], dim=1)
        out = self.act(self.conv2d(out))
        return out

class CBAM(nn.Module):
    def __init__(self, c1, c2):
        super(CBAM, self).__init__()
        self.channel_attention = ChannelAttentionModule(c1)
        self.spatial_attention = SpatialAttentionModule()

    def forward(self, x):
        out = self.channel_attention(x) * x
        out = self.spatial_attention(out) * out
        return out

# BiFPN模块代码
class BiFPN_Add2(nn.Module):
    def __init__(self, c1, c2):
        super(BiFPN_Add2, self).__init__()
        # 设置可学习参数 nn.Parameter的作用是:将一个不可训练的类型Tensor转换成可以训练的类型parameter
        # 并且会向宿主模型注册该参数 成为其一部分 即model.parameters()会包含这个parameter
        # 从而在参数优化的时候可以自动一起优化
        self.w = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)
        self.epsilon = 0.0001
        self.conv = nn.Conv2d(c1, c2, kernel_size=1, stride=1, padding=0)
        self.silu = nn.SiLU()

    def forward(self, x):
        w = self.w
        weight = w / (torch.sum(w, dim=0) + self.epsilon)
        return self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1]))

# 三个特征图add操作
class BiFPN_Add3(nn.Module):
    def __init__(self, c1, c2):
        super(BiFPN_Add3, self).__init__()
        self.w = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)
        self.epsilon = 0.0001
        self.conv = nn.Conv2d(c1, c2, kernel_size=1, stride=1, padding=0)
        self.silu = nn.SiLU()

    def forward(self, x):
        w = self.w
        weight = w / (torch.sum(w, dim=0) + self.epsilon)
        # Fast normalized fusion
        return self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1] + weight[2] * x[2]))
🍀🍀步骤2:yolo.py文件修改

yolo.py文件中找到parse_model函数,在下图中所示位置添加CBAM,并且添加下列代码:

# -----------BiFPN-------------------
        elif m in [BiFPN_Add2, BiFPN_Add3]:
            c2 = max([ch[x] for x in f])
        # ------------end-----------------------

具体添加位置如下图所示:

🍀🍀步骤3:创建自定义yaml文件

models文件夹中复制yolov5s.yaml,粘贴并重命名为:yolov5s_CBAM_BiFPN.yaml具体如下图所示:

🍀🍀步骤4:修改自定义yaml文件

本步骤是修改yolov5s_CBAM_BiFPN.yaml,根据改进后的网络结构图进行修改。

修改后的完整yaml文件如下所示:

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# By CSDN 小哥谈

# Parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
anchors:
  - [5, 6, 8, 14, 15, 11]  # P2/4
  - [10, 13, 16, 30, 33, 23] # P3/8
  - [30, 61, 62, 45, 59, 119] # P4/16
  - [116, 90, 156, 198, 373, 326] # P5/32

backbone:
  # [from, number, module, args]
  [
    [-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
    [-1, 1, Conv, [128, 3, 2]], # 1-P2/4
    [-1, 3, C3, [128]],  # 2 160 * 160
    [-1, 1, CBAM, [128]],  # 3
    [-1, 1, Conv, [256, 3, 2]], # 4-P3/8
    [-1, 6, C3, [256]],  # 80 * 80
    [-1, 1, Conv, [512, 3, 2]], # 6-P4/16
    [-1, 9, C3, [512]],  # 7 40 * 40
    [-1, 1, Conv, [1024, 3, 2]], # 8-P5/32
    [-1, 3, C3, [1024]],  # 9 20 * 20
    [-1, 1, SPPF, [1024, 5]], # 10
  ]
head: [
    [-1, 1, Conv, [512, 1, 1]], # 11
    [-1, 1, nn.Upsample, [None, 2, "nearest"]], # 12
    [[-1, 7], 1, BiFPN_Add2, [256, 256]], # cat backbone P4  # 13
    [-1, 3, C3, [512, False]], # 14

    [-1, 1, Conv, [256, 1, 1]], # 15
    [-1, 1, nn.Upsample, [None, 2, "nearest"]], # 16
    [[-1, 5], 1, BiFPN_Add2, [128, 128]], # cat backbone P3 # 17
    [-1, 3, C3, [256, False]], # (P3/8-small) # 18

    [-1, 1, Conv, [128, 1, 1]], # 19
    [-1, 1, nn.Upsample, [None, 2, "nearest"]], #20
    [[-1, 2], 1, BiFPN_Add2, [64, 64]],  # 21  p2
    [-1, 3, C3, [128, False]],  # 22

    [-1, 1, Conv, [256, 3, 2]],  # 23
    [[-1, 18, 5], 1, BiFPN_Add3, [128, 128]], # 24 p3
    [-1, 3, C3, [256, False]], # 25 p3

    [-1, 1, Conv, [512, 3, 2]], # 26
    [[-1, 14, 7], 1, BiFPN_Add3, [256, 256]], # 27 cat head P4
    [-1, 3, C3, [512, False]], # 28 (P4/16-medium)

    [-1, 1, Conv, [512, 3, 2]],  # 29
    [[-1, 11], 1, BiFPN_Add2, [256, 256]], # 30 cat head P5
    [-1, 3, C3, [1024, False]], # 31 (P5/32-large)

    [[22, 25, 28, 31], 1, Detect, [nc, anchors]], # Detect(P2, P3, P4, P5)
  ]
🍀🍀步骤5:验证是否加入成功

yolo.py文件里,将配置改为我们刚才自定义的yolov5s_CBAM_BiFPN.yaml

修改1,位置位于yolo.py文件165行左右,具体如图所示:

修改2,位置位于yolo.py文件363行左右,具体如下图所示:

配置完毕之后,点击“运行”,结果如下图所示:

由运行结果可知,与我们前面更改后的网络结构图相一致,证明添加成功了!✅

参数量对比:

yolov5s.yaml:214 layers, 7235389 parameters, 7235389 gradients, 16.6 GFLOPs

yolov5s_CBAM_BiFPN.yaml:284 layers, 7597553 parameters, 7597553 gradients, 21.5 GFLOPs

🍀🍀步骤6:修改默认参数 

修改1,设置可学习权重,将下列代码放置在train.py文件(160行左右)

# 设置可学习权重
    g0, g1, g2 = [], [], []  # optimizer parameter groups
    for v in model.modules():
        # hasattr: 测试指定的对象是否具有给定的属性,返回一个布尔值
        if hasattr(v, 'bias') and isinstance(v.bias, nn.Parameter):  # bias
            g2.append(v.bias)  # biases
        if isinstance(v, nn.BatchNorm2d):  # weight (no decay)
            g0.append(v.weight)
        elif hasattr(v, 'weight') and isinstance(v.weight, nn.Parameter):
            g1.append(v.weight)
        # BiFPN_Concat
        elif isinstance(v, BiFPN_Add2) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):
            g1.append(v.w)
        elif isinstance(v, BiFPN_Add3) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):
            g1.append(v.w)

具体放置位置如下图所示:

修改2,在train.py文件中找到parse_opt函数,然后将第二行 '--cfg' 的default改为 ' models/yolov5s_CBAM_BiFPN.yaml ',然后就可以开始进行训练了。🎈🎈🎈

🍀🍀步骤7:实际训练测试 

在本步骤中,parse_opt函数中的参数'--weights'采用的是yolov5s.pt'--data'所采用的是helmet.yaml(作者提前创建的安全帽佩戴检测地址及分类信息,同学可自定义),然后设置'--epochs'100轮。相关参数设置完毕后,点击运行train.py文件,没有发生报错,模型正常训练,具体如下图所示:👇

说明:后期实际训练时,根据论文所设置的指标进行训练,上述只是进行测试。 


🚀5.试验分析

🍀🍀5.1 数据集

VisDrone2019数据集由天津大学机器学习和数据挖掘实验室AISKYEYE团队收集,基准数据集包含288个视频片段261908帧10209幅静态图像。数据集是在不同的场景、不同的天气和光照条件下使用各种无人机平台(即不同型号的无人机)收集的,手工标注了超过260万个边界框或经常感兴趣的目标点,包括行人、人、轿车、货车、公共汽车、卡车、摩托 车、自行车、遮阳篷三轮车和三轮车等10个感兴趣的对象类别。其各类标签数量如表1所示。

🍀🍀5.2 评价指标

为验证模型性能,本文选用精确率(Precision,P)召回率(Recall,R)平均精度(average precision,AP) 平均精度均值(mean average precision,mAP)来评估模型的检测性能。

关于目标检测评价指标,请参考文章:

第1篇 目标检测概述 —(3)目标检测评价指标

🍀🍀5.3 检测效果

VisDrone2019数据测试集上的一些检测结果如下所示:

说明:

本节课根据文章《基于改进YOLOv5的小目标检测》进行代码实现。

作者:黎学飞、童晶、陈正鸣、包勇、倪佳佳。

期刊:计算机系统应用 ISSN 1003-3254, CODEN CSAOBN

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

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

相关文章

【YOLOv5进阶】——修改网络结构(以C2f模块为例)

一、站在巨人的肩膀上 这里我们借鉴YOLOv8源码: 上期说到,对于网络模块定义详情在common.py这个文件,如Conv、CrossConv、C3f等。本期要修改的需要参考YOLOv8里的C2f模块,它定义在YOLOv8的module文件夹的block.py文件里&#xf…

1900springboot VUE 生态菜园管理系统开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot VUE生态菜园管理系统是一套完善的完整信息管理类型系统,结合springboot框架和VUE完成本系统,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统具有完整的源代码和…

c#未能加载基类System错误 这台计算机上缺少此项目引用的 NuGet 程序包

拷贝代码到另一台计算机运行,打开Form1.cs报错 首先确认package的框架 如果是472,则更换472的框架 打开项目->xx属性,进行修改 如果框架正确,就是未识别到程序包 可以参考: https://www.cnblogs.com/txwtech/p/1…

⌈ 传知代码 ⌋ 【CLIP】文本也能和图像配对

💛前情提要💛 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间,对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

Django学习(1)Model

模型 1、Django操作指令 2、Django模型字段类型 3、Django模型字段类型属性 4、Django模型Meta属性

WINUI——Behavior(行为)小结

前言 在使用MVVM进行WINUI或WPF开发时,Command在某些时候并不能满足逻辑与UI分离的要求。这时肯定就需要其它技术的支持,Behavior就是一种。在WPF中是有Behavior直接支持的,转到WINUI后,相对有一些麻烦,于是在此记录之…

Linux网络命令——tcpdump

tcpdump是Linux下的一个网络数据采集分析工具,也就是常说的抓包工具 tcpdump 核心参数 tcpdump [option] [proto] [dir] [type] 例如:$ tcpdump -i eth0 -nn -s0 -v port 80 option 可选参数: -i : 选择要捕获的接口,通常是以太…

NFT 智能合约实战-快速开始(1)NFT发展历史 | NFT合约标准(ERC-721、ERC-1155和ERC-998)介绍

文章目录 NFT 智能合约实战-快速开始(1)NFT发展历史国内NFT市场国内NFT合规性如何获得NFT?如何查询NFT信息?在 OpenSea 上查看我们的 NFT什么是ERC721NFT合约标准ERC-721、ERC-1155和ERC-998 对比ERC721IERC721.sol 接口内容关于合约需要接收 ERC721 资产 onERC721Received…

机器学习笔记 - LoRA:大型语言模型的低秩适应

一、简述 1、模型微调 随着大型语言模型 (LLM) 的规模增加到数千亿,对这些模型进行微调成为一项挑战。传统上,要微调模型,我们需要更新所有模型参数。这也称为完全微调 (FFT) 。下图详细概述了此方法的工作原理。 完全微调FFT 的计算成本和资源需求很大,因为更新每…

超详解——python条件和循环——小白篇

目录 1. 缩进和悬挂else 2. 条件表达式 3. 和循环搭配的else 4. 可调用对象 总结: 1. 缩进和悬挂else 在Python中,代码块是通过缩进来表示的。条件判断和循环结构的代码块需要正确缩进。悬挂else指的是else子句和相应的if或循环在同一级别的缩进。 …

【Python深度学习】——信息量|熵

【Python深度学习】——信息量|熵 假设1. 信息量1.1 含义1.2 信息量的公式: 2. 熵Entropy2. 含义2.2 熵的计算公式:2.3 熵的作用 假设 例子:掷硬币 假设我们有一个公平的硬币。这个硬币有两个面:正面(H)和反面(T&…

C#项目实战

事件 public delegate void NumManipulationHandler(NumEventArgs e); // 基于上面的委托定义事件 public event NumManipulationHandler ChangeNum;public class Program{public static void Main(){NumEvent even new NumEvent(0);even.ChangeNum EventAction.Action;even…

如何在 Windows 11/10/8/7 中恢复已删除的文件

经历文件一键消失(无论出于何种原因)可能是最大的噩梦之一。即使您自己删除了文件以释放一些空间,有时您最终还是需要一劳永逸地删除的文件。无论您只是想减轻系统存储的负担并让其容纳最新的数据,还是发现它无关紧要(…

开源VisualFreebasic中文版,vb7 IDE,VB6升级64位跨平台开发安卓APP,Linux程序

吴涛老矣,社区苦无64位易语言,用注入DLL增强菜单,做成VS一样的界面 终归是治标不治本,一来会报毒,二来闭源20年没更新了 开源的VB7,欢迎易语言的铁粉进群:1032313876 【Freebasic编程语言】编绎…

算法金 | AI 基石,无处不在的朴素贝叶斯算法

大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 历史上,许多杰出人才在他们有生之年默默无闻, 却在逝世后被人们广泛追忆和崇拜。 18世纪的数学家托马斯贝叶斯…

【python】python GUI编程--tkinter模块初探

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

【RabbitMQ】RabbitMQ配置与交换机学习

【RabbitMQ】RabbitMQ配置与交换机学习 文章目录 【RabbitMQ】RabbitMQ配置与交换机学习简介安装和部署1. 安装RabbitMQ2.创建virtual-host3. 添加依赖4.修改配置文件 WorkQueues模型1.编写消息发送测试类2.编写消息接收(监听)类3. 实现能者多劳 交换机F…

特种设备起重机指挥题库附答案

1、【多选题】力的三要素是指:( )。(ACD) A、力的大小 B、力的单位 C、力的方向 D、力的作用点 2、【多选题】司索作业规范正确的要求是( )(ABC) A、吊点正确 B、吊索挂设合理 C、绑扎牢靠 D、吊索长短一致 3、【多选题】圆柱形物体兜吊时,一定要放空圈&#…

LearnDash+BuddyBoss:终极在线课程社区组合

您是否希望使用 WordPress 建立在线课程社区? 如果是这样,没有比LearnDash和BuddyBoss在线课程社区更好的组合了。使用这两款产品,您可以创建和销售在线课程、创建群组和讨论,并为您的学生提供整个社交网络,所有这些都…

用咖啡来理解springboot3的自动配置机制

大家好,这里是教授.F 目录 前提知识: 场景引入: 1.Starter依赖: 2.默认配置: 3.自定义配置: 4.条件化配置: 5.自动装配: 具体过程: 扫包路径的配置: 配置…