YOLOv8改进 | 模块缝合 | C2f融合多尺度表征学习模块 【含OD、RTDETR、OBB等yaml文件】

news2024/11/16 9:20:45

秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转


💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡


专栏目录 :《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有100+篇内容,内含各种Head检测头、损失函数Loss、Backbone、Neck、NMS等创新点改进——点击即可跳转


本文介绍的Multi-Scale是基于不同核大小的卷积如何影响不同尺度对象的检测性能研究。其成果是一种新策略,可以显著增强实时目标检测器在多尺度特征表示上的能力。文章在介绍主要的原理后,将手把手教学如何进行模块的代码添加和修改,并将修改后的完整代码放在文章的最后,方便大家一键运行,小白也可轻松上手实践。以帮助您更好地学习深度学习目标检测YOLO系列的挑战。 

专栏地址YOLOv8改进——更新各种有效涨点方法——点击即可跳转  

目录

1. 原理 

2. 将C2f_MSBlock添加到yolov8网络中

2.1 C2f_MSBlock代码实现

2.2 C2f_MSBlock的神经网络模块代码解析

2.3 更改init.py文件

2.4 添加yaml文件

2.5 注册模块

2.6 执行程序

3. 完整代码分享

4. GFLOPs

5. 进阶

6. 总结


1. 原理 

论文地址:YOLO-MS: Rethinking Multi-Scale Representation Learning for Real-time Object Detection——点击即可跳转

官方代码:官方代码仓库——点击即可跳转

多尺度块(MS-Block)是增强实时物体检测中多尺度特征表示能力的关键组件。以下是其主要原理的分解:

  1. 分层特征融合:MS-Block 采用受 Res2Net 模型启发的分层特征融合策略。它将输入特征图分成多个组,每个组单独处理。第一组不做任何修改就通过,而后续组则通过倒置瓶颈层处理,这些层涉及具有不同内核大小的深度卷积。这使网络能够有效地捕获多尺度特征。

  2. 带深度卷积的倒置瓶颈:MS-Block 使用带深度卷积的倒置瓶颈结构,而不是标准卷积。这种方法可以有效地使用大内核,从而增强了块捕获不同尺度特征的能力,而不会产生过多的计算成本。

  3. 通道交互:经过反向瓶颈层处理后,特征图被连接起来并通过 1x1 卷积。这最后一步促进了前面步骤中提取的不同尺度特征之间的交互,确保输出特征图包含丰富的多尺度表示。

  4. 多尺度表示效率:MS-Block 旨在平衡计算效率和捕获多尺度特征的能力。通过调整深度卷积中使用的分支数量和内核大小,可以优化该块以在对象检测任务中实现速度和准确性之间的更好权衡。

MS在实时对象检测中特别有用,因为速度和准确性都至关重要,因为它允许模型有效地学习和表示多个尺度的特征,同时保持较高的推理速度。

2. 将C2f_MSBlock添加到yolov8网络中

2.1 C2f_MSBlock代码实现

关键步骤一将下面代码粘贴到在/ultralytics/ultralytics/nn/modules/block.py中,并在该文件的__all__中添加“C2f_MSBlock”


class MSBlockLayer(nn.Module):
    def __init__(self, inc, ouc, k) -> None:
        super().__init__()
        
        self.in_conv = Conv(inc, ouc, 1)
        self.mid_conv = Conv(ouc, ouc, k, g=ouc)
        self.out_conv = Conv(ouc, inc, 1)
    
    def forward(self, x):
        return self.out_conv(self.mid_conv(self.in_conv(x)))

class MSBlock(nn.Module):
    def __init__(self, inc, ouc, kernel_sizes, in_expand_ratio=3., mid_expand_ratio=2., layers_num=3, in_down_ratio=2.) -> None:
        super().__init__()
        
        in_channel = int(inc * in_expand_ratio // in_down_ratio)
        self.mid_channel = in_channel // len(kernel_sizes)
        groups = int(self.mid_channel * mid_expand_ratio)
        self.in_conv = Conv(inc, in_channel)
        
        self.mid_convs = []
        for kernel_size in kernel_sizes:
            if kernel_size == 1:
                self.mid_convs.append(nn.Identity())
                continue
            mid_convs = [MSBlockLayer(self.mid_channel, groups, k=kernel_size) for _ in range(int(layers_num))]
            self.mid_convs.append(nn.Sequential(*mid_convs))
        self.mid_convs = nn.ModuleList(self.mid_convs)
        self.out_conv = Conv(in_channel, ouc, 1)
        
        self.attention = None
    
    def forward(self, x):
        out = self.in_conv(x)
        channels = []
        for i,mid_conv in enumerate(self.mid_convs):
            channel = out[:,i * self.mid_channel:(i+1) * self.mid_channel,...]
            if i >= 1:
                channel = channel + channels[i-1]
            channel = mid_conv(channel)
            channels.append(channel)
        out = torch.cat(channels, dim=1)
        out = self.out_conv(out)
        if self.attention is not None:
            out = self.attention(out)  
        return out

class C3_MSBlock(C3):
    def __init__(self, c1, c2, n=1, kernel_sizes=[1, 3, 3], in_expand_ratio=3., mid_expand_ratio=2., layers_num=3, in_down_ratio=2., shortcut=False, g=1, e=0.5):
        super().__init__(c1, c2, n, shortcut, g, e)
        c_ = int(c2 * e)  # hidden channels
        self.m = nn.Sequential(*(MSBlock(c_, c_, kernel_sizes, in_expand_ratio, mid_expand_ratio, layers_num, in_down_ratio) for _ in range(n)))

class C2f_MSBlock(C2f):
    def __init__(self, c1, c2, n=1, kernel_sizes=[1, 3, 3], in_expand_ratio=3., mid_expand_ratio=2., layers_num=3, in_down_ratio=2., shortcut=False, g=1, e=0.5):
        super().__init__(c1, c2, n, shortcut, g, e)
        self.m = nn.ModuleList(MSBlock(self.c, self.c, kernel_sizes, in_expand_ratio, mid_expand_ratio, layers_num, in_down_ratio) for _ in range(n))

2.2 C2f_MSBlock的神经网络模块代码解析

这段代码实现了一个多尺度特征提取模块,分为三个主要类:MSBlockLayerMSBlockC2f_MSBlock。以下是每个类的详细解释:

1. MSBlockLayer

  • 功能: 实现一个基本的卷积层序列,用于处理特定尺度的特征图。

  • 构造函数参数:

    • inc: 输入通道数。

    • ouc: 输出通道数。

    • k: 卷积核大小。

  • 构造函数内容:

    • self.in_conv: 1x1卷积,用于调整输入通道数。

    • self.mid_conv: 使用深度可分离卷积(group convolution)的中间卷积层,卷积核大小为k

    • self.out_conv: 1x1卷积,将通道数还原为输入通道数。

  • forward函数: 顺序执行in_convmid_convout_conv,返回处理后的特征图。

2. MSBlock

  • 功能: 实现一个多尺度特征块,包含多个 MSBlockLayer 组成的分支,每个分支对应不同的卷积核大小。

  • 构造函数参数:

    • inc: 输入通道数。

    • ouc: 输出通道数。

    • kernel_sizes: 卷积核大小的列表,用于指定每个分支的卷积核大小。

    • in_expand_ratio: 输入通道扩展倍率。

    • mid_expand_ratio: 中间通道扩展倍率。

    • layers_num: 每个分支中MSBlockLayer的层数。

    • in_down_ratio: 输入通道缩减倍率。

  • 构造函数内容:

    • in_channel: 计算扩展后的输入通道数。

    • self.mid_channel: 每个分支的通道数。

    • groups: 深度卷积的组数(与通道数有关)。

    • self.in_conv: 用于调整输入特征图通道数的卷积层。

    • self.mid_convs: 一个包含多个分支的模块列表,每个分支使用不同的卷积核大小。

    • self.out_conv: 用于将多分支输出融合成最终输出的1x1卷积。

    • self.attention: 暂时未使用的注意力机制模块。

  • forward函数: 先通过in_conv处理输入,然后在各个分支中进行特征提取,最后通过拼接和卷积生成输出。如果定义了注意力机制,还会对输出进行进一步处理。

3. C2f_MSBlock

  • 功能: 继承自 C2f 类,是一个容器类,用于在其中集成多个 MSBlock

  • 构造函数参数:

    • c1: 输入通道数。

    • c2: 输出通道数。

    • n: MSBlock 的数量。

    • kernel_sizes: 卷积核大小的列表。

    • 其他参数 (in_expand_ratio, mid_expand_ratio, layers_num, in_down_ratio, shortcut, g, e): 用于配置 MSBlockC2f 类的各种特性。

  • 构造函数内容:

    • self.m: 包含多个 MSBlock 的模块列表,每个 MSBlock 按照指定参数进行初始化。

总结

这个代码通过 MSBlockLayer 实现了基础的多尺度特征提取单元,再通过 MSBlock 将这些单元组合成多分支模块,每个分支负责提取不同尺度的特征。最后,C2f_MSBlock 类将多个 MSBlock 组合在一起,用于构建更复杂的多尺度特征提取网络。这种设计能够有效地捕捉图像中不同尺度的特征,提高模型的检测能力。

2.3 更改init.py文件

关键步骤二:修改modules文件夹下的__init__.py文件,先导入函数   

然后在下面的__all__中声明函数  

2.4 添加yaml文件

关键步骤三:在/ultralytics/ultralytics/cfg/models/v8下面新建文件yolov8_C2f_MSBlock.yaml文件,粘贴下面的内容

  • OD【目标检测】
# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect

# Parameters
nc: 80  # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'
  # [depth, width, max_channels]
  n: [0.33, 0.25, 1024]  # YOLOv8n summary: 225 layers,  3157200 parameters,  3157184 gradients,   8.9 GFLOPs
  s: [0.33, 0.50, 1024]  # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPs
  m: [0.67, 0.75, 768]   # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs
  l: [1.00, 1.00, 512]   # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
  x: [1.00, 1.25, 512]   # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs

# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4
  - [-1, 3, C2f_MSBlock, [128, [1, 3, 3], 3, 2, 3, 2]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f_MSBlock, [256, [1, 5, 5], 3, 2, 3, 2]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f_MSBlock, [512, [1, 7, 7], 3, 2, 3, 2]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f_MSBlock, [1024, [1, 9, 9], 3, 2, 3, 2]]
  - [-1, 1, SPPF, [1024, 5]]  # 9

# YOLOv8.0n head
head:
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
  - [-1, 3, C2f, [512]]  # 12

  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)

  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]  # cat head P5
  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large)

  - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)
  • RTDETR
# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect

# Parameters
nc: 80  # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'
  # [depth, width, max_channels]
  n: [0.33, 0.25, 1024]  # YOLOv8n summary: 225 layers,  3157200 parameters,  3157184 gradients,   8.9 GFLOPs
  s: [0.33, 0.50, 1024]  # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPs
  m: [0.67, 0.75, 768]   # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs
  l: [1.00, 1.00, 512]   # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
  x: [1.00, 1.25, 512]   # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs

# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4
  - [-1, 3, C2f_MSBlock, [128, [1, 3, 3], 3, 2, 3, 2]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f_MSBlock, [256, [1, 5, 5], 3, 2, 3, 2]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f_MSBlock, [512, [1, 7, 7], 3, 2, 3, 2]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f_MSBlock, [1024, [1, 9, 9], 3, 2, 3, 2]]
  - [-1, 1, SPPF, [1024, 5]]  # 9

# YOLOv8.0n head
head:
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
  - [-1, 3, C2f, [512]]  # 12

  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)

  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]  # cat head P5
  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large)

  - [[15, 18, 21], 1, RTDETRDecoder, [nc]] # Detect(P3, P4, P5)
  • Seg【语义分割】
# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect

# Parameters
nc: 80  # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'
  # [depth, width, max_channels]
  n: [0.33, 0.25, 1024]  # YOLOv8n summary: 225 layers,  3157200 parameters,  3157184 gradients,   8.9 GFLOPs
  s: [0.33, 0.50, 1024]  # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPs
  m: [0.67, 0.75, 768]   # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs
  l: [1.00, 1.00, 512]   # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
  x: [1.00, 1.25, 512]   # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs

# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4
  - [-1, 3, C2f_MSBlock, [128, [1, 3, 3], 3, 2, 3, 2]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f_MSBlock, [256, [1, 5, 5], 3, 2, 3, 2]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f_MSBlock, [512, [1, 7, 7], 3, 2, 3, 2]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f_MSBlock, [1024, [1, 9, 9], 3, 2, 3, 2]]
  - [-1, 1, SPPF, [1024, 5]]  # 9

# YOLOv8.0n head
head:
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
  - [-1, 3, C2f, [512]]  # 12

  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
  - [-1, 3, C2f, [256]]  # 15 (P3/8-small)

  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f, [512]]  # 18 (P4/16-medium)

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]  # cat head P5
  - [-1, 3, C2f, [1024]]  # 21 (P5/32-large)

  - [[15, 18, 21], 1, Segment, [nc, 32, 256]] # Segment(P3, P4, P5)

温馨提示:因为本文只是对yolov8基础上添加模块,如果要对yolov8n/l/m/x进行添加则只需要指定对应的depth_multiple 和 width_multiple。不明白的同学可以看这篇文章: yolov8yaml文件解读——点击即可跳转  


# YOLOv8n
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.25  # layer channel multiple
max_channels: 1024 # max_channels
 
# YOLOv8s
depth_multiple: 0.33  # model depth multiple
width_multiple: 0.50  # layer channel multiple
max_channels: 1024 # max_channels
 
# YOLOv8l 
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple
max_channels: 512 # max_channels
 
# YOLOv8m
depth_multiple: 0.67  # model depth multiple
width_multiple: 0.75  # layer channel multiple
max_channels: 768 # max_channels
 
# YOLOv8x
depth_multiple: 1.33  # model depth multiple
width_multiple: 1.25  # layer channel multiple
max_channels: 512 # max_channels

2.5 注册模块

关键步骤四:在task.py的parse_model函数中注册

2.6 执行程序

在train.py中,将model的参数路径设置为yolov8_C2f_MSBlock.yaml的路径

建议大家写绝对路径,确保一定能找到

from ultralytics import YOLO
import warnings
warnings.filterwarnings('ignore')
from pathlib import Path
 
if __name__ == '__main__':
 
 
    # 加载模型
    model = YOLO("ultralytics/cfg/v8/yolov8.yaml")  # 你要选择的模型yaml文件地址
    # Use the model
    results = model.train(data=r"你的数据集的yaml文件地址",
                          epochs=100, batch=16, imgsz=640, workers=4, name=Path(model.cfg).stem)  # 训练模型

  🚀运行程序,如果出现下面的内容则说明添加成功🚀 

                   from  n    params  module                                       arguments
  0                  -1  1       464  ultralytics.nn.modules.conv.Conv             [3, 16, 3, 2]
  1                  -1  1      4672  ultralytics.nn.modules.conv.Conv             [16, 32, 3, 2]
  2                  -1  1      6416  ultralytics.nn.modules.block.C2f_MSBlock     [32, 32, 1, [1, 3, 3], 3, 2, 3, 2]
  3                  -1  1     18560  ultralytics.nn.modules.conv.Conv             [32, 64, 3, 2]
  4                  -1  2     42816  ultralytics.nn.modules.block.C2f_MSBlock     [64, 64, 2, [1, 5, 5], 3, 2, 3, 2]
  5                  -1  1     73984  ultralytics.nn.modules.conv.Conv             [64, 128, 3, 2]
  6                  -1  2    165504  ultralytics.nn.modules.block.C2f_MSBlock     [128, 128, 2, [1, 7, 7], 3, 2, 3, 2]
  7                  -1  1    295424  ultralytics.nn.modules.conv.Conv             [128, 256, 3, 2]
  8                  -1  1    379008  ultralytics.nn.modules.block.C2f_MSBlock     [256, 256, 1, [1, 9, 9], 3, 2, 3, 2]
  9                  -1  1    164608  ultralytics.nn.modules.block.SPPF            [256, 256, 5]
 10                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']
 11             [-1, 6]  1         0  ultralytics.nn.modules.conv.Concat           [1]
 12                  -1  1    148224  ultralytics.nn.modules.block.C2f             [384, 128, 1]
 13                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']
 14             [-1, 4]  1         0  ultralytics.nn.modules.conv.Concat           [1]
 15                  -1  1     37248  ultralytics.nn.modules.block.C2f             [192, 64, 1]
 16                  -1  1     36992  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 2]
 17            [-1, 12]  1         0  ultralytics.nn.modules.conv.Concat           [1]
 18                  -1  1    123648  ultralytics.nn.modules.block.C2f             [192, 128, 1]
 19                  -1  1    147712  ultralytics.nn.modules.conv.Conv             [128, 128, 3, 2]
 20             [-1, 9]  1         0  ultralytics.nn.modules.conv.Concat           [1]
 21                  -1  1    493056  ultralytics.nn.modules.block.C2f             [384, 256, 1]
 22        [15, 18, 21]  1    897664  ultralytics.nn.modules.head.Detect           [80, [64, 128, 256]]
YOLOv8_C2f_MSBlock summary: 609 layers, 3036000 parameters, 3035984 gradients, 8.6 GFLOPs

3. 完整代码分享

https://pan.baidu.com/s/1CYdp-yXZZFv0ye9sDEZw2w?pwd=vwri

提取码: vwri 

4. GFLOPs

关于GFLOPs的计算方式可以查看百面算法工程师 | 卷积基础知识——Convolution

未改进的YOLOv8nGFLOPs

img

改进后的GFLOPs

5. 进阶

可以与其他的注意力机制或者损失函数等结合,进一步提升检测效果

6. 总结

Multi-Scale Block (MS-Block) 是一种旨在增强实时目标检测中多尺度特征表示能力的核心组件。它通过分层特征融合策略,将输入特征图分成多个分支,并利用倒置瓶颈结构中的深度可分离卷积对不同分支进行处理。每个分支采用不同大小的卷积核,以有效捕捉不同尺度的特征,同时控制计算开销。之后,这些分支的输出会被拼接,并通过一个1x1卷积层进行通道间的交互,从而整合多尺度信息,生成具有丰富特征表示的输出特征图。MS-Block的设计重点在于在保持计算效率的同时,显著提高多尺度特征的捕捉能力,从而在实时目标检测中实现速度与精度的平衡。

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

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

相关文章

String框架基础补充

前言 本文将继续上一篇文章的内容对 Spring 数据访问层管理,Spring集成mybatis等知识进行补充,未看过上一篇文章的小伙伴可以点击下方链接,跳转观看上一篇文章Spring框架基础https://mp.csdn.net/mp_blog/creation/editor/141639879 Spring数据访问层管理 首先,我们需要知道 : …

软考高项彻底没用了?谁说的?站出来,我保证不笑场!

哎呀,最近这风言风语可不少啊,说咱们的软考高项证书成了“过气网红”,彻底没用了?这可真是让我哭笑不得,咱们得好好聊聊这个话题,不能让这“谣言”满天飞啊! 首先,我得说&#xff0…

直播电商如何重构人场关系?推荐这套电商精细化运营方案!

随着电子商务的不断发展,直播电商和货架电商已经成为两大主流的在线购物模式。它们各自以独特的方式满足消费者的购物需求,同时也有不同的商业挑战和机遇。本文将从消费者行为、技术应用、品牌策略等多个角度分析这两种电商模式的核心区别。同时&#xf…

大众集团25届校招社招网申入职SHL测评题库:综合能力测评、性格问卷、英语测评考什么?

恭喜您通过大众汽车(中国)科技有限公司的简历初。请点击下面的测评链接,在5天内完成测评,过期失效(例:3.11收到链接,3.15为最后一天有效期)。每位人选只有一次测评机会。 ​大众汽车入职测试细节: 1.性格问卷:25 分钟 2.综合能力:46 分钟&a…

Python 轻松去除验证码干扰点,让识别不再犯难

Python 轻松去除验证码干扰点,让识别不再犯难 引言一、干扰点噪声二、图片降噪三、测试运行结果写在最后 作者:高玉涵 时间:2024.8.29 21:52 博客:blog.csdn.net/cg_i 环境:Windows10、Python 3.11.3、PIL、Tesseract-…

Unet改进10:在不同位置添加CPCA||通道先验卷积注意力机制

本文内容:在不同位置添加CPCA注意力机制 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 低对比度和显著的器官形状变化等特征经常出现在医学图像中。现有注意机制的自适应能力普遍不足,限制了医学影像分割性能的提高。本文提出了一种有效的通道先验卷积…

储能电池热失控监测系统的研发难点是什么?

​ ​​储能电池热失控监测系统的研发难点主要包括以下几个方面: ​ ​1.准确的早期预警 ​ ​在热失控发生的早期阶段,电池的温度、电压、电流等特征参数变化可能非常缓慢,通过传统的监测方法难以及早地监测到电池故障。而此时电池…

使用C++,仿照string类,实现myString

类由结构体演化而来,只需要将struct改成关键字class,就定义了一个类 C中类和结构体的区别:默认的权限不同,结构体中默认权限为public,类中默认权限为private 默认的继承方式不同,结构体的默认继承方式为p…

LLM的发展简述

文章目录 1. NLP的发展简史2. LLM 的进展3. 参考 1. NLP的发展简史 信息理论的创立:20世纪50年代,Claude Shannon 奠定了信息理论的基础,引入了熵和冗余等概念,对 NLP 和计算语言学产生了深远影响。 形式语法的发展:…

代码随想录(day8)—环形链表

题目 预备知识点: for和while的区别 while语句属于循环语句,在判断是,如果条件为true,则会继续判断,直到false为止,即会进行多次判断(除非一开始条件就是错的)。 if语句属于条件判…

炫光HUD杂散光测试方法及设备

HUD杂散光测试概述 HUD(Heads-Up Display)抬头显示器是现代汽车中的一项先进技术,它可以将重要信息如速度、导航等投射在驾驶员的视线前方,从而减少低头查看仪表盘的次数,提高行车安全。然而,HUD在实际使用…

数据主权与隐私保护的深入探讨

随着数字化进程的加速,数据已成为当今世界的重要资源。数据主权和隐私保护这两个概念也越来越受到关注。数据主权涉及到国家对数据的控制权和管理权,而隐私保护则关乎个人数据的安全性和隐私权利。两者相互交织,共同塑造了数字时代的法律、经…

PTA - python暑假题集1

目录 7-1 Hello World!7-2 计算摄氏温度7-3 计算物体自由下落的距离7-4 整数四则运算7-5 求整数均值7-6 输出带框文字7-7 整数152的各位数字7-8 计算火车运行时间7-9 计算存款利息7-10 逆序的三位数7-11 重要的话说三遍7-12 后天7-13 I Love GPLT7-14 是不是太胖了7-15 计算指数…

day44——C++对C的扩充

八、C对函数的扩充 8.1 函数重载(overload) 1> 概念 函数重载就是能够实现"一名多用",是实现泛型编程的一种 泛型编程:试图以不变的代码,来实现可变的功能 2> 引入背景 程序员在写函数时&#x…

某系统存在任意文件下载漏洞

穷者,谁不想达,达者,更畏惧穷。为求发达,穷人兢兢业业,辛辛苦苦,农耕其田,工利其器,商务其业,学读其书,人人都在独善其身,可除了那些少数的书生可…

VS2022打包Docker镜像

1. 前置环境 操作系统win10/win11 安装 Docker Desktop 2. 演示项目 https://gitee.com/izory/ZrAdminNetCore .net8 分支为例 3. 添加 docker支持 4. 配置工程文件 在.proj 文件加上 <ContainerRepository>ZrAdminCore</ContainerRepository> <Containe…

【C++ 面试 - 内存管理】每日 3 题(八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

视频压缩工具哪个好?视频压缩工具安利

还在为视频文件过大而烦恼吗&#xff1f;想要快速分享或上传视频却受限于空间或时间&#xff1f; 别担心&#xff0c;今天我来告诉你们&#xff1a;视频压缩成文件怎么弄。 无需复杂操作&#xff0c;轻松几步&#xff0c;就能让你的视频文件瘦身成功&#xff0c;既保留关键内…

深度学习基础—结构化机器学习项目

1.正交化 这是一个老式电视&#xff0c;有一组旋钮可以对画面进行调节&#xff0c;例如高度、宽度、画面梯形角度、画面位置、画面旋转等等&#xff0c;但是如果有一个旋钮&#xff0c;旋转时可以调节上面所有参数&#xff0c;那么就会出现一种情况&#xff1a;当前的画面高度和…

jconsole远程连接

jconsole可以远程连接的前提&#xff08;需要在部署应用时像下面示例这样设置&#xff09;&#xff1a; -Djava.rmi.server.hostname127.0.0.1 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port3214 -Dcom.sun.management.jmxremote.sslfalse -Dcom.sun.m…