YOLOv9改进策略 | 添加注意力篇 | 一文带你改进GAM、CBAM、CA、ECA等通道注意力机制和多头注意力机制

 一、本文介绍

这篇文章给大家带来的改进机制是一个汇总篇,包含一些简单的注意力机制,本来一直不想发这些内容的(网上教程太多了,发出来增加文章数量也没什么意义),但是群内的读者很多都问我这些机制所以单独出一期视频来汇总一些比较简单的注意力机制添加的方法和使用教程,本文的内容不会过度的去解释原理,更多的是从从代码的使用上和实用的角度出发去写这篇教程。

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

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


目录

 一、本文介绍

二、GAM

2.1 GAM的介绍

2.2 GAM的核心代码

三、CBAM

3.1 CBAM的介绍

​编辑​​

3.2 CBAM核心代码

四、CA

4.1 CA的介绍

4.2 CA核心代码

五、ECA

5.1 ECA的介绍

 5.2 ECA核心代码

六、注意力机制的添加方法

6.1 修改一

6.2 修改二 

6.3 修改三 

6.4 修改四 

七、yaml文件

7.1 添加位置1 

7.1 添加位置2

八、本文总结


二、GAM

2.1 GAM的介绍

​​官方论文地址: 官方论文地址点击此处即可跳转

官方代码地址: 官方代码地址点击此处即可跳转

​​


简单介绍:GAM旨在通过设计一种机制,减少信息损失并放大全局维度互动特征,从而解决传统注意力机制在通道和空间两个维度上保留信息不足的问题。GAM采用了顺序的通道-空间注意力机制,并对子模块进行了重新设计。具体来说,通道注意力子模块使用3D排列来跨三个维度保留信息,并通过一个两层的MLP增强跨维度的通道-空间依赖性。在空间注意力子模块中,为了更好地关注空间信息,采用了两个卷积层进行空间信息融合,同时去除了可能导致信息减少的最大池化操作,通过使用分组卷积和通道混洗在ResNet50中避免参数数量显著增加。GAM在不同的神经网络架构上稳定提升性能,特别是对于ResNet18,GAM以更少的参数和更好的效率超过了ABN,其简单原理结构图如下所示。

​​


2.2 GAM的核心代码

import torch
import torch.nn as nn'''
https://arxiv.org/abs/2112.05561
'''class GAM(nn.Module):def __init__(self, in_channels, rate=4):super().__init__()out_channels = in_channelsin_channels = int(in_channels)out_channels = int(out_channels)inchannel_rate = int(in_channels/rate)self.linear1 = nn.Linear(in_channels, inchannel_rate)self.relu = nn.ReLU(inplace=True)self.linear2 = nn.Linear(inchannel_rate, in_channels)self.conv1=nn.Conv2d(in_channels, inchannel_rate,kernel_size=7,padding=3,padding_mode='replicate')self.conv2=nn.Conv2d(inchannel_rate, out_channels,kernel_size=7,padding=3,padding_mode='replicate')self.norm1 = nn.BatchNorm2d(inchannel_rate)self.norm2 = nn.BatchNorm2d(out_channels)self.sigmoid = nn.Sigmoid()def forward(self,x):b, c, h, w = x.shape# B,C,H,W ==> B,H*W,Cx_permute = x.permute(0, 2, 3, 1).view(b, -1, c)# B,H*W,C ==> B,H,W,Cx_att_permute = self.linear2(self.relu(self.linear1(x_permute))).view(b, h, w, c)# B,H,W,C ==> B,C,H,Wx_channel_att = x_att_permute.permute(0, 3, 1, 2)x = x * x_channel_attx_spatial_att = self.relu(self.norm1(self.conv1(x)))x_spatial_att = self.sigmoid(self.norm2(self.conv2(x_spatial_att)))out = x * x_spatial_attreturn outif __name__ == '__main__':img = torch.rand(1,64,32,48)b, c, h, w = img.shapenet = GAM(in_channels=c, out_channels=c)output = net(img)print(output.shape)


三、CBAM

3.1 CBAM的介绍

​​

官方论文地址:官方论文地址点击此处即可跳转

官方代码地址:官方代码地址点击此处即可跳转

​​

简单介绍:CBAM的主要思想是通过关注重要的特征并抑制不必要的特征来增强网络的表示能力。模块首先应用通道注意力,关注"重要的"特征,然后应用空间注意力,关注这些特征的"重要位置"。通过这种方式,CBAM有效地帮助网络聚焦于图像中的关键信息,提高了特征的表示力度,下图为其简单原理结构图。 

​​


3.2 CBAM核心代码

import torch
import torch.nn as nnclass ChannelAttention(nn.Module):"""Channel-attention module https://github.com/open-mmlab/mmdetection/tree/v3.0.0rc1/configs/rtmdet."""def __init__(self, channels: int) -> None:"""Initializes the class and sets the basic configurations and instance variables required."""super().__init__()self.pool = nn.AdaptiveAvgPool2d(1)self.fc = nn.Conv2d(channels, channels, 1, 1, 0, bias=True)self.act = nn.Sigmoid()def forward(self, x: torch.Tensor) -> torch.Tensor:"""Applies forward pass using activation on convolutions of the input, optionally using batch normalization."""return x * self.act(self.fc(self.pool(x)))class SpatialAttention(nn.Module):"""Spatial-attention module."""def __init__(self, kernel_size=7):"""Initialize Spatial-attention module with kernel size argument."""super().__init__()assert kernel_size in (3, 7), "kernel size must be 3 or 7"padding = 3 if kernel_size == 7 else 1self.cv1 = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)self.act = nn.Sigmoid()def forward(self, x):"""Apply channel and spatial attention on input for feature recalibration."""return x * self.act(self.cv1(torch.cat([torch.mean(x, 1, keepdim=True), torch.max(x, 1, keepdim=True)[0]], 1)))class CBAM(nn.Module):"""Convolutional Block Attention Module."""def __init__(self, c1, kernel_size=7):"""Initialize CBAM with given input channel (c1) and kernel size."""super().__init__()self.channel_attention = ChannelAttention(c1)self.spatial_attention = SpatialAttention(kernel_size)def forward(self, x):"""Applies the forward pass through C1 module."""return self.spatial_attention(self.channel_attention(x))


四、CA

4.1 CA的介绍

​​

官方论文地址:官方论文地址点击此处即可跳转

官方代码地址: 官方代码地址点击此处即可跳转

​​


简单介绍: 坐标注意力是一种结合了通道注意力和位置信息的注意力机制,旨在提升移动网络的性能。它通过将特征张量沿两个空间方向进行1D全局池化,分别捕获沿垂直和水平方向的特征,保留了精确的位置信息并捕获了长距离依赖性。这两个方向的特征图被单独编码成方向感知和位置敏感的注意力图,然后这些注意力图通过乘法作用于输入特征图,以突出感兴趣的对象表示。坐标注意力的引入,使得模型能够更准确地定位和识别感兴趣的对象,同时由于其轻量级和灵活性,它可以轻松集成到现有的移动网络架构中,几乎不会增加计算开销。

​​


4.2 CA核心代码

import torch
import torch.nn as nn
import math
import torch.nn.functional as Fclass h_sigmoid(nn.Module):def __init__(self, inplace=True):super(h_sigmoid, self).__init__()self.relu = nn.ReLU6(inplace=inplace)def forward(self, x):return self.relu(x + 3) / 6class h_swish(nn.Module):def __init__(self, inplace=True):super(h_swish, self).__init__()self.sigmoid = h_sigmoid(inplace=inplace)def forward(self, x):return x * self.sigmoid(x)class CoordAtt(nn.Module):def __init__(self, inp, reduction=32):super(CoordAtt, self).__init__()oup = inpself.pool_h = nn.AdaptiveAvgPool2d((None, 1))self.pool_w = nn.AdaptiveAvgPool2d((1, None))mip = max(8, inp // reduction)self.conv1 = nn.Conv2d(inp, mip, kernel_size=1, stride=1, padding=0)self.bn1 = nn.BatchNorm2d(mip)self.act = h_swish()self.conv_h = nn.Conv2d(mip, oup, kernel_size=1, stride=1, padding=0)self.conv_w = nn.Conv2d(mip, oup, kernel_size=1, stride=1, padding=0)def forward(self, x):identity = xn,c,h,w = x.size()x_h = self.pool_h(x)x_w = self.pool_w(x).permute(0, 1, 3, 2)y = torch.cat([x_h, x_w], dim=2)y = self.conv1(y)y = self.bn1(y)y = self.act(y) x_h, x_w = torch.split(y, [h, w], dim=2)x_w = x_w.permute(0, 1, 3, 2)a_h = self.conv_h(x_h).sigmoid()a_w = self.conv_w(x_w).sigmoid()out = identity * a_w * a_hreturn out

五、ECA

5.1 ECA的介绍

​​

官方论文地址:官方论文地址点击此处即可跳转

官方代码地址:官方代码地址点击此处即可跳转

​​

简单介绍:ECA(Efficient Channel Attention)注意力机制的原理可以总结为:避免通道注意力模块中的降维操作,通过采用局部跨通道交互策略,利用1D卷积实现高效的通道注意力计算。这种方法保持了性能的同时显著减少了模型的复杂性,通过自适应选择卷积核大小,确定了局部跨通道交互的覆盖范围。 ECA模块通过少量参数和低计算成本,实现了在ResNets和MobileNetV2等主干网络上的显著性能提升,且相对于其他注意力模块具有更高的效率和更好的性能。 


 5.2 ECA核心代码

import torch
from torch import nn
from torch.nn.parameter import Parameterclass ECA(nn.Module):"""Constructs a ECA module.Args:channel: Number of channels of the input feature mapk_size: Adaptive selection of kernel size"""def __init__(self, channel, k_size=3):super(ECA, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.conv = nn.Conv1d(1, 1, kernel_size=k_size, padding=(k_size - 1) // 2, bias=False) self.sigmoid = nn.Sigmoid()def forward(self, x):# feature descriptor on the global spatial informationy = self.avg_pool(x)# Two different branches of ECA moduley = self.conv(y.squeeze(-1).transpose(-1, -2)).transpose(-1, -2).unsqueeze(-1)# Multi-scale information fusiony = self.sigmoid(y)return x * y.expand_as(x)


六、注意力机制的添加方法

6.1 修改一

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


6.2 修改二 

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


6.3 修改三 

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

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

​​


6.4 修改四 

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

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


七、yaml文件

7.1 添加位置1 

下面的文件是配置好的yaml文件,其中包含了四个注意力机制,其中默认先用的CBAM大家使用那个只需要把其他的注释掉即可

# 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:[[-1, 1, CBAM, []],  # 添加一行我们的改进机制可以替换其它注意力机制在这个位置,这里以CBAM为例# elan-spp block[-1, 1, SPPELAN, [512, 256]],  # 11# 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]],  # 14# 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]],  # 17 (P3/8-small)# conv-down merge[-1, 1, Conv, [256, 3, 2]],[[-1, 14], 1, Concat, [1]],  # cat head P4# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 20 (P4/16-medium)# conv-down merge[-1, 1, Conv, [512, 3, 2]],[[-1, 11], 1, Concat, [1]],  # cat head P5# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 23 (P5/32-large)# routing[5, 1, CBLinear, [[256]]], # 24[7, 1, CBLinear, [[256, 512]]], # 25[9, 1, CBLinear, [[256, 512, 512]]], # 26# conv down[0, 1, Conv, [64, 3, 2]],  # 27-P1/2# conv down[-1, 1, Conv, [128, 3, 2]],  # 28-P2/4# elan-1 block[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]],  # 29# conv down fuse[-1, 1, Conv, [256, 3, 2]],  # 30-P3/8[[24, 25, 26, -1], 1, CBFuse, [[0, 0, 0]]], # 31# elan-2 block[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]],  # 32# conv down fuse[-1, 1, Conv, [512, 3, 2]],  # 33-P4/16[[25, 26, -1], 1, CBFuse, [[1, 1]]], # 34# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 35# conv down fuse[-1, 1, Conv, [512, 3, 2]],  # 36-P5/32[[26, -1], 1, CBFuse, [[2]]], # 37# elan-2 block[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]],  # 38# detect[[32, 35, 38, 17, 20, 23], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)]


7.1 添加位置2

# 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, CBAM, []],  # 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, CBAM, []],  # 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, CBAM, []],  # 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, CBAM, []],  # 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, CBAM, []],  # 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, CBAM, []],  # 43 添加一行我们的改进机制# detect[[35, 39, 43, 17, 21, 25], 1, DualDDetect, [nc]],  # DualDDetect(A3, A4, A5, P3, P4, P5)]

使用方法同上!


想要学习添加更多添加位置更多机制欢迎大家订阅专栏~ 


八、本文总结

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

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

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

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

相关文章

PDPS15---安装过程---常遇问题---分享

目录 问题1 安装失败 1.1 运行第一步出错 1.2 解决 问题2 路径错误 2.1 错误 2.2 解决 问题3 运行失败 3.1 无法找到路径 3.2 原因分析 3.3 解决 问题4 拒绝访问 4.1 出现提示 4.2 分析 4.3 解决 问题5 许可证过期 5.1 PD找不到许可证 5.2 解决 问题1 安装失败…

Joplin:自由、安全、多功能的笔记应用

什么是 Joplin? Joplin是一款免费、开源的笔记和待办事项应用程序,可以处理整理到笔记本中的大量笔记。这些笔记是可搜索的,可以直接从应用程序或从您自己的文本编辑器中复制、标记和修改。笔记采用Markdown 格式 功能亮点 功能丰富&#x…

从“制造”到“智造”:“灯塔”经验助力中国制造业转型升级-转载

作者:Karel Eloot,侯文皓,Francisco Betti,Enno de Boer和Yves Giraud 作为中国实体经济的主体,制造业是推动中国经济发展乃至全球制造业持续增长的重要引擎。站在历史与未来交汇的新起点上,中国制造业将背…

3D模型如何实现拖拽打开?---模大狮模型网

在当今数字化时代,3D技术的应用已经深入到各行各业,为用户带来了更加丰富、生动的体验。然而,对于一些用户来说,打开和查看3D模型可能会面临一些困难,特别是在无法拖拽打开时。本文将为您揭示解决这一问题的方法&#…

【C】语⾔内存函数--超详解

1. memcpy 使⽤和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 这个函数在遇到 \0 的时候并不会停下来。 如果source和destination有任何的重叠&am…

数据结构与算法之树和二叉树的一些概念和性质

目录 前言 一、树的定义 二、树的若干术语 1.结点的度 2.叶子 3.双亲与孩子 4.兄弟 5.祖先 6.树的度 7.结点的层次 8.树的深度 9.有序树和无序树 10.森林 三、树的逻辑结构 四、树的存储结构 1.顺序存储 2.链式存储 五、二叉树 1.定义 2.二叉树的五种状态 …

SPA模式下的多页面跳转原理及实现

jQuery Mobile在SPA模式下的多页面跳转原理及实现案例 文章目录 jQuery Mobile在SPA模式下的多页面跳转原理及实现案例前言一、SPA的实现原理和代码分析1.实现原理说明(1)index.html(2)index.js(3)page2.ht…

前端css中线性渐变(linear-gradient)的使用

前端css中线性渐变 一、前言二、关键词句三、主要内容说明(一)、线性渐变方向1.角度调整方向2.负值角度,源码13.源码1运行效果4.关键字调整方向5.to right向右线性渐变,源码26.源码2运行效果 (二)、线性渐变…

初识C语言——第十六天

C语言中的语句结构类型:顺序/选择/循环 分支语句 if else switch 循环语句 while for do whlie goto语句 代码练习:找两个整数的最大公约数和最小公倍数 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h>//int main() //{ // int age 60; // if (ag…

YOLOv5-7.0改进(三)添加损失函数EIoU、AlphaIoU、SIoU、WIoU、MPDIoU、NWD

前言 损失函数的改进一直是涨点的重要技巧&#xff0c;本篇博客将使用六个不同损失函数对算法进行改进&#xff0c;并绘制出改进结果对比图~ 往期回顾 YOLOv5-7.0改进&#xff08;一&#xff09;MobileNetv3替换主干网络 YOLOv5-7.0改进&#xff08;二&#xff09;BiFPN替换…

基士得耶CP 6303c速印机不制版故障检修

故障&#xff1a;基士得耶CP 6303c经常提示版纸卡纸&#xff0c;重设版纸 版纸还没下滚筒&#xff0c;卡在版纸仓里面,手动滚动裁纸刀可以解决&#xff0c;但第二天又是这个毛病&#xff1b; 版纸定位传感器的灵敏度调节一下,然后给机器全面做个清洁大保养&#xff0c;尤其是传…

网工内推 | 技术支持工程师,最高15k,加班有补贴

01 星网信通 招聘岗位&#xff1a;售前技术支持 职责描述&#xff1a; 1、售前技术支持&#xff1a;技术交流、产品选型报价、方案制作等工作&#xff1b; 2、招投标支持&#xff1a;项目招标参数撰写、标书质疑、应标文件技术部分撰写及资质文件归纳准备、现场讲标及技术澄清…

vue路由知识补充(updating···)

1路由守卫中的next() next()方法表示放行&#xff0c;如果不执行此方法路由不会跳转&#xff0c;此方法可以接收一个参数 字符串路径&#xff1a;如果传递一个字符串路径&#xff0c;那么路由会重定向到该路径。 next(/home); 路由对象&#xff1a;如果传递一个路由对象&…

leetcode尊享面试——二叉树(python)

250.统计同值子树 使用dfs深度搜索&#xff0c;同值子树&#xff0c;要满足三个条件&#xff1a; 对于当前节点node&#xff0c;他的左子树血脉纯净&#xff08;为同值子树&#xff09;&#xff0c;右子树血脉纯净&#xff08;为同值子树&#xff09;&#xff0c;node的值等于…

Windows系统下修改文件夹和U盘图标实战

文章目录 知识学习一、修改磁盘图标第一步、新建.INF文件第二步、放置图标第三步、重新插入U盘第四步、隐藏与显示文件知识拓展 二、修改文件夹图标设置图标样式恢复图标样式 在日常办公中使用的是windows系统&#xff0c;系统默认的文件图标都一样&#xff0c;不利于分类整理&…

电商核心技术揭秘52:数字化内容营销创新

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘相关系列文章合集&#xff08;3&#xff09; 电商技术揭秘四十一&#xff1a;电商平台的营销系统浅析 电商技术揭秘四十二&#…

【C++】继承 — 继承的引入、赋值切片详细讲解

前言 我们知道C语言是一门面向对象编程的语言&#xff0c;而面向对象编程有三大特性&#xff0c;它们分别是&#xff1a; 封装继承多态 目录 1. 继承的概念及定义1.1继承的概念1.2继承的定义格式1.3 继承的使用 2 基类和派生类对象赋值转换3 继承中的作用域3.1 派生类对象的存…

Linux下安装snaphu

1、官网下载安装包 2、解压&#xff0c;移动文件夹到/usr/local/下 3、在/usr/local/下创建man&#xff0c;在man下创建man1文件夹 4、进入到snaphu的src文件夹里&#xff0c;执行sudo make&#xff0c;如果报错 在这个 Makefile 中&#xff0c;-arch x86_64 是 macOS 特定的…

【Linux】-Linux用户和权限[3]

一、认知root用户 1、root用户&#xff08;超级管理员&#xff09; 无论是Windows、MacOS、Linux均采用多用户的管理模式进行权限管理。 在Linux系统中&#xff0c;拥有最大权限的账户为&#xff1a;root&#xff08;超级管理员&#xff09; root用户拥有最大的系统操作权限…

Android MediaCodec 简明教程(七):使用 MediaCodec 解码到 OES 纹理上

系列文章目录 Android MediaCodec 简明教程&#xff08;一&#xff09;&#xff1a;使用 MediaCodecList 查询 Codec 信息&#xff0c;并创建 MediaCodec 编解码器Android MediaCodec 简明教程&#xff08;二&#xff09;&#xff1a;使用 MediaCodecInfo.CodecCapabilities 查…