背景意义
随着全球海洋经济的快速发展,海洋安全和海上防御的需求日益增加,舰船检测与分类技术在军事和民用领域的重要性愈发凸显。传统的舰船识别方法多依赖于人工监测和经验判断,效率低下且容易受到人为因素的影响。因此,基于计算机视觉和深度学习的自动化舰船检测与分类系统应运而生,成为提升海洋监控能力的重要手段。
在众多深度学习模型中,YOLO(You Only Look Once)系列因其实时性和高效性受到广泛关注。YOLOv11作为该系列的最新版本,具备更强的特征提取能力和更快的处理速度,适合用于复杂海洋环境下的舰船检测。然而,针对舰船的特定需求,YOLOv11的性能仍有提升空间,尤其是在图像分割和细粒度分类方面。因此,改进YOLOv11以适应舰船战舰的检测与分类任务,具有重要的理论价值和实际意义。
本研究将基于HRSC2016数据集,该数据集包含616幅高分辨率舰船图像,涵盖了多种舰船类型,如航空母舰、驱逐舰、潜艇等。通过对这些图像进行实例分割,能够实现对舰船的精确定位和分类,从而为海洋监控、军事侦察及海上安全提供有力支持。此外,改进后的YOLOv11模型将有助于提升在复杂背景下的检测精度,推动舰船检测技术的进一步发展。
综上所述,基于改进YOLOv11的舰船战舰检测与分类图像分割系统的研究,不仅能提高舰船识别的自动化水平,还能为海洋安全和军事防御提供更为可靠的技术保障,具有广泛的应用前景和深远的社会意义。
图片效果
数据集信息
本项目所使用的数据集为"HRSC2016",该数据集专门用于舰船战舰的检测与分类,旨在提升YOLOv11模型在图像分割任务中的性能。HRSC2016数据集包含22个不同类别的舰船类型,涵盖了从航空母舰到游艇等多种舰船,具体类别包括:航空母舰、辅助船、驳船、战列舰、散货船、货船、指挥舰、护卫舰、巡洋舰、驱逐舰、渡轮、渔船、护卫舰、医院船、登陆舰、摩托艇、油轮、巡逻舰、滚装船、潜艇、战舰以及游艇。这些类别的多样性使得数据集在舰船检测与分类的研究中具有重要的参考价值。
HRSC2016数据集的图像均为高分辨率,提供了丰富的舰船特征信息,能够有效支持模型的训练与验证。每个类别的舰船在数据集中均有充分的样本,确保了模型在不同类型舰船上的泛化能力。通过对这些图像进行标注,数据集不仅提供了舰船的位置信息,还包含了相应的类别标签,为模型的训练提供了坚实的基础。
在本项目中,HRSC2016数据集将作为核心训练数据,帮助改进YOLOv11的舰船检测与分类图像分割系统。通过对数据集的深入分析与处理,我们期望能够提高模型在复杂海洋环境中的检测精度和分类准确性,从而推动舰船监测技术的发展。整体而言,HRSC2016数据集的丰富性和多样性为本项目的成功实施奠定了重要基础。
核心代码
以下是经过简化和注释的核心代码部分,主要保留了模型的结构和功能:
import torch
import torch.nn as nn
import math
import itertools
class Attention4D(nn.Module):
"""实现4D注意力机制的类"""
def init (self, dim=384, key_dim=32, num_heads=8, attn_ratio=4, resolution=7, act_layer=nn.ReLU, stride=None):
super().init ()
self.num_heads = num_heads # 注意力头的数量
self.scale = key_dim ** -0.5 # 缩放因子
self.key_dim = key_dim # 键的维度
self.nh_kd = key_dim * num_heads # 每个头的键的维度总和
# 根据stride决定是否进行下采样
if stride is not None:
self.resolution = math.ceil(resolution / stride) # 计算下采样后的分辨率
self.stride_conv = nn.Sequential(
nn.Conv2d(dim, dim, kernel_size=3, stride=stride, padding=1, groups=dim),
nn.BatchNorm2d(dim),
)
self.upsample = nn.Upsample(scale_factor=stride, mode='bilinear') # 上采样
else:
self.resolution = resolution
self.stride_conv = None
self.upsample = None
self.N = self.resolution ** 2 # 总的空间位置数
self.d = int(attn_ratio * key_dim) # 注意力输出的维度
self.dh = self.d * num_heads # 每个头的输出维度总和
# 定义查询、键、值的卷积层
self.q = nn.Sequential(nn.Conv2d(dim, self.num_heads * self.key_dim, 1), nn.BatchNorm2d(self.num_heads * self.key_dim))
self.k = nn.Sequential(nn.Conv2d(dim, self.num_heads * self.key_dim, 1), nn.BatchNorm2d(self.num_heads * self.key_dim))
self.v = nn.Sequential(nn.Conv2d(dim, self.num_heads * self.d, 1), nn.BatchNorm2d(self.num_heads * self.d))
# 定义局部值的卷积层
self.v_local = nn.Sequential(
nn.Conv2d(self.num_heads * self.d, self.num_heads * self.d, kernel_size=3, stride=1, padding=1, groups=self.num_heads * self.d),
nn.BatchNorm2d(self.num_heads * self.d),
)
# 定义注意力机制中的投影层
self.proj = nn.Sequential(act_layer(), nn.Conv2d(self.dh, dim, 1), nn.BatchNorm2d(dim))
# 计算注意力偏置
points = list(itertools.product(range(self.resolution), range(self.resolution)))
attention_offsets = {}
idxs = []
for p1 in points:
for p2 in points:
offset = (abs(p1[0] - p2[0]), abs(p1[1] - p2[1]))
if offset not in attention_offsets:
attention_offsets[offset] = len(attention_offsets)
idxs.append(attention_offsets[offset])
self.attention_biases = nn.Parameter(torch.zeros(num_heads, len(attention_offsets)))
self.register_buffer('attention_bias_idxs', torch.LongTensor(idxs).view(self.N, self.N))
def forward(self, x):
"""前向传播"""
B, C, H, W = x.shape # 获取输入的维度
if self.stride_conv is not None:
x = self.stride_conv(x) # 下采样
# 计算查询、键、值
q = self.q(x).flatten(2).reshape(B, self.num_heads, -1, self.N).permute(0, 1, 3, 2)
k = self.k(x).flatten(2).reshape(B, self.num_heads, -1, self.N).permute(0, 1, 2, 3)
v = self.v(x)
v_local = self.v_local(v)
v = v.flatten(2).reshape(B, self.num_heads, -1, self.N).permute(0, 1, 3, 2)
# 计算注意力权重
attn = (q @ k) * self.scale + self.attention_biases[:, self.attention_bias_idxs]
attn = attn.softmax(dim=-1) # softmax归一化
# 计算输出
x = (attn @ v)
out = x.transpose(2, 3).reshape(B, self.dh, self.resolution, self.resolution) + v_local
if self.upsample is not None:
out = self.upsample(out)
out = self.proj(out) # 投影到原始维度
return out
class EfficientFormerV2(nn.Module):
"""EfficientFormer V2模型"""
def init (self, layers, embed_dims=None, num_classes=1000):
super().init ()
self.patch_embed = nn.Conv2d(3, embed_dims[0], kernel_size=3, stride=2, padding=1) # 初始嵌入层
# 构建网络结构
self.network = nn.ModuleList()
for i in range(len(layers)):
# 添加每个阶段的块
stage = nn.Sequential(*[Attention4D(dim=embed_dims[i]) for _ in range(layers[i])])
self.network.append(stage)
self.classifier = nn.Linear(embed_dims[-1], num_classes) # 分类器
def forward(self, x):
"""前向传播"""
x = self.patch_embed(x) # 嵌入
for block in self.network:
x = block(x) # 通过网络块
x = x.mean(dim=[2, 3]) # 全局平均池化
x = self.classifier(x) # 分类
return x
示例用法
if name == 'main ':
inputs = torch.randn((1, 3, 640, 640)) # 输入张量
model = EfficientFormerV2(layers=[2, 2, 6, 4], embed_dims=[32, 64, 128, 256]) # 创建模型
res = model(inputs) # 前向传播
print(res.size()) # 输出结果的尺寸
代码注释说明:
Attention4D类:实现了一个4D注意力机制,包含查询、键、值的计算,以及注意力权重的计算和应用。
EfficientFormerV2类:构建了EfficientFormer V2模型,包含多个注意力块和分类器。
前向传播:定义了模型的前向传播过程,包括输入嵌入、通过网络块处理、全局平均池化和最终分类。
示例用法:在主程序中创建了一个输入张量并通过模型进行前向传播,输出结果的尺寸。
这个程序文件定义了一个名为 EfficientFormerV2 的深度学习模型,主要用于图像处理任务。模型的设计灵感来源于 Transformer 架构,结合了卷积神经网络(CNN)的优点,旨在提高计算效率和准确性。
首先,文件中定义了一些超参数,包括不同模型版本的宽度和深度,这些参数用于控制模型的复杂性和计算需求。具体来说,EfficientFormer_width 和 EfficientFormer_depth 字典分别定义了不同版本(如 S0、S1、S2 和 L)的通道数和层数。
接下来,定义了多个类,主要包括 Attention4D、Attention4DDownsample、Embedding、Mlp、AttnFFN 和 FFN。这些类实现了模型的核心组件,如注意力机制、前馈网络和嵌入层。
Attention4D 类实现了一个四维注意力机制,能够处理输入的特征图,并计算出加权后的输出。它使用了多个卷积层来生成查询(Q)、键(K)和值(V),并通过计算注意力权重来聚合信息。Attention4DDownsample 类则在注意力机制的基础上实现了下采样功能,以减少特征图的分辨率。
Embedding 类负责将输入图像转换为嵌入表示,支持不同的处理方式(如轻量级和自适应下采样)。Mlp 类实现了多层感知机(MLP),用于对特征进行进一步处理。AttnFFN 和 FFN 类则结合了注意力机制和前馈网络,形成了模型的基本构建块。
eformer_block 函数用于构建模型的不同层次结构,具体取决于输入的层数和其他超参数。EfficientFormerV2 类则是整个模型的主类,负责整合各个组件,并定义前向传播过程。
在模型的前向传播中,输入图像首先通过嵌入层,然后依次经过各个构建块,最终输出特征。模型还支持特征分支输出,以便在不同层次上获取特征。
文件的最后部分定义了一些函数,用于创建不同版本的 EfficientFormerV2 模型,并加载预训练权重。通过 efficientformerv2_s0、efficientformerv2_s1、efficientformerv2_s2 和 efficientformerv2_l 函数,可以方便地实例化不同规模的模型。
在 main 部分,程序创建了几个模型实例,并对随机生成的输入进行前向传播,输出每个模型的特征图大小。这部分代码用于测试模型的构建和功能。
总体而言,这个程序文件实现了一个高效的图像处理模型,结合了注意力机制和卷积操作,适用于各种计算机视觉任务。
10.3 block.py
以下是代码中最核心的部分,并附上详细的中文注释:
import torch
import torch.nn as nn
import torch.nn.functional as F
def autopad(k, p=None, d=1): # kernel, padding, dilation
"""自动填充以实现'same'形状输出。"""
if d > 1:
k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k] # 实际的卷积核大小
if p is None:
p = k // 2 if isinstance(k, int) else [x // 2 for x in k] # 自动填充
return p
class Conv(nn.Module):
"""标准卷积层,包含卷积和批归一化。"""
def init (self, in_channels, out_channels, kernel_size=3, stride=1, padding=None, groups=1, act=True):
super().init ()
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, autopad(kernel_size, padding), groups=groups, bias=False)
self.bn = nn.BatchNorm2d(out_channels)
self.act = nn.SiLU() if act else nn.Identity() # 默认激活函数为SiLU
def forward(self, x):
"""前向传播函数。"""
return self.act(self.bn(self.conv(x)))
class Bottleneck(nn.Module):
"""标准瓶颈结构,包含两个卷积层。"""
def init (self, c1, c2, shortcut=True, g=1, k=(3, 3), e=0.5):
super().init ()
c_ = int(c2 * e) # 隐藏通道数
self.cv1 = Conv(c1, c_, k[0], 1) # 第一个卷积层
self.cv2 = Conv(c_, c2, k[1], 1) # 第二个卷积层
self.add = shortcut and c1 == c2 # 是否使用快捷连接
def forward(self, x):
"""前向传播函数。"""
return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))
class C3k(nn.Module):
"""C3k模块,包含多个瓶颈结构。"""
def init (self, c1, c2, n=1, shortcut=False, g=1, e=0.5, k=3):
super().init ()
self.m = nn.Sequential(*(Bottleneck(c1, c2, shortcut, g, k=(k, k), e=1.0) for _ in range(n))) # 多个瓶颈层
def forward(self, x):
"""前向传播函数。"""
return self.m(x)
class DynamicConv(nn.Module):
"""动态卷积层,使用条件卷积。"""
def init (self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True, num_experts=4):
super().init ()
self.conv = nn.Sequential(
DynamicConv_Single(c1, c2, kernel_size=k, stride=s, padding=autopad(k, p, d), dilation=d, groups=g, num_experts=num_experts),
nn.BatchNorm2d(c2),
nn.SiLU() if act else nn.Identity()
)
def forward(self, x):
"""前向传播函数。"""
return self.conv(x)
class SEAttention(nn.Module):
"""通道注意力机制。"""
def init (self, in_channels, reduction=16):
super(SEAttention, self).init ()
self.fc1 = nn.Conv2d(in_channels, in_channels // reduction, kernel_size=1)
self.fc2 = nn.Conv2d(in_channels // reduction, in_channels, kernel_size=1)
def forward(self, x):
"""前向传播函数。"""
b, c, _, _ = x.size()
y = F.adaptive_avg_pool2d(x, 1).view(b, c)
y = self.fc2(F.relu(self.fc1(y))).view(b, c, 1, 1)
return x * torch.sigmoid(y)
class C3k2(nn.Module):
"""C3k2模块,包含多个C3k模块。"""
def init (self, c1, c2, n=1, c3k=False, e=0.5, g=1, shortcut=True):
super().init ()
self.m = nn.ModuleList(C3k(c1, c2, n, shortcut, g, e) for _ in range(n)) # 多个C3k模块
def forward(self, x):
"""前向传播函数。"""
for m in self.m:
x = m(x)
return x
这里可以继续添加其他类和函数的核心部分及其注释
代码核心部分说明
autopad: 用于自动计算卷积的填充,使得输出尺寸与输入相同。
Conv: 自定义卷积层,包含卷积、批归一化和激活函数。
Bottleneck: 实现标准的瓶颈结构,通常用于深度学习模型中以减少参数数量。
C3k: 包含多个瓶颈结构的模块。
DynamicConv: 实现动态卷积,允许根据输入条件选择卷积核。
SEAttention: 实现通道注意力机制,增强特征表达能力。
C3k2: 包含多个C3k模块的结构,适用于更复杂的特征提取。
进一步的说明
如果需要对其他部分进行简化和注释,请告知我。
这个程序文件 block.py 是一个深度学习模型的实现,主要用于计算机视觉任务,特别是目标检测和图像分割等。文件中包含了多个模块和类,主要涉及卷积操作、注意力机制、特征融合等。以下是对文件内容的详细说明:
首先,文件导入了许多必要的库,包括 PyTorch 和一些自定义模块。接着,定义了一些基础的卷积和激活函数,例如 Conv 和 h_swish,这些函数在后续的模型构建中被广泛使用。
接下来,文件定义了一系列的网络模块,包括不同类型的卷积块(如 Bottleneck、C3k、C3k2 等),这些模块通过堆叠实现了更复杂的网络结构。每个模块通常包括多个卷积层、激活函数和批归一化层,部分模块还包含了跳跃连接(shortcut),以便在训练过程中保持信息的流动。
文件中还实现了多种注意力机制,如 GOLDYOLO_Attention、PSA_Attention 和 CA_HSFPN,这些机制通过对特征图的加权来增强模型对重要特征的关注,从而提高模型的性能。
此外,文件中实现了一些特征融合模块,如 DynamicInterpolationFusion 和 ContextGuideFusionModule,这些模块通过对不同尺度的特征进行融合,来增强模型对多尺度信息的捕捉能力。
文件还包含了一些特殊的卷积模块,如 DynamicConv 和 GhostModule,这些模块通过动态卷积和轻量级卷积的方式,进一步提高了模型的效率和效果。
最后,文件中定义了一些特定的网络结构,如 C3k2_Star、C3k2_MogaBlock 和 C3k2_UniRepLKNetBlock,这些结构结合了上述的各种模块和机制,形成了完整的网络架构。
总的来说,block.py 文件是一个功能丰富的深度学习模型实现,涵盖了卷积、注意力、特征融合等多个方面,适用于计算机视觉中的多种任务。通过这些模块的组合,可以构建出高效且具有强大表现力的视觉模型。
10.4 attention.py
以下是代码中最核心的部分,并附上详细的中文注释:
import torch
from torch import nn
class EMA(nn.Module):
def init (self, channels, factor=8):
super(EMA, self).init ()
self.groups = factor # 将通道分成若干组
assert channels // self.groups > 0 # 确保每组至少有一个通道
self.softmax = nn.Softmax(-1) # 定义softmax层
self.agp = nn.AdaptiveAvgPool2d((1, 1)) # 自适应平均池化到1x1
self.pool_h = nn.AdaptiveAvgPool2d((None, 1)) # 自适应平均池化到(h, 1)
self.pool_w = nn.AdaptiveAvgPool2d((1, None)) # 自适应平均池化到(1, w)
self.gn = nn.GroupNorm(channels // self.groups, channels // self.groups) # 分组归一化
self.conv1x1 = nn.Conv2d(channels // self.groups, channels // self.groups, kernel_size=1) # 1x1卷积
self.conv3x3 = nn.Conv2d(channels // self.groups, channels // self.groups, kernel_size=3, padding=1) # 3x3卷积
def forward(self, x):
b, c, h, w = x.size() # 获取输入的批量大小、通道数、高度和宽度
group_x = x.reshape(b * self.groups, -1, h, w) # 将输入重塑为(b*g, c//g, h, w)
x_h = self.pool_h(group_x) # 对每组进行高度池化
x_w = self.pool_w(group_x).permute(0, 1, 3, 2) # 对每组进行宽度池化并转置
hw = self.conv1x1(torch.cat([x_h, x_w], dim=2)) # 将两个池化结果拼接后通过1x1卷积
x_h, x_w = torch.split(hw, [h, w], dim=2) # 将结果分为高度和宽度部分
x1 = self.gn(group_x * x_h.sigmoid() * x_w.permute(0, 1, 3, 2).sigmoid()) # 通过sigmoid激活后进行分组归一化
x2 = self.conv3x3(group_x) # 通过3x3卷积
x11 = self.softmax(self.agp(x1).reshape(b * self.groups, -1, 1).permute(0, 2, 1)) # 对x1进行自适应平均池化和softmax
x12 = x2.reshape(b * self.groups, c // self.groups, -1) # 重塑x2
x21 = self.softmax(self.agp(x2).reshape(b * self.groups, -1, 1).permute(0, 2, 1)) # 对x2进行自适应平均池化和softmax
x22 = x1.reshape(b * self.groups, c // self.groups, -1) # 重塑x1
weights = (torch.matmul(x11, x12) + torch.matmul(x21, x22)).reshape(b * self.groups, 1, h, w) # 计算权重
return (group_x * weights.sigmoid()).reshape(b, c, h, w) # 返回加权后的结果
class SimAM(nn.Module):
def init (self, e_lambda=1e-4):
super(SimAM, self).init ()
self.activaton = nn.Sigmoid() # 定义sigmoid激活函数
self.e_lambda = e_lambda # 正则化参数
def forward(self, x):
b, c, h, w = x.size() # 获取输入的批量大小、通道数、高度和宽度
n = w * h - 1 # 计算n
x_minus_mu_square = (x - x.mean(dim=[2, 3], keepdim=True)).pow(2) # 计算均值平方差
y = x_minus_mu_square / (4 * (x_minus_mu_square.sum(dim=[2, 3], keepdim=True) / n + self.e_lambda)) + 0.5 # 计算y
return x * self.activaton(y) # 返回加权后的输入
class SpatialGroupEnhance(nn.Module):
def init (self, groups=8):
super().init ()
self.groups = groups # 组数
self.avg_pool = nn.AdaptiveAvgPool2d(1) # 自适应平均池化到1x1
self.weight = nn.Parameter(torch.zeros(1, groups, 1, 1)) # 权重参数
self.bias = nn.Parameter(torch.zeros(1, groups, 1, 1)) # 偏置参数
self.sig = nn.Sigmoid() # 定义sigmoid激活函数
self.init_weights() # 初始化权重
def init_weights(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode='fan_out') # 使用He初始化卷积层权重
if m.bias is not None:
nn.init.constant_(m.bias, 0) # 偏置初始化为0
elif isinstance(m, nn.BatchNorm2d):
nn.init.constant_(m.weight, 1) # 批归一化权重初始化为1
nn.init.constant_(m.bias, 0) # 偏置初始化为0
elif isinstance(m, nn.Linear):
nn.init.normal_(m.weight, std=0.001) # 线性层权重初始化为小的正态分布
if m.bias is not None:
nn.init.constant_(m.bias, 0) # 偏置初始化为0
def forward(self, x):
b, c, h, w = x.shape # 获取输入的批量大小、通道数、高度和宽度
x = x.view(b * self.groups, -1, h, w) # 重塑输入
xn = x * self.avg_pool(x) # 计算加权
xn = xn.sum(dim=1, keepdim=True) # 按通道求和
t = xn.view(b * self.groups, -1) # 重塑
t = t - t.mean(dim=1, keepdim=True) # 减去均值
std = t.std(dim=1, keepdim=True) + 1e-5 # 计算标准差
t = t / std # 归一化
t = t.view(b, self.groups, h, w) # 重塑
t = t * self.weight + self.bias # 计算最终权重
t = t.view(b * self.groups, 1, h, w) # 重塑
x = x * self.sig(t) # 加权输入
x = x.view(b, c, h, w) # 恢复原始形状
return x
代码核心部分说明
EMA (Exponential Moving Average): 该模块用于计算输入特征的加权平均,增强特征的表达能力。它通过对输入特征进行分组处理,并使用卷积和归一化操作来实现。
SimAM (Similarity Attention Module): 该模块通过计算输入特征的均值和方差来生成注意力权重,并使用sigmoid激活函数来增强特征的表示能力。
SpatialGroupEnhance: 该模块通过自适应平均池化和sigmoid激活函数来增强空间特征的表达能力。它将输入特征分为多个组,并计算每组的加权平均。
这些模块在特征提取和增强中起着重要作用,能够提高模型的性能。
这个程序文件 attention.py 实现了一系列与注意力机制相关的深度学习模块,主要用于计算机视觉任务中的特征提取和增强。文件中使用了 PyTorch 框架,包含了多个类和函数,具体功能如下:
首先,文件导入了必要的库,包括 PyTorch 的核心模块、神经网络模块、以及一些用于高效计算的工具,如 einops 和 torchvision。接着,定义了一些通用的注意力机制模块,如 EMA(Exponential Moving Average)、SimAM(Similarity Attention Module)、SpatialGroupEnhance 等。
EMA 类实现了一种基于通道的注意力机制,通过对输入特征进行分组处理,计算出每个组的权重,并通过 Sigmoid 函数进行激活,最终将权重应用于输入特征。
SimAM 类实现了一种简单的注意力机制,主要通过计算输入特征的均值和方差来生成注意力权重,并与输入特征相乘以增强特征。
SpatialGroupEnhance 类则通过对输入特征进行空间上的增强,利用平均池化和 Sigmoid 激活函数生成空间注意力权重,从而提升特征的表达能力。
TopkRouting 和 KVGather 类实现了基于路由的注意力机制,通过选择最相关的特征进行加权聚合,增强了模型对重要特征的关注。
BiLevelRoutingAttention 类实现了一种双层路由注意力机制,结合了全局和局部特征的提取,适用于高分辨率输入。该类的 forward 方法处理输入特征,通过计算查询、键、值的关系来生成注意力权重,并应用于输入特征。
此外,文件中还实现了其他一些注意力机制模块,如 CoordAtt、TripletAttention、BAMBlock、EfficientAttention 等。这些模块各自实现了不同的注意力机制,旨在提升模型的特征提取能力和表达能力。
最后,文件中还定义了一些辅助函数和类,如 img2windows 和 windows2img,用于处理图像的窗口化操作,以便在注意力计算中进行更细粒度的特征提取。
总体而言,attention.py 文件是一个功能丰富的深度学习模块集合,专注于实现各种注意力机制,适用于计算机视觉任务中的特征增强和提取。
源码文件

源码获取
欢迎大家点赞、收藏、关注、评论 啦 、查看👇🏻获取联系方式👇🏻