首页 > 其他分享 >【每天一篇深度学习论文】即插即用特征注意力融合模块FFA

【每天一篇深度学习论文】即插即用特征注意力融合模块FFA

时间:2024-11-29 12:59:25浏览次数:10  
标签:__ dim nn self 模块 即插即用 FFA size

目录

论文介绍

题目

FFA-Net: Feature Fusion Attention Network for Single Image Dehazing

论文地址

arxiv.org/pdf/1911.07559

创新点

  • 特征融合注意力网络(FFA-Net):提出了一种端到端的特征融合注意力网络(FFA-Net)用于单张图像去雾。FFA-Net在厚雾区域和富含纹理的细节恢复方面具有显著优势,其细节和色彩保真度优于之前的去雾方法。
  • 特征注意力模块(FA):设计了一个创新的特征注意力模块,结合了通道注意力和像素注意力机制。该模块使得网络在厚雾区域和关键通道上更加聚焦,提供了处理不同类型信息的灵活性,提升了卷积神经网络的表达能力。
  • 局部残差学习和特征注意力的基础模块:提出了一种结合局部残差学习和特征注意力的基础模块,局部残差学习允许薄雾和低频信息通过多层局部残差连接被跳过,从而让网络关注更有效的信息。
  • 基于注意力的特征融合结构(FFA):提出了基于注意力的特征融合结构,可以将浅层特征保留并传递到深层,并根据不同级别特征的重要性自适应地学习权重。这种方式比直接指定权重的融合方法效果更好。

方法

整体结构

FFA-Net模型通过浅层特征提取、多个包含局部残差学习和特征注意力的组架构、全局残差学习和特征融合注意力模块来实现单图像去雾。模型利用通道和像素级的注意力机制自适应地调整不同特征的权重,融合浅层和深层信息,从而更有效地去除雾霾,保留细节和色彩的准确性。
在这里插入图片描述

  • **浅层特征提取模块:**输入的有雾图像首先通过浅层特征提取模块,用以提取初步的低层特征。
  • **组架构(Group Architecture):**模型的核心部分由多个组架构组成,每个组架构包含多个基础模块,通过多个跳跃连接增加网络深度和表达能力。这种组架构主要通过局部残差学习(Local Residual Learning)和特征注意力模块(Feature Attention, FA)来实现。
    在这里插入图片描述
  • 基础模块(Basic Block):基础模块由局部残差学习和特征注意力模块构成,局部残差学习可以跳过薄雾和低频信息,使网络更专注于有效信息。特征注意力模块通过通道注意力和像素注意力结合的方式,增强网络在不同特征和像素上的关注力度。
    在这里插入图片描述
  • 全局残差学习模块(Global Residual Learning):在组架构的输出之后加入一个全局残差学习模块,通过两层卷积操作和长跳跃连接来帮助网络更好地恢复清晰的图像。这一模块能够进一步提高去雾效果并稳定网络训练。
  • 特征融合注意力模块(Feature Fusion Attention, FFA):所有组架构的输出在通道方向上进行特征图拼接,并通过特征注意力机制来调整不同级别特征的权重,实现浅层和深层信息的融合。这种自适应权重的学习让网络能够更好地关注厚雾区域和高频纹理信息
  • 重构模块:融合后的特征最终输入到重构模块中,通过反卷积或卷积操作来生成无雾的清晰图像输出。

即插即用模块作用

FFA 作为一个即插即用模块,主要适用于:

  • 应用场景:
    • 图像去雾:适用于处理厚雾或不均匀雾霾分布的场景,可以增强去雾效果,恢复图像的细节和真实色彩。
    • 图像超分辨率:适用于需要提升图像分辨率的场景,帮助保留高频纹理和细节信息。
    • 图像去噪:在去除噪声的同时保留图像的细节,使图像在噪声去除后更清晰。
    • 图像复原:如去雨、去划痕等低层视觉任务,适合需要融合多层特征信息以增强细节表现的场景。
  • 主要作用
    • 自适应特征权重分配:通过通道和像素注意力机制,自适应地为不同特征分配权重,增强关键区域(如厚雾区域和高频细节)的关注度。
    • 浅层与深层信息融合:保留浅层的关键信息并传递至深层,提高网络在处理复杂纹理和细节上的能力。
    • 提升图像复原效果:增强网络在细节复原、色彩还原和视觉效果上的表现,使图像复原效果更加真实和自然

消融实验结果

在这里插入图片描述

  • 仅使用特征注意力模块(FA)时,网络在去雾性能上已经具有较强的竞争力。
  • 将局部残差学习(LRL)与FA模块结合使用后,网络性能和训练稳定性均有所提升。
  • 当结合FFA结构后,网络性能进一步大幅提升,表明FFA结构在融合不同层级特征信息、提高去雾效果上起到了关键作用。

即插即用模块


import torch.nn as nn
import torch

def default_conv(in_channels, out_channels, kernel_size, bias=True):
    return nn.Conv2d(in_channels, out_channels, kernel_size, padding=(kernel_size // 2), bias=bias)



class PALayer(nn.Module):
    def __init__(self, channel):
        super(PALayer, self).__init__()
        self.pa = nn.Sequential(
            nn.Conv2d(channel, channel // 8, 1, padding=0, bias=True),
            nn.ReLU(inplace=True),
            nn.Conv2d(channel // 8, 1, 1, padding=0, bias=True),
            nn.Sigmoid()
        )

    def forward(self, x):
        y = self.pa(x)
        return x * y



class CALayer(nn.Module):
    def __init__(self, channel):
        super(CALayer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.ca = nn.Sequential(
            nn.Conv2d(channel, channel // 8, 1, padding=0, bias=True),
            nn.ReLU(inplace=True),
            nn.Conv2d(channel // 8, channel, 1, padding=0, bias=True),
            nn.Sigmoid()
        )

    def forward(self, x):
        y = self.avg_pool(x)
        y = self.ca(y)
        return x * y


# 基础块(Block)
class Block(nn.Module):
    def __init__(self, conv, dim, kernel_size):
        super(Block, self).__init__()
        self.conv1 = conv(dim, dim, kernel_size, bias=True)
        self.act1 = nn.ReLU(inplace=True)
        self.conv2 = conv(dim, dim, kernel_size, bias=True)
        self.calayer = CALayer(dim)
        self.palayer = PALayer(dim)

    def forward(self, x):
        res = self.act1(self.conv1(x))
        res = res + x
        res = self.conv2(res)
        res = self.calayer(res)
        res = self.palayer(res)
        res = res + x
        return res


# 分组(Group)
class Group(nn.Module):
    def __init__(self, conv, dim, kernel_size, blocks):
        super(Group, self).__init__()

        modules = [Block(conv, dim, kernel_size) for _ in range(blocks)]
        modules.append(conv(dim, dim, kernel_size))
        self.gp = nn.Sequential(*modules)

    def forward(self, x):
        res = self.gp(x)
        res = res + x
        return res



class FFA(nn.Module):
    def __init__(self, gps, blocks, conv=default_conv):
        super(FFA, self).__init__()
        self.gps = gps
        self.dim = 64
        kernel_size = 3
        pre_process = [conv(3, self.dim, kernel_size)]


        assert self.gps == 3


        self.g1 = Group(conv, self.dim, kernel_size, blocks=blocks)
        self.g2 = Group(conv, self.dim, kernel_size, blocks=blocks)
        self.g3 = Group(conv, self.dim, kernel_size, blocks=blocks)


        self.ca = nn.Sequential(
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(self.dim * self.gps, self.dim // 16, 1, padding=0),
            nn.ReLU(inplace=True),
            nn.Conv2d(self.dim // 16, self.dim * self.gps, 1, padding=0, bias=True),
            nn.Sigmoid()
        )


        self.palayer = PALayer(self.dim)

        post_process = [
            conv(self.dim, self.dim, kernel_size),
            conv(self.dim, 3, kernel_size)
        ]

        self.pre = nn.Sequential(*pre_process)
        self.post = nn.Sequential(*post_process)

    def forward(self, x1):
        x = self.pre(x1)
        res1 = self.g1(x)
        res2 = self.g2(res1)
        res3 = self.g3(res2)
        w = self.ca(torch.cat([res1, res2, res3], dim=1))
        w = w.view(-1, self.gps, self.dim)[:, :, :, None, None]
        out = w[:, 0, ::] * res1 + w[:, 1, ::] * res2 + w[:, 2, ::] * res3
        out = self.palayer(out)
        x = self.post(out)
        return x + x1


if __name__ == "__main__":

    input = torch.randn(1, 3, 32, 32) # B C H W

    model = FFA(gps=3, blocks=20)

    output = model(input)

    print(input.size())    print(output.size())

标签:__,dim,nn,self,模块,即插即用,FFA,size
From: https://blog.csdn.net/Magnolia_He/article/details/144076622

相关文章

  • 【每天一篇深度学习论文】即插即用频域增强通道注意力机制EFCAttention
    目录论文介绍题目:论文地址:创新点方法整体结构即插即用模块作用消融实验结果即插即用模块代码论文介绍题目:FECAM:FrequencyEnhancedChannelAttentionMechanismforTimeSeriesForecasting论文地址:https://arxiv.org/abs/2212.01209创新点频域增强的通道......
  • js模块化
    JavaScript模块化规范1.模块化概述什么是模块化?将程序文件依据一定规则拆分成多个文件,这种编码方式就是模块化的编码方式拆分出来的每个文件就是一个模块,模块中的数据都是私有的,模块之间相互隔离同时也能通过一些手段,可以把模块内的指定数据“交出去”,供其他模块使用......
  • JS怎么实现Module模块化?
    在JavaScript中实现模块化主要有两种方式:CommonJS和ES6模块。以下是这两种方法的基本实现:CommonJSCommonJS是Node.js的原生模块系统,但它也可以在浏览器环境中使用通过构建工具如Webpack或Browserify。模块导出://myModule.jsmodule.exports={myFunction:function(......
  • django中admin模块中修改密码的form
    django中admin模块中修改密码的form,参考这个文件在E:\django5env\Lib\site-packages\django\contrib\auth\forms.py,其中写了好几个关于form的,可以参考其验证、错误信息等方法classPasswordChangeForm(SetPasswordForm):"""Aformthatletsauserchangetheirp......
  • 用函数实现模块化的程序设计(四)
    4.对被调用函数的声明和函数原型前言在函数中调用另一个函数(即被调用函数)需要具备以下条件:(1)被调用函数必须是已经定义的函数(库函数或者用户自己定义的函数)(2)如果使用库函数,应在开头用#include指令调用有关库函数所用到的信息包含到文件(3)如果使用用户自己定义的函数,而该......
  • Letstg市场模块大更新!新产品上线,精彩不容错过!
    大家好!我们产品经理李明,我非常激动地宣布,Letstg市场模块迎来了全面升级!为了给大家带来更多的选择和更好的体验,我们新增了许多全新产品,让你的社交和娱乐体验更加丰富!......
  • (即插即用模块-Attention部分) 二十一、(2021) Polarized Self-Attention 极化自注意
    文章目录1、PolarizedSelf-Attention2、代码实现paper:PolarizedSelf-Attention:TowardsHigh-qualityPixel-wiseRegressionCode:https://github.com/DeLightCMU/PSA1、PolarizedSelf-Attention像素级回归是细粒度计算机视觉任务中的常见问题。回归问题往......
  • 大核选择卷积模块 LSK
    importtorchimporttorch.nnasnn#Github地址:https://github.com/zcablii/Large-Selective-Kernel-Network#论文地址:https://openaccess.thecvf.com/content/ICCV2023/papers/Li_Large_Selective_Kernel_Network_for_Remote_Sensing_Object_Detection_ICCV_2023_paper.pdfc......
  • MAGNet -MAFM 多尺度感知融合模块
    importmathimporttorch.nnasnnimporttorchfromtimm.models.layersimporttrunc_normal_classCOI(nn.Module):def__init__(self,inc,k=3,p=1):super().__init__()self.outc=incself.dw=nn.Conv2d(inc,self.outc,kernel......
  • (即插即用模块-Attention部分) 二十、(2021) GAA 门控轴向注意力
    文章目录1、GatedAxial-Attention2、代码实现paper:MedicalTransformer:GatedAxial-AttentionforMedicalImageSegmentationCode:https://github.com/jeya-maria-jose/Medical-Transformer1、GatedAxial-Attention论文首先分析了ViTs在训练小规模数据......