注意力机制SENet:一种即插即用的通道注意力模块

SENet是一种深度学习网络结构,它通过全局平均池化和全连接层计算特征层权重,利用Sigmoid函数限制权重在0-1之间。在PyTorch中,可以使用nn.Sequential方便地构建SENet模型,自动按顺序执行各层操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、SENet

  1. 对特征层进行全局平均池化(高度和宽度上),获得一个深度为C2的特征长条
  2. 通过两个全连接层,第一个全连接层输出缩减维度/r,第二个全连接层输出还原维度
  3. 最后通过一个Sigmoid函数,获取每个特征层的权值 0—1之间
  4. 对原特征层的每一层进行加权并返回

在这里插入图片描述

二、SENet的pytorch实现

class senet(nn.Module):
    def __init__(self, channel, ratio=16):
        super(senet, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1) #全局平均池化
        self.fc = nn.Sequential(
            nn.Linear(channel, channel // ratio, False),
            nn.ReLU(),
            nn.Linear(channel // ratio, channel, False),
            nn.Sigmoid(),  # 用于将每个元素压缩到0---1之间
        )
    def forward(self, x):
        b, c, h, w = x.size()
        # 全局平均池化 b,c,h,w----->b,c,1,1
        avg = self.avg_pool(x).view([b, c])
        # 将平均池化后的结果输入全连接 通过sigmoid得到每一个层的权重大小
        fc = self.fc(avg).view([b, c, 1, 1])
        return x * fc  # 将特征层 和 每一层相乘加权

三、学到的一些其他知识

在继承nn.Sequential的类中,不需要显式地重写forward方法
因为当调用nn.Sequential的实例的forward方法时,它会按照模块的顺序依次调用每个模块的forward方法,将输入数据传递给每个模块,并返回最终的输出。

import torch
import torch.nn as nn
class MyNetwork(nn.Sequential):
    def __init__(self):
        super(MyNetwork, self).__init__(
            nn.Linear(10, 20),
            nn.ReLU(),
            nn.Linear(20, 30),
            nn.ReLU()
        )
# 使用自定义网络类
model = MyNetwork()
input = torch.randn(1, 10)
output = model(input)
SENet一种基于注意力机制的神经网络模型,它可以自适应地调整每个通道的权重,以提高模型的表现能力。下面是SENet的一个简单实现代码,包括SE模块SENet的主体结构: ```python import torch import torch.nn as nn import torch.nn.functional as F class SEModule(nn.Module): def __init__(self, channels, reduction): super(SEModule, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.fc1 = nn.Conv2d(channels, channels // reduction, kernel_size=1, bias=False) self.relu = nn.ReLU(inplace=True) self.fc2 = nn.Conv2d(channels // reduction, channels, kernel_size=1, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): batch_size, channels, _, _ = x.size() y = self.avg_pool(x).view(batch_size, channels) y = self.fc1(y) y = self.relu(y) y = self.fc2(y) y = self.sigmoid(y).view(batch_size, channels, 1, 1) return x * y class SENet(nn.Module): def __init__(self, num_classes=1000, channels=64, reduction=16): super(SENet, self).__init__() self.conv1 = nn.Conv2d(3, channels, kernel_size=3, stride=1, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(channels) self.relu = nn.ReLU(inplace=True) self.layer1 = self._make_layer(SEModule, channels, reduction, 3) self.layer2 = self._make_layer(SEModule, channels*2, reduction, 4, stride=2) self.layer3 = self._make_layer(SEModule, channels*4, reduction, 6, stride=2) self.layer4 = self._make_layer(SEModule, channels*8, reduction, 3, stride=2) self.avgpool = nn.AdaptiveAvgPool2d(1) self.fc = nn.Linear(channels*8, num_classes) def _make_layer(self, block, channels, reduction, blocks, stride=1): layers = [] layers.append(block(channels, reduction)) for i in range(1, blocks): layers.append(block(channels, reduction)) return nn.Sequential(*layers) def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) x = self.layer1(x) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) x = self.avgpool(x) x = x.view(x.size(0), -1) x = self.fc(x) return x ``` 在上面的代码中,SEModule是SE模块,它通过自适应平均池化和两个全连接层实现通道注意力SENet则是SE模型的主体框架,它采用四个卷积层和四个SE模块构建。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值