论文链接:https://arxiv.org/pdf/2305.17654
如下图:
MixDehazeNet 主要由两个核心模块组成:
MSPLCK(Multi-Scale Parallel Large Convolution Kernel,多尺度并行大卷积核模块) 是一种创新的深度学习模块,旨在通过多尺度特征提取和大卷积核的结合,增强模型对局部和全局信息的捕获能力。以下是对 MSPLCK 模块的详细解读:
MSPLCK 模块的设计目标是解决传统卷积神经网络(CNN)在特征提取中的两个主要问题:
通过结合多尺度卷积核和并行设计,MSPLCK 模块能够在保持计算效率的同时,捕获多尺度的局部和全局特征。
MSPLCK 模块主要由以下几个部分组成:
MSPLCK 模块的工作流程如下:
MSPLCK 模块广泛应用于需要多尺度特征提取的计算机视觉任务中,例如:
MSPLCK 模块通过多尺度并行卷积核和特征融合的设计,显著提升了模型对局部和全局特征的捕获能力,同时保持了较高的计算效率。其创新点在于结合了膨胀卷积和深度可分离卷积的优势,为多尺度特征提取提供了一种高效、灵活的解决方案。这种模块设计在图像去雾、目标检测和图像分割等任务中表现出色,具有广泛的应用潜力。
在这里插入图片描述
EPA 模块是 MixDehazeNet 的核心创新之一,其设计目的是通过混合不同类型的注意力机制,增强网络对特征图中重要信息的捕获能力。具体来说,EPA 模块包含以下三种注意力机制:
EPA 模块的一个显著特点是将上述三种注意力机制并行化处理,而非依次串联。这种设计的优势在于:
在这里插入图片描述
MixDehazeNet 的增强并行注意力模块(EPA)通过结合简单像素注意力、通道注意力和像素注意力,显著提升了网络对图像特征的捕获能力。其并行设计不仅提高了计算效率,还实现了多维信息的高效融合,使得 MixDehazeNet 在图像去雾任务中表现出色。这种模块的设计理念也为其他计算机视觉任务(如图像分割和目标检测)提供了参考。
import torch
import torch.nn as nn
class MixStructureBlock(nn.Module):
def __init__(self, dim):
super().__init__()
# 初始化两个批归一化层
self.norm1 = nn.BatchNorm2d(dim)
self.norm2 = nn.BatchNorm2d(dim)
# 定义不同大小的卷积层
self.conv1 = nn.Conv2d(dim, dim, kernel_size=1) # 1x1卷积
self.conv2 = nn.Conv2d(dim, dim, kernel_size=5, padding=2, padding_mode='reflect') # 5x5卷积,反射填充
# 膨胀率3的分组卷积,用于捕捉不同范围的特征
self.conv3_19 = nn.Conv2d(dim, dim, kernel_size=7, padding=9, groups=dim, dilation=3, padding_mode='reflect')
self.conv3_13 = nn.Conv2d(dim, dim, kernel_size=5, padding=6, groups=dim, dilation=3, padding_mode='reflect')
self.conv3_7 = nn.Conv2d(dim, dim, kernel_size=3, padding=3, groups=dim, dilation=3, padding_mode='reflect')
# 简单像素注意力机制
self.Wv = nn.Sequential(
nn.Conv2d(dim, dim, 1), # 1x1卷积用于维度变换
nn.Conv2d(dim, dim, kernel_size=3, padding=3 // 2, groups=dim, padding_mode='reflect') # 分组卷积
)
self.Wg = nn.Sequential(
nn.AdaptiveAvgPool2d(1), # 全局平均池化
nn.Conv2d(dim, dim, 1), # 1x1卷积
nn.Sigmoid() # Sigmoid激活函数
)
# 通道注意力机制
self.ca = nn.Sequential(
nn.AdaptiveAvgPool2d(1), # 全局平均池化
nn.Conv2d(dim, dim, 1, padding=0, bias=True), # 1x1卷积
nn.GELU(), # GELU激活函数
# nn.ReLU(True), # 可选:ReLU激活函数
nn.Conv2d(dim, dim, 1, padding=0, bias=True), # 1x1卷积
nn.Sigmoid() # Sigmoid激活函数
)
# 像素注意力机制
self.pa = nn.Sequential(
nn.Conv2d(dim, dim // 8, 1, padding=0, bias=True), # 1x1卷积降维
nn.GELU(), # GELU激活函数
# nn.ReLU(True), # 可选:ReLU激活函数
nn.Conv2d(dim // 8, 1, 1, padding=0, bias=True), # 1x1卷积升维
nn.Sigmoid() # Sigmoid激活函数
)
# 多层感知机(MLP),用于特征融合
self.mlp = nn.Sequential(
nn.Conv2d(dim * 3, dim * 4, 1), # 1x1卷积,特征融合
nn.GELU(), # GELU激活函数
# nn.ReLU(True), # 可选:ReLU激活函数
nn.Conv2d(dim * 4, dim, 1) # 1x1卷积,恢复维度
)
self.mlp2 = nn.Sequential(
nn.Conv2d(dim * 3, dim * 4, 1), # 第二个1x1卷积,特征融合
nn.GELU(), # GELU激活函数
# nn.ReLU(True), # 可选:ReLU激活函数
nn.Conv2d(dim * 4, dim, 1) # 1x1卷积,恢复维度
)
def forward(self, x):
# 第一个分支
identity = x # 保存输入x作为残差连接
x = self.norm1(x) # 批归一化
x = self.conv1(x) # 1x1卷积
x = self.conv2(x) # 5x5卷积
# 融合不同膨胀率的分组卷积输出
x = torch.cat([self.conv3_19(x), self.conv3_13(x), self.conv3_7(x)], dim=1)
x = self.mlp(x) # MLP进行特征融合
x = identity + x # 残差连接
# 第二个分支,包含注意力机制
identity = x # 保存上一步的输出作为新的残差连接
x = self.norm2(x) # 批归一化
# 融合简单像素注意力、通道注意力和像素注意力
x = torch.cat([self.Wv(x) * self.Wg(x), self.ca(x) * x, self.pa(x) * x], dim=1)
x = self.mlp2(x) # 第二个MLP进行特征融合
x = identity + x # 残差连接
return x
if __name__ == '__main__':
# 创建一个随机输入张量,形状为 (batch_size, channels, height, width)
input = torch.rand(1, 64, 640, 640)
# 实例化MixStructureBlock模块
block = MixStructureBlock(dim=64)
# 前向传播
output = block(input)
# 打印输入和输出的形状
print(input.size())
print(output.size())
输出结果:
torch.Size([1, 64, 640, 640])
torch.Size([1, 64, 640, 640])
https://blog.csdn.net/m0_47867638/article/details/145043041?spm=1001.2014.3001.5501
https://blog.csdn.net/m0_47867638/article/details/145043022?spm=1001.2014.3001.5501
https://blog.csdn.net/m0_47867638/article/details/145042690?spm=1001.2014.3001.5501