YOLOv9改进策略 | 添加注意力篇 | 利用YOLO-Face提出的SEAM注意力机制优化物体遮挡检测(附代码 + 修改教程)

 一、本文介绍

本文给大家带来的改进机制是由YOLO-Face提出能够改善物体遮挡检测的注意力机制SEAM,SEAM(Spatially Enhanced Attention Module)注意力网络模块旨在补偿被遮挡面部的响应损失,通过增强未遮挡面部的响应来实现这一目标,其希望通过学习遮挡面和未遮挡面之间的关系来改善遮挡情况下的损失从而达到改善物体遮挡检测的效果,本文将通过介绍其主要原理后,提供该机制的代码和修改教程,并附上运行的yaml文件和运行代码,小白也可轻松上手。。

欢迎大家订阅我的专栏一起学习YOLO! 

 专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏 


目录

 一、本文介绍

二、原理介绍

2.1 遮挡改进

2.2 SEAM模块

2.3 排斥损失 

三、核心代码

四、添加教程

 4.1 修改一

4.2 修改二 

4.3 修改三 

4.4 修改四 

五、SEAM的yaml文件和运行记录

5.1 SEAM的yaml文件

5.2 MultiSEAM的yaml文件

5.3 训练过程截图 

五、本文总结


二、原理介绍

2.1 遮挡改进

本文重点介绍遮挡改进,其主要体现在两个方面:注意力网络模块(SEAM)排斥损失(Repulsion Loss)

1. SEAM模块:SEAM(Spatially Enhanced Attention Module)注意力网络模块旨在补偿被遮挡面部的响应损失,通过增强未遮挡面部的响应来实现这一目标。SEAM模块通过深度可分离卷积和残差连接的组合来实现,其中深度可分离卷积按通道进行操作,虽然可以学习不同通道的重要性并减少参数量,但忽略了通道间的信息关系。为了弥补这一损失,不同深度卷积的输出通过点对点(1x1)卷积组合。然后使用两层全连接网络融合每个通道的信息,以增强所有通道之间的联系。这种模型希望通过学习遮挡面和未遮挡面之间的关系,来弥补遮挡情况下的损失。

2. 排斥损失(Repulsion Loss):一种设计来处理面部遮挡问题的损失函数。具体来说,排斥损失被分为两部分:RepGT和RepBox。RepGT的功能是使当前的边界框尽可能远离周围的真实边界框,而RepBox的目的是使预测框尽可能远离周围的预测框,从而减少它们之间的IOU,以避免某个预测框被NMS抑制,从而属于两个面部。


2.2 SEAM模块

下图展示了SEAM(Separated and Enhancement Attention Module)的架构以及CSMM(Channel and Spatial Mixing Module)的结构

左侧是SEAM的整体架构,包括三个不同尺寸(patch-6、patch-7、patch-8)的CSMM模块。这些模块的输出进行平均池化,然后通过通道扩展(Channel exp)操作,最后相乘以提供增强的特征表示。右侧是CSMM模块的详细结构,它通过不同尺寸的patch来利用多尺度特征,并使用深度可分离卷积来学习空间维度和通道之间的相关性。模块包括了以下元素:

(a)Patch Embedding:对输入的patch进行嵌入。
(b)GELU:Gaussian Error Linear Unit,一种激活函数。
(c)BatchNorm:批量归一化,用于加速训练过程并提高性能。
(d)Depthwise Convolution:深度可分离卷积,对每个输入通道分别进行卷积操作。
(f)Pointwise Convolution:逐点卷积,其使用1x1的卷积核来融合深度可分离卷积的特征。

这种模块设计旨在通过对空间维度和通道的细致处理,从而增强网络对遮挡面部特征的注意力和捕捉能力。通过综合利用多尺度特征和深度可分离卷积,CSMM在保持计算效率的同时,提高了特征提取的精确度。这对于面部检测尤其重要,因为面部特征的大小、形状和遮挡程度可以在不同情况下大相径庭。通过SEAM和CSMM,YOLO-FaceV2提高了模型对复杂场景中各种面部特征的识别能力。


2.3 排斥损失 

排斥损失(Repulsion Loss)是一种用于处理面部检测中遮挡问题的损失函数。在面部检测中,类内遮挡可能会导致一个面部包含另一个面部的特征,从而增加错误检测率。排斥损失能够有效地通过排斥效应来缓解这一问题。排斥损失被分为两个部分:RepGTRepBox

(a)RepGT损失:其功能是使当前边界框尽可能远离周围的真实边界框。这里的“周围真实边界框”指的是与除了要预测的边界框外的面部标签具有最大IoU的那个边界框。RepGT损失的计算方法如下:

L_{\text{RepGT}} = \sum_{P \in P^+} \text{SmoothLn}(\text{IoG}(P, G_{\text{Rep}}))

其中,P​代表面部预测框,G_{\text{Rep}}​是周围具有最大IoU的真实边界框。这里的IoG(Intersection over Ground truth)定义为\frac{\text{area}(P \cap G)}{\text{area}(G)}​,且其值范围在0到1之间。SmoothLn​是一个连续可导的对数函数,\sigma​是一个在[0,1)范围内的平滑参数,用于调整排斥损失对异常值的敏感度。

(b)RepBox损失:其目的是使预测框尽可能远离周围的预测框,从而减少它们之间的IOU,以避免一个预测框因NMS(非最大抑制)而被压制,并归属于两个面部。预测框被分成多个组,不同组之间的预测框对应不同的面部标签。对于不同组之间的预测框p_i​和p_j​,希望它们之间的重叠面积尽可能小。RepBox也使用SmoothLn作为优化函数。

L_{\text{RepBox}} = \sum_{i \neq j} \text{SmoothLn}(\text{IoU}(B_{p_i}, B_{p_j}))

排斥损失通过使边界框之间保持距离,减少预测框之间的重叠,从而提高面部检测在遮挡情况下的准确性。


三、核心代码

代码的使用方式看章节四!

import torch
import torch.nn as nn

__all__ = ['SEAM', 'MultiSEAM']

class Residual(nn.Module):
    def __init__(self, fn):
        super(Residual, self).__init__()
        self.fn = fn

    def forward(self, x):
        return self.fn(x) + x

class SEAM(nn.Module):
    def __init__(self, c1, n=1, reduction=16):
        super(SEAM, self).__init__()
        c2 = c1
        self.DCovN = nn.Sequential(
            # nn.Conv2d(c1, c2, kernel_size=3, stride=1, padding=1, groups=c1),
            # nn.GELU(),
            # nn.BatchNorm2d(c2),
            *[nn.Sequential(
                Residual(nn.Sequential(
                    nn.Conv2d(in_channels=c2, out_channels=c2, kernel_size=3, stride=1, padding=1, groups=c2),
                    nn.GELU(),
                    nn.BatchNorm2d(c2)
                )),
                nn.Conv2d(in_channels=c2, out_channels=c2, kernel_size=1, stride=1, padding=0, groups=1),
                nn.GELU(),
                nn.BatchNorm2d(c2)
            ) for i in range(n)]
        )
        self.avg_pool = torch.nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(c2, c2 // reduction, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(c2 // reduction, c2, bias=False),
            nn.Sigmoid()
        )

        self._initialize_weights()
        # self.initialize_layer(self.avg_pool)
        self.initialize_layer(self.fc)


    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.DCovN(x)
        y = self.avg_pool(y).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        y = torch.exp(y)
        return x * y.expand_as(x)

    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.xavier_uniform_(m.weight, gain=1)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def initialize_layer(self, layer):
        if isinstance(layer, (nn.Conv2d, nn.Linear)):
            torch.nn.init.normal_(layer.weight, mean=0., std=0.001)
            if layer.bias is not None:
                torch.nn.init.constant_(layer.bias, 0)


def DcovN(c1, c2, depth, kernel_size=3, patch_size=3):
    dcovn = nn.Sequential(
        nn.Conv2d(c1, c2, kernel_size=patch_size, stride=patch_size),
        nn.SiLU(),
        nn.BatchNorm2d(c2),
        *[nn.Sequential(
            Residual(nn.Sequential(
                nn.Conv2d(in_channels=c2, out_channels=c2, kernel_size=kernel_size, stride=1, padding=1, groups=c2),
                nn.SiLU(),
                nn.BatchNorm2d(c2)
            )),
            nn.Conv2d(in_channels=c2, out_channels=c2, kernel_size=1, stride=1, padding=0, groups=1),
            nn.SiLU(),
            nn.BatchNorm2d(c2)
        ) for i in range(depth)]
    )
    return dcovn

class MultiSEAM(nn.Module):
    def __init__(self, c1, depth=1, kernel_size=3, patch_size=[3, 5, 7], reduction=16):
        super(MultiSEAM, self).__init__()
        c2 = c1
        self.DCovN0 = DcovN(c1, c2, depth, kernel_size=kernel_size, patch_size=3)
        self.DCovN1 = DcovN(c1, c2, depth, kernel_size=kernel_size, patch_size=3)
        self.DCovN2 = DcovN(c1, c2, depth, kernel_size=kernel_size, patch_size=3)
        self.avg_pool = torch.nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Sequential(
            nn.Linear(c2, c2 // reduction, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(c2 // reduction, c2, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        y0 = self.DCovN0(x)
        y1 = self.DCovN1(x)
        y2 = self.DCovN2(x)
        y0 = self.avg_pool(y0).view(b, c)
        y1 = self.avg_pool(y1).view(b, c)
        y2 = self.avg_pool(y2).view(b, c)
        y4 = self.avg_pool(x).view(b, c)
        y = (y0 + y1 + y2 + y4) / 4
        y = self.fc(y).view(b, c, 1, 1)
        y = torch.exp(y)
        return x * y.expand_as(x)


四、添加教程

 4.1 修改一

第一还是建立文件,我们找到如下yolov9-main/models文件夹下建立一个目录名字呢就是'modules'文件夹(用群内的文件的话已经有了无需新建)!然后在其内部建立一个新的py文件将核心代码复制粘贴进去即可。


4.2 修改二 

第二步我们在该目录下创建一个新的py文件名字为'__init__.py'(用群内的文件的话已经有了无需新建),然后在其内部导入我们的检测头如下图所示。


4.3 修改三 

第三步我门中到如下文件'yolov9-main/models/yolo.py'进行导入和注册我们的模块(用群内的文件的话已经有了无需重新导入直接开始第四步即可)

从今天开始以后的教程就都统一成这个样子了,因为我默认大家用了我群内的文件来进行修改!!

​​


4.4 修改四 

按照我的添加在parse_model里添加即可。

到此就修改完成了,大家可以复制下面的yaml文件运行。


五、SEAM的yaml文件和运行记录

5.1 SEAM的yaml文件

# YOLOv9

# parameters
nc: 80  # number of classes
depth_multiple: 1  # model depth multiple
width_multiple: 1  # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()

# anchors
anchors: 3

# YOLOv9 backbone
backbone:
  [
   [-1, 1, Silence, []],
   # conv down
   [-1, 1, Conv, [64, 3, 2]],  # 1-P1/2
   # conv down
   [-1, 1, Conv, [128, 3, 2]],  # 2-P2/4
   # elan-1 block
   [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 3
   # conv down
   [-1, 1, Conv, [256, 3, 2]],  # 4-P3/8
   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 5
   # conv down
   [-1, 1, Conv, [512, 3, 2]],  # 6-P4/16
   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 7
   # conv down
   [-1, 1, Conv, [512, 3, 2]],  # 8-P5/32
   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 9
  ]

# YOLOv9 head
head:
  [
   # elan-spp block
   [-1, 1, SPPELAN, [512, 256]],  # 10

   # up-concat merge
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 7], 1, Concat, [1]],  # cat backbone P4

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 13

   # up-concat merge
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 5], 1, Concat, [1]],  # cat backbone P3

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [256, 256, 128, 1]],  # 16 (P3/8-small)
   [-1, 1, SEAM, []],  # 17 添加一行我们的改进机制

   # conv-down merge
   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 13], 1, Concat, [1]],  # cat head P4

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 20 (P4/16-medium)
   [-1, 1, SEAM, []],  # 21 添加一行我们的改进机制

   # conv-down merge
   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 24 (P5/32-large)
   [-1, 1, SEAM, []],  # 25 添加一行我们的改进机制

   # routing
   [5, 1, CBLinear, [[256]]], # 26
   [7, 1, CBLinear, [[256, 512]]], # 27
   [9, 1, CBLinear, [[256, 512, 512]]], # 28

   # conv down
   [0, 1, Conv, [64, 3, 2]],  # 29-P1/2

   # conv down
   [-1, 1, Conv, [128, 3, 2]],  # 30-P2/4

   # elan-1 block
   [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 31

   # conv down fuse
   [-1, 1, Conv, [256, 3, 2]],  # 32-P3/8
   [[26, 27, 28, -1], 1, CBFuse, [[0, 0, 0]]], # 33

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 34
   [-1, 1, SEAM, []],  # 35 添加一行我们的改进机制

   # conv down fuse
   [-1, 1, Conv, [512, 3, 2]],  # 36-P4/16
   [[27, 28, -1], 1, CBFuse, [[1, 1]]], # 37

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 38
   [-1, 1, SEAM, []],  # 39 添加一行我们的改进机制

   # conv down fuse
   [-1, 1, Conv, [512, 3, 2]],  # 40-P5/32
   [[28, -1], 1, CBFuse, [[2]]], # 41

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 42
   [-1, 1, SEAM, []],  # 43 添加一行我们的改进机制

   # detect
   [[35, 39, 43, 17, 21, 25], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)
  ]

5.2 MultiSEAM的yaml文件

# YOLOv9

# parameters
nc: 80  # number of classes
depth_multiple: 1  # model depth multiple
width_multiple: 1  # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()

# anchors
anchors: 3

# YOLOv9 backbone
backbone:
  [
   [-1, 1, Silence, []],
   # conv down
   [-1, 1, Conv, [64, 3, 2]],  # 1-P1/2
   # conv down
   [-1, 1, Conv, [128, 3, 2]],  # 2-P2/4
   # elan-1 block
   [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 3
   # conv down
   [-1, 1, Conv, [256, 3, 2]],  # 4-P3/8
   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 5
   # conv down
   [-1, 1, Conv, [512, 3, 2]],  # 6-P4/16
   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 7
   # conv down
   [-1, 1, Conv, [512, 3, 2]],  # 8-P5/32
   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 9
  ]

# YOLOv9 head
head:
  [
   # elan-spp block
   [-1, 1, SPPELAN, [512, 256]],  # 10

   # up-concat merge
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 7], 1, Concat, [1]],  # cat backbone P4

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 13

   # up-concat merge
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 5], 1, Concat, [1]],  # cat backbone P3

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [256, 256, 128, 1]],  # 16 (P3/8-small)
   [-1, 1, MultiSEAM, []],  # 17 添加一行我们的改进机制

   # conv-down merge
   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 13], 1, Concat, [1]],  # cat head P4

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 20 (P4/16-medium)
   [-1, 1, MultiSEAM, []],  # 21 添加一行我们的改进机制

   # conv-down merge
   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 24 (P5/32-large)
   [-1, 1, MultiSEAM, []],  # 25 添加一行我们的改进机制

   # routing
   [5, 1, CBLinear, [[256]]], # 26
   [7, 1, CBLinear, [[256, 512]]], # 27
   [9, 1, CBLinear, [[256, 512, 512]]], # 28

   # conv down
   [0, 1, Conv, [64, 3, 2]],  # 29-P1/2

   # conv down
   [-1, 1, Conv, [128, 3, 2]],  # 30-P2/4

   # elan-1 block
   [-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 31

   # conv down fuse
   [-1, 1, Conv, [256, 3, 2]],  # 32-P3/8
   [[26, 27, 28, -1], 1, CBFuse, [[0, 0, 0]]], # 33

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 34
   [-1, 1, MultiSEAM, []],  # 35 添加一行我们的改进机制

   # conv down fuse
   [-1, 1, Conv, [512, 3, 2]],  # 36-P4/16
   [[27, 28, -1], 1, CBFuse, [[1, 1]]], # 37

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 38
   [-1, 1, MultiSEAM, []],  # 39 添加一行我们的改进机制

   # conv down fuse
   [-1, 1, Conv, [512, 3, 2]],  # 40-P5/32
   [[28, -1], 1, CBFuse, [[2]]], # 41

   # elan-2 block
   [-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 42
   [-1, 1, MultiSEAM, []],  # 43 添加一行我们的改进机制

   # detect
   [[35, 39, 43, 17, 21, 25], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)
  ]


5.3 训练过程截图 


五、本文总结

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

 专栏地址:YOLOv9有效涨点专栏-持续复现各种顶会内容-有效涨点-全网改进最全的专栏 

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

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

相关文章

链表第4/9题--翻转链表--双指针法

LeetCode206:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]示例…

鸿蒙OpenHarmony开发板解析:【特性配置规则】

特性 特性配置规则 下面介绍feature的声明、定义以及使用方法。 feature的声明 开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 在部件的bundle.json文件中通过feature_list来声明部件的feature列…

生信技能45 - 基于docker容器运行生信软件

1. 获取docker镜像 以运行xhmm CNV分析软件为例。 # 搜索仓库镜像 sudo docker search xhmm# 拉取镜像 sudo docker pull ksarathbabu/xhmm_v1.0# 启动镜像,非后台 sudo docker run -it ksarathbabu/xhmm_v1.0 /bin/bash # -i: 交互式操作。 # -t: 终端。 # ksarathbabu/xhmm…

爆爽,英语小白怒刷 50 课!像玩游戏一样学习英语~

重点!!!(先看这) 清楚自己学英语的目的, 先搞清楚目标,再行动自身现在最需要的东西:词汇量?口语?还是阅读能力?找对应的书籍,学习资料往兴趣靠拢:网上有大量的推荐美剧学习、小说学习,不要被他…

机器学习算法应用——K近邻分类器(KNN)

K近邻分类器(KNN)(4-2) K近邻分类器(K-Nearest Neighbor,简称KNN)是一种基本的机器学习分类算法。它的工作原理是:在特征空间中,如果一个样本在特征空间中的K个最相邻的样…

【一刷《剑指Offer》】面试题 17:合并两个排序的链表

力扣对应题目链接:21. 合并两个有序链表 - 力扣(LeetCode) 核心考点:链表合并。 一、《剑指Offer》内容 二、分析题目 这道题的解题思路有很多: 可以一个一个节点的归并。可以采用递归完成。 三、代码 1、易于理解的…

Linux-基础命令第三天

1、命令:wc 作用:统计行数、单词数、字符数 格式:wc 选项 文件名 例: 统计文件中的行数、单词数、字符数 说明:59代表行数,111代表单词数,2713代表字符数,a.txt代表文件名 选项…

c语言查找字符串中指定字符串的个数

目录 一、测试思路二、方式1三、方式2 一、测试思路 使用C语言来查找一个字符串中指定数量的子字符串&#xff0c;使用 strncmp 函数或者 memcmp 函数&#xff0c;遍历主字符串并计数子字符串出现的次数。或者使用 strstr 函数&#xff0c; strstr 函数是 C 语言标准库 <str…

Java 集合-List

集合主要分为两组(单列集合, 双列集合) Connection 接口有两个重要的子接口LIst 和 Set, 它们的实现子类都是单列集合, Map 接口的实现子类是双列集合, 存放的是 K-V Connection 接口 Collection 接口和常用方法 下面以 ArrayList 演示一下 add: 添加单个元素remove: 删除指…

基于GIS地理技术+智慧巡检解决方案(Word原件)

传统的巡检采取人工记录的方式&#xff0c;该工作模式在生产中存在很大弊端&#xff0c;可能造成巡检不到位、操作失误、观察不仔细、历史问题难以追溯等现象&#xff0c;使得巡检数据不准确&#xff0c;设备故障隐患得不到及时发现和处理。因此建立一套完善的巡检管理系统是企…

【C语言】——联合体与枚举

【C语言】——联合体与枚举 一、联合体1.1、联合体类型的声明1.2、联合体的特点1.3、相同成员的结构体和联合体对比1.4、联合体的大小计算1.5、联合体的应用举例 二、枚举2.1、枚举类型的声明2.2、枚举类型的优点 一、联合体 1.1、联合体类型的声明 联合体也叫做共用体   与…

TLF35584 Windows Watchdog

1、相关寄存器 1&#xff09;WWDCFG0 - Protected Window watchdog configuration request 0 *R2 offset Address&#xff1a;09H&#xff1b;Reset Value&#xff1a;06H&#xff1b; 窗口看门狗关窗口的周期默认值&#xff1a;350wd cycles 350ms。 2&#xff09;WWDCFG1…

国产银河麒麟V10SP1系统下搭建TiDB数据库操作步骤图文

开发目的&#xff1a;在国产银河麒麟系统中搭建TiDB数据库运行环境。 开发工具&#xff1a;银河麒麟系统V10SP1TiDBMySql数据库8.0。 具体步骤&#xff1a; 1、在VmWare虚拟机中安装好国产银河麒麟V10Sp1操作系统。 2、打开终端命令&#xff0c;安装TiDB相关软件&#xff1…

调试记录 CPU PCIE 找不到设备,AC 耦合电容的问题

1. 问题 现象&#xff1a; 1. 国产CPU的主板&#xff0c;主板内的PCIE 设备找的到&#xff0c;但是另一块板子上连接的PCIE 设备找不到。 2. 排查问题在哪里的计划 1. 检查原理图先排除信号定义的问题&#xff0c; TXRX是否反接。 2. 示波器检查PCIE 的时钟频率是否正确。 3. …

ESLint: Unexpected ‘debugger‘ statement.(no-debugger)(debugger报红)

ESLint: Unexpected debugger statement.(no-debugger) 解决办法&#xff1a; 找到.eslintrc.js文件中rules的no-debugger更改为0即可

队列的实现(使用链表)

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 目录 1、队列的概念2、队列的链表实现方法2.1 前言2.2 正文2.2.1 队列的初始化2.2.2 队列的销毁…

苹果公司因iPad广告争议而道歉,承认“未达标”|TodayAI

周二&#xff0c;苹果公司发布了一则新的iPad Pro广告&#xff0c;引起了广泛争议&#xff0c;该公司随后发表道歉声明&#xff0c;承认这则广告“未达标”。这则名为“压碎&#xff01;”的广告意图展示全新的M4芯片iPad Pro的创意潜力&#xff0c;但却因其表现方式而备受批评…

服务器直连电脑(盒子直连电脑)电脑需要设置为固定ip才能访问盒子

文章目录 现象盒子设置为固定ip&#xff0c;pc设置成固定ip&#xff08;以太网网卡&#xff0c;realtak那个&#xff0c;不是tap-windows那个&#xff0c;tap-windows不用管&#xff09;&#xff0c;在pc上用ip搜索工具搜索&#xff0c;可以搜到盒子ip。盒子设置为固定ip&#…

phpstudy靶场访问显示404 Not Found

涉及靶场 upload-labd sqli-labs pikachu dvwa 以及所有部署在phpstudy中的靶场 一、检查phpstduy设置 localhost——管理——修改 1、根目录&#xff08;默认设置&#xff0c;不要改&#xff09; localhost这个域名必须保留&#xff0c;并且把根目录设置为phpstudy的WWW文…

性能测试工具——wrk的安装与使用

前言 想和大家来聊聊性能测试&#xff0c;聊到了性能测试必须要说的是性能测试中的工具&#xff0c;在这些工具中我今天主要给大家介绍wrk。 ​介绍 wrk是一款开源的性能测试工具 &#xff0c;简单易用&#xff0c;没有Load Runner那么复杂&#xff0c;他和 apache benchmar…