YOLOv8改进 | 2023 | 通过RFAConv重塑空间注意力(深度学习的前沿突破)

一、本文介绍

本文给大家带来的改进机制是RFAConv,全称为Receptive-Field Attention Convolution,是一种全新的空间注意力机制。与传统的空间注意力方法相比,RFAConv能够更有效地处理图像中的细节和复杂模式(适用于所有的检测对象都有一定的提点)。这不仅让YOLOv8在识别和定位目标时更加精准,还大幅提升了处理速度和效率。本文章深入会探讨RFAConv如何在YOLOv8中发挥作用,以及它是如何改进在我们的YOLOv8中的。我将通过案例的角度来带大家分析其有效性(结果训练结果对比图)

适用检测目标:亲测所有的目标检测均有一定的提点

推荐指数:⭐⭐⭐⭐⭐

  专栏回顾:YOLOv8改进系列专栏——本专栏持续复习各种顶会内容——科研必备 

效果回顾展示->

因为资源有限我发的文章都要做对比实验所以本次实验我只用了一百张图片检测的是火灾训练了一百个epoch,该结果只能展示出该机制有效,但是并不能产生决定性结果,因为具体的效果还要看你的数据集和实验环境所影响(这次找的数据集质量好像不太好效果波动很大)。 

图片分析->在我的数据集上大家可以看到mAP50大概增长了0.4左右。

目录

一、本文介绍

二、RFAConv结构讲解

2.1、RAFCAonv主要思想

2.2、感受野空间特征

2.3、解决参数共享问题

2.4、提高大尺寸卷积核的效率

三、RFAConv代码

3.1 RFAConv本地代码

3.2 修改RFAConv的bug 

3.3 修改了RFAConv的C2f和Bottleneck模块

四、手把手教你添加RFAConv和C2f_RFAConv模块

4.1 RFAConv的添加教程

4.2 RFAConv的yaml文件和训练截图

4.2.1 RFAConv的yaml文件

4.2.2 RFAConv的训练过程截图 

五、RFAConv可添加的位置

5.1 推荐RFAConv可添加的位置 

5.2 图示RFAConv可添加的位置 

六、本文总结


二、RFAConv结构讲解

论文地址:官方论文地址

代码地址:官方代码地址


2.1、RAFCAonv主要思想

RFAConv(Receptive-Field Attention Convolution)的主要思想是将空间注意力机制与卷积操作相结合,从而提高卷积神经网络(CNN)的性能。这种方法的核心在于优化卷积核的工作方式,特别是在处理感受野内的空间特征时。以下是RFAConv的几个关键思想:

1. 感受野空间特征的重点关注:RFAConv特别关注于感受野内的空间特征,不仅仅局限于传统的空间维度。这种方法允许网络更有效地理解和处理图像中的局部区域,从而提高特征提取的精确性。

2. 解决参数共享问题:在传统的CNN中,卷积核在处理不同区域的图像时共享同样的参数,这可能限制了模型对于复杂模式的学习能力。RFAConv通过引入注意力机制,能够更灵活地调整卷积核的参数,针对不同区域提供定制化的处理。

3. 提高大尺寸卷积核的效率:对于大尺寸卷积核,仅使用标准的空间注意力可能不足以捕获所有重要的信息。RFAConv通过提供有效的注意力权重,使得大尺寸卷积核能够更有效地处理图像信息。

总结:RFAConv通过结合空间注意力和感受野特征的处理,为卷积神经网络提供了一种新的、更高效的方式来提取和处理图像特征,尤其是在处理复杂或大尺寸的输入时。

下面我来分别介绍这几点->


2.2、感受野空间特征

感受野空间特征是指卷积神经网络(CNN)中,卷积层能“看到”的输入数据的局部区域。在CNN中,每个卷积操作的输出是基于输入数据的一个小窗口,或者说是一个局部感受野。这个感受野定义了卷积核可以接触到的输入数据的大小和范围。

感受野的概念对于理解CNN如何从输入数据中提取特征是至关重要的。在网络的初级层,感受野通常很小,允许模型捕捉到细微的局部特征,如边缘和角点。随着数据通过更多的卷积层,通过层层叠加,感受野逐渐扩大,允许网络感知到更大的区域,捕捉到更复杂的特征,如纹理和对象的部分。

在CNN的上下文中,感受野空间特征指的是每个卷积操作能够感知的输入图像区域中的特征。这些特征可以包括颜色、形状、纹理等基本视觉元素。在传统的卷积网络中,感受野通常是固定的,并且每个位置的处理方式都是相同的。但是,如果网络能够根据每个区域的不同特点来调整感受野的处理方式,那么网络对特征的理解就会更加精细和适应性更强。

上图展示了一个3x3的卷积操作。在这个操作中,特征是通过将卷积核与同样大小的感受野滑块相乘然后求和得到的。具体来说,输入图像X上的每一个3x3的区域(即感受野)都被一个3x3的卷积核K处理。每个感受野内的元素,X_{i,j}(其中i和j表示在感受野内的位置)都与卷积核K内对应位置的权重,K_{i,j}相乘,然后这些乘积会被求和得到一个新的特征值F。这个过程在整个输入图像上滑动进行,以生成新的特征图。这种标准的卷积操作强调了局部连接和权重共享的概念,即卷积核的权重对整个输入图。

总结:在RFAConv中,感受野空间特征被用来指导注意力机制,这样模型就不仅仅关注于当前层的特定区域,而是根据输入数据的复杂性和重要性动态调整感受野。通过这种方式,RFAConv能够为不同区域和不同尺寸的感受野提供不同的处理,使得网络能够更加有效地捕捉和利用图像中的信息。


2.3、解决参数共享问题

RFAConv卷积以解决参数共享问题,RFAConv通过引入注意力机制,允许网络为每个感受野生成特定的权重。这样,卷积核可以根据每个感受野内的不同特征动态调整其参数,而不是对所有区域一视同仁。

具体来说,RFAConv利用空间注意力来确定感受野中每个位置的重要性,并据此调整卷积核的权重。这样,每个感受野都有自己独特的卷积核,而不是所有感受野共享同一个核。这种方法使得网络能够更细致地学习图像中的局部特征,从而有助于提高整体网络性能。

通过这种方法,RFAConv提升了模型的表达能力,允许它更精确地适应和表达输入数据的特征,尤其是在处理复杂或多变的图像内容时。

上图展示了一个卷积操作的过程,其中卷积核参数 K_{i}通过将注意力权重 A_{i}与卷积核参数 K 相乘得到。这意味着每个感受野滑块的卷积操作都有一个独特的卷积核参数,这些参数是通过将通用的卷积核参数与特定于该位置的注意力权重相结合来获得的。

具体地说,这个过程将注意力机制与卷积核相结合,为每个感受野位置产生一个定制化的卷积核。例如,图中的 Kernel 1、Kernel 2 和 Kernel 3 分别是通过将通用卷积核参数 K 与对应的注意力权重 A_{1}​、A_{2}​ 和 A_{3}​ 相乘得到的。这种方法允许网络在特征提取过程中对不同空间位置的特征赋予不同的重要性,从而增强了模型对关键特征的捕获能力。

总结:这样的机制增加了卷积神经网络的表达能力,使得网络能够更加灵活地适应不同的输入特征,并有助于提高最终任务的性能。这是一种有效的方式来处理传统卷积操作中的参数共享问题,因为它允许每个位置的卷积核适应其处理的特定区域。


2.4、提高大尺寸卷积核的效率

RFAConv通过利用感受野注意力机制来动态调整卷积核的权重,从而为每个区域的特征提取提供了定制化的关注度。这样,即便是大尺寸卷积核,也能够更加有效地捕捉和处理重要的空间特征,而不会对不那么重要的信息分配过多的计算资源。

具体来说,RFAConv方法允许网络识别和强调输入特征图中更重要的区域,并且根据这些区域调整卷积核的权重。这意味着网络可以对关键特征进行重加权,使得大尺寸卷积核不仅能够捕捉到广泛的信息,同时也能够集中计算资源在更有信息量的特征上,从而提升了整体的处理效率和网络性能。

上图描述了感受野滑块中特征的重叠,这是在标准卷积操作中常见的现象。特征的重叠导致了注意力权重的共享问题,意味着不同的感受野可能会对相同的输入特征使用相同的注意力权重。

在图中,F_{1}​,F_{2}​,...F_{N}代表不同感受野滑块内的特征输出,它们是通过将输入特征 X 与对应的注意力权重 A 以及卷积核 K 的权重进行逐元素乘法运算后得到的。例如,F_{1} 是通过将 X_{11}乘以对应的注意力权重 A_{11}和卷积核权重 K_{1}计算得到的,以此类推。

该图强调了每个感受野滑块内的卷积操作的参数不应该完全共享,而是应该根据每个特定区域内的特征和相应的注意力权重进行调整。这种调整允许网络对每个局部区域进行更加精细的处理,能够更好地捕捉和响应输入数据的特定特征,而不是简单地对整个图像应用相同的权重。这样的方法能够提升网络对特征的理解和表示,从而改善最终的学习和预测性。

总结:通过这种方法,RFAConv提升了模型的表达能力,允许它更精确地适应和表达输入数据的特征,尤其是在处理复杂或多变的图像内容时。这种灵活的参数调整机制为提高卷积神经网络的性能和泛化能力提供了新的途径。


三、RFAConv代码

3.1 RFAConv本地代码

该代码为RFAConv的本体,使用方式请看章节四。

from torch import nn
from einops import rearrange



class RFAConv(nn.Module):  # 基于Unfold实现的RFAConv
    def __init__(self, in_channel, out_channel, kernel_size=3):
        super().__init__()
        self.kernel_size = kernel_size
        self.unfold = nn.Unfold(kernel_size=(kernel_size, kernel_size), padding=kernel_size // 2)
        self.get_weights = nn.Sequential(
            nn.Conv2d(in_channel * (kernel_size ** 2), in_channel * (kernel_size ** 2), kernel_size=1,
                      groups=in_channel),
            nn.BatchNorm2d(in_channel * (kernel_size ** 2)))

        self.conv = nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, padding=0, stride=kernel_size)
        self.bn = nn.BatchNorm2d(out_channel)
        self.act = nn.ReLU()

    def forward(self, x):
        b, c, h, w = x.shape
        unfold_feature = self.unfold(x)  # 获得感受野空间特征  b c*kernel**2,h*w
        x = unfold_feature
        data = unfold_feature.unsqueeze(-1)
        weight = self.get_weights(data).view(b, c, self.kernel_size ** 2, h, w).permute(0, 1, 3, 4, 2).softmax(-1)
        weight_out = rearrange(weight, 'b c h w (n1 n2) -> b c (h n1) (w n2)', n1=self.kernel_size,
                               n2=self.kernel_size)  # b c h w k**2 -> b c h*k w*k
        receptive_field_data = rearrange(x, 'b (c n1) l -> b c n1 l', n1=self.kernel_size ** 2).permute(0, 1, 3,
                                                                                                        2).reshape(b, c,
                                                                                                                   h, w,
                                                                                                                   self.kernel_size ** 2)  # b c*kernel**2,h*w ->  b c h w k**2
        data_out = rearrange(receptive_field_data, 'b c h w (n1 n2) -> b c (h n1) (w n2)', n1=self.kernel_size,
                             n2=self.kernel_size)  # b c h w k**2 -> b c h*k w*k
        conv_data = data_out * weight_out
        conv_out = self.conv(conv_data)
        return self.act(self.bn(conv_out))





3.2 修改RFAConv的bug 

因为以上的代码不能够直接使用在我们的YOLOv8中会报错而且参数对不上,我对其外层嵌套了一个模块。 

class RFAConv_yolov8(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=1, stride=1, g=1, dilation=1):
        super().__init__()
        self.conv = Conv(in_channels, out_channels, k=1)

        self.RFAConv = RFAConv(out_channels, out_channels, kernel_size=3)

        self.bn = nn.BatchNorm2d(out_channels)

        self.gelu = nn.GELU()

    def forward(self, x):
        x = self.conv(x)

        x = self.RFAConv(x)

        x = self.gelu(self.bn(x))
        return x


3.3 修改了RFAConv的C2f和Bottleneck模块

class Bottleneck_RFAConv(nn.Module):
    """Standard bottleneck."""

    def __init__(self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):
        """Initializes a bottleneck module with given input/output channels, shortcut option, group, kernels, and
        expansion.
        """
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, k[0], 1)
        self.cv2 = RFAConv_yolov8(c_, c2, k[1], 1, g=g)
        self.add = shortcut and c1 == c2

    def forward(self, x):
        """'forward()' applies the YOLO FPN to input data."""
        return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))


class C2f_RFAConv(nn.Module):
    """Faster Implementation of CSP Bottleneck with 2 convolutions."""
    def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):
        """Initialize CSP bottleneck layer with two convolutions with arguments ch_in, ch_out, number, shortcut, groups,
        expansion.
        """
        super().__init__()
        self.c = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, 2 * self.c, 1, 1)
        self.cv2 = Conv((2 + n) * self.c, c2, 1)  # optional act=FReLU(c2)
        self.m = nn.ModuleList(Bottleneck_RFAConv(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n))

    def forward(self, x):
        """Forward pass through C2f layer."""
        x = self.cv1(x)
        x = x.chunk(2, 1)
        y = list(x)
        # y = list(self.cv1(x).chunk(2, 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))

    def forward_split(self, x):
        """Forward pass using split() instead of chunk()."""
        y = list(self.cv1(x).split((self.c, self.c), 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))


四、手把手教你添加RFAConv和C2f_RFAConv模块

4.1 RFAConv的添加教程

添加教程这里不再重复介绍、因为专栏内容有许多,添加过程又需要截特别图片会导致文章大家读者也不通顺如果你已经会添加注意力机制了,可以跳过本章节,如果你还不会,大家可以看我下面的文章里面详细的介绍了拿到一个任意机制(C2f、Conv、Bottleneck、Loss、DetectHead)如何添加到你的网络结构中去。

这个卷积也可以放在C2f和Bottleneck中进行使用可以即插即用,个人觉得放在Bottleneck中效果比较好。

添加教程->YOLOv8改进 | 如何在网络结构中添加注意力机制、C2f、卷积、Neck、检测头


4.2 RFAConv的yaml文件和训练截图

4.2.1 RFAConv的yaml文件

下面的配置文件为我修改的RFAConv的位置。

# 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, [128, True]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f, [256, True]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f, [1024, True]]
  - [-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_RFAConv, [256]]  # 15 (P3/8-small)

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

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

  - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)


4.2.2 RFAConv的训练过程截图 

下面是添加了RFAConv的训练截图。

下面的是将RFAConv机制添加到了C2f和Bottleneck。

(最近有人说我改的代码是没有发全的,我不知道这群人是怎么说出这种话的,希望大家如果用我的代码成功的可以在评论区支持一下,我也好发更多的改进毕竟免费给大家看。同时有问题皆可在评论区留言我看到都会回复) 

​​


五、RFAConv可添加的位置

5.1 推荐RFAConv可添加的位置 

RFAConv是一种即插即用的模块,其可以添加的位置有很多,添加的位置不同效果也不同,所以我下面推荐几个添加的位,置大家可以进行参考,当然不一定要按照我推荐的地方添加。

  1. 残差连接中:在残差网络的残差连接中加入RFAConv

  2. Neck部分:YOLOv8的Neck部分负责特征融合,这里添加修改后的C2f_RFAConv可以帮助模型更有效地融合不同层次的特征。

  3. 检测头中的卷积:在最终的输出层前加入RFAConv可以使模型在做出最终预测之前,更加集中注意力于最关键的特征。

文字大家可能看我描述不太懂,大家可以看下面的网络结构图中我进行了标注。


5.2 图示RFAConv可添加的位置 

​​


六、本文总结

到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv8改进有效涨点专栏,本专栏目前为新开的平均质量分98分,后期我会根据各种最新的前沿顶会进行论文复现,也会对一些老的改进机制进行补充,目前本专栏免费阅读(暂时,大家尽早关注不迷路~)如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

专栏回顾:YOLOv8改进系列专栏——本专栏持续复习各种顶会内容——科研必备

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

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

相关文章

C语言——写一个简单函数,找两个数中最大者

#include <stdio.h>int max( int a, int b ) { return a>b ? a:b; }int main() { int a, b;printf("输入两个数:\n");scanf("%d %d", &a, &b);printf("max %d\n", max(a, b));return 0; }输出结果&#xff1a;

Python---文件

文件--- 内存中存放的数据在计算机关机后就会消失。要长久保存数据&#xff0c;就要使用硬盘、光盘、U 盘等设备。为了便于数据的管理和检索&#xff0c;引入了“文件”的概念。 一篇文章、一段视频、一个可执行程序&#xff0c;都可以被保存为一个文件&#xff0c;并赋予一个…

TiDB专题---1、TiDB简介和特性

什么是TiDB TiDB 是一个分布式 NewSQL 数据库&#xff0c;它支持水平弹性扩展、ACID 事务、标准 SQL、MySQL 语法和 MySQL 协议&#xff0c;具有数据强一致的高可用特性&#xff0c;是一个不仅适合 OLTP 场景还适合 OLAP 场景的混合数据库。 TiDB 是 PingCAP 公司自主设计、研发…

pycharm编译报错处理

1.c生成工具下载 https://visualstudio.microsoft.com/visual-cpp-build-tools/ 在这里插入图片描述 pip install pycocotools

Python解释器和环境变量配置(超详细)

一、 python解释器下载 1.百度python官网并打开 官网网址&#xff1a;www.python.org/ 在这里插入图片描述 2.选择DownLoads&#xff0c;Windows并打开 3.在下图页面选择你需要的版本下载即可&#xff08;本文以python 3.10.4版本演示&#xff09; 在这里插入图片描述 二、安…

Redis集群模式

Redis集群主要有三种模式 主从复制模式&#xff08;Master-Slave&#xff09;、哨兵模式&#xff08;Sentinel&#xff09;和Cluster模式 主从复制模式&#xff1a;适用于数据备份和读写分离场景&#xff0c;配置简单&#xff0c;但在主节点故障时需要手动切换。哨兵模式&…

Python使用——发送Get请求,模拟http请求 进行SSH连接服务器

前言 本篇博客是python开发的使用案例博客&#xff0c;结合一些具体的案例进行阐述&#xff0c;本篇博客主要内容是使用Python发送Get请求&#xff0c;模拟http请求&#xff0c;后面可以搞个爬虫出来&#xff0c;另外就是如何使用Python进行SSH连接服务器。 其他相关的博客文…

数据结构(超详细讲解!!)第二十六节 图(上)

1.基本概念 图&#xff08;Graph&#xff09;是一种较线性表和树更为复杂的非线性结构。是对结点的前趋和后继个数不加限制的数据结构&#xff0c;用来描述元素之间“多对多”的关系(即结点之间的关系是任意的)。 一个图G &#xff08;V&#xff0c;E&#xff09;由顶点&…

思维跳动:抖店商品怎么设置拼团?

在抖店上销售商品时&#xff0c;设置拼团活动是一种促销策略&#xff0c;可以吸引更多用户参与购买&#xff0c;并增加销量。下面将介绍一些方法和步骤&#xff0c;帮助你在抖店中设置商品的拼团活动。 一、抖店商品怎么设置拼团&#xff1f; 首先&#xff0c;选择适合的商品进…

HP1010 | 业界首款图腾柱 PFC 专用数字控制器震撼来袭!

随着节能标准和客户需求的不断提高&#xff0c;电源解决方案的效率和尺寸也在不断优化&#xff0c;设计紧凑高效的 PFC 电源是一个复杂的开发挑战。随着第三代半导体器件氮化镓和碳化硅的大范围应用&#xff0c;图腾柱无桥 PFC&#xff08;TPPFC&#xff09;应用获得极大的拓展…

Kettle连接到GBase 8s数据库

1&#xff0c;将GBase 8s数据库驱动放到kettle的lib目录下 如下图&#xff0c;在data-integration\lib下添加连接GBase 8s数据库的驱动gbasedbtjdbc.jar(视Server版本&#xff0c;增加匹配的驱动) 2&#xff0c;在 文件 -> 新建 -> 数据库连接 或者是在 转换 -> D…

Python 利用aiohttp异步流式下载文件

背景 本篇文章为小编翻译文章&#xff0c;小编在查找资料时看到的一篇文章&#xff0c;看了后感觉不错&#xff0c;就翻译过来&#xff0c;供大家参考学习 文章原文地址&#xff1a;https://www.slingacademy.com/article/python-aiohttp-how-to-download-files-using-stream…

6、Qt延时的使用

一、sleep() 1、说明 QThread类中如下三个静态函数&#xff1a; QThread::sleep(n); //延迟n秒 QThread::msleep(n); //延迟n毫秒 QThread::usleep(n); //延迟n微妙 这种方式使用简单&#xff0c;但是会阻塞线程&#xff0c;有界面时界面会卡死&#xff0c;一般在非GUI线…

Linux常用命令——cd命令

文章目录 1. 简介2. 命令参数3. 常见用法与实例3.1 基本用法3.2 使用绝对路径或相对路径3.3 使用特殊字符3.4 使用参数 4. 总结 1. 简介 cd命令是Linux系统中最基础且频繁使用的命令之一&#xff0c;用于改变当前工作目录。它是“change directory”的缩写&#xff0c;对于任何…

mybatis快速入门(基于Mapper接口编程)

1、准备数据模型&#xff0c;建库建表 CREATE DATABASE mybatis-example;USE mybatis-example;CREATE TABLE t_emp(emp_id INT AUTO_INCREMENT,emp_name CHAR(100),emp_salary DOUBLE(10,5),PRIMARY KEY(emp_id) );INSERT INTO t_emp(emp_name,emp_salary) VALUES("tom&qu…

北美运营商T-mobile认证分级简介和定义类型

T-mobile认证如果对于成品来说&#xff0c;有个好处就是可以选用经过T-mobile认证过的模组或者芯片&#xff0c;如果产品使用的芯片或者模组是没有经过认证的&#xff0c;测试量和测试时间方面会比使用认证过的多一些。此外T-mobile认证对产品的认证进行分级管理&#xff1a;认…

Netty Review - 探索Pipeline的Inbound和Outbound

文章目录 概念Server CodeClient CodeInboundHandler和OutboundHandler的执行顺序在InboundHandler中不触发fire方法InboundHandler和OutboundHandler的执行顺序如果把OutboundHandler放在InboundHandler的后面&#xff0c;OutboundHandler会执行吗 概念 我们知道当boss线程监控…

Linux常用命令----mkdir命令

文章目录 1. 基础概念2. 参数含义3. 常见用法4. 实例演示5. 结论 在Linux操作系统中&#xff0c;mkdir 命令是用来创建目录的基础命令。这个命令简单但极其强大&#xff0c;是每个Linux用户都应当熟悉的工具之一。以下是对mkdir命令的详细介绍&#xff0c;包括其参数含义、常见…

【C++】: unordered_map的使用

1、概念 key 键值的类型。unordered_map中的每个元素都是由其键值唯一标识的。 T 映射值的类型。unordered_map中的每个元素都用来存储一些数据作为其映射值。 Hash 一种一元函数对象类型&#xff0c;它接受一个key类型的对象作为参数&#xff0c;并根据该对象返回size_t类型…

jenkins-cicd基础操作

1.先决条件 1.首先我个人势在k8s集群中创建的jenkins,部署方法搭建 k8s部署jenkins-CSDN博客 2.安装指定插件. 1.Gitlab plugin 用于调用gitlab-api的插件 2.Kubernetes plugin jenkins与k8s进行交互的插件,可以用来自动化的构建和部署 3.Build Authorizatio…