学习Se-net和Sk-net 附网络简单代码(pytorch)

Se-net通过通道注意力机制提升网络性能,其核心是全局平均池化和全连接层来调整通道权重。SK-net则采用自适应卷积选择不同卷积块,每个通道可以选择适合的卷积。两者均可作为模块增强Resnet等网络。
摘要由CSDN通过智能技术生成

(一)Se-net的原理和思路
    Se-net严格来说是一个小结构,它可以直接插入已有的网络结构中,帮助原有结构获得更好的效果,如插入Resnet网络中。
在这里插入图片描述

Se-net的整个流程如下:
    (1)假设一个特征图,它的维度是(1,3,255,255),首先将它进行一般卷积。这个过程也可以是其他网络的操作过程。之后我们得到一个新的维度的特征图,假设卷积块为64个,那么输出的特征图的维度为(1,64,255,255)。
    (2)在以往的网络中,我们仅仅是对网络通过深度学习的方法来优化参数的值,这Se-net中我们引入了通道注意力机制这是因为64个通道代表了图像不同的特征分布,引入注意力机制我们可以给不同通道不同的权重,以便于该通道在后续的计算中占据更重要的成分,这样有助于我们更好的捕捉不同区域的特征。
    所以这里我们首先需要抽象提取出每一个通道的整体特征参数,这里根据论文的测试,选用的全局平均池化,它将维度从(1,64,255,255)可以变化为(1,64,1,1)然后通过全连接->激活->全连接->sigmoid的连接获得每一个通道的权重参数。这里用sigmoid也是根据测试得出来的。然后在用简单的乘法对原数据进行权重增减。这样就获得了一个新的特征图,它在理论上能够更好的表达的图片的特征。

(二)Se-net网络代码实现
    以下只给出一个网络本身的定义,代码还是很好理解的,在 super里定义清楚每一层的输入输出量就可以了,这里指的注意的是他有一个reduction量,他是用来调节线性层负责度的参数,在综合性能和复杂度的基础上选择16作为默认值。

class SELayer(nn.Module):
    def __init__(self, channel, reduction=16):
        super(SELayer, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)  
        self.fc = nn.Sequential(
            nn.Linear(channel, channel // reduction, bias=False),  
            nn.ReLU(inplace=True),
            nn.Linear(channel // reduction, channel, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        y = self.avg_pool(x).view(b, c)  
        y = self.fc(y).view(b, c, 1, 1)  
        return x * y.expand_as(x)

(三)Se-net+Resnet
    左图是ResNet结构,右图是ResNet和Se-net联合的网络,可以看到添加的部分就是Se-net的核心。
在这里插入图片描述

    这里也就是在基础的Resnet中添加了Se-net模块,这里这个模块应该添加在哪里在论文中也是做了比较的,给的代码只是一个参考位置。

self.conv1 = nn.Conv2d(mid_channels, mid_channels, 3, 1, 1, bias=True)
self.conv2 = nn.Conv2d(mid_channels, mid_channels, 3, 1, 1, bias=True)
self.avd_layer = nn.AvgPool2d(3, 1, padding=1)
self.relu = nn.ReLU(inplace=True)
self.se = SELayer(64, 16)

residual = x
out = self.conv1(x)
out = self.relu(out)
out = self.conv2(out)
out = self.se(out)

out += residual
out = self.relu(out)

return out

(四)SK-net的原理和思路
    省略掉过程其实SK-net和Se-net的思路是有贴近的地方的,它们都是输入一个图片特征,通过一定处理使得卷积后的图片特征的每个通道的权重不一样。Se-net是根据注意力机制,学习到了不同的权重,而SK-net是根据自适应卷积的方式来挑选和融合出不同的卷积,也就是每一个通道都可以选择最适合自己的卷积块(以及使用不同的感受野来获取图像特征)。
在这里插入图片描述
SK-net的整个流程如下:
(1)Split划分
    首先使用不同的卷积核获得两个不同的特征图。
(2)Fuse融合
    融合两个不同的特征图,然后将它们通过全局平均池化的方式提取出每一个通道的融合值。再通过线性层进行通过压缩,这里和Se-net的通道注意力是一样的。
(3)Select选择
    在通过一个Softmax层进行选择,后续的操作和Se-net是一样的,得到通过挑选的特征图。这里的特征图可以看到每一个通道所使用的卷积核是不一样的,也是通过学习得到的。

(五)SK-net网络代码实现
    在网络里主要有①获得不同的卷积块②全局平均池化层③线性层④softmax层。所以在super函数里主要就是对这几个部分进行初始化。同时因为卷积块可以有多个不只有两个,线性层的压缩量等参数都可以自己设定,所以也需要初始化。这里的d就是线性层压缩后的通道数量,M是采用的卷积块个数,首先要初始化卷积不同的卷积块,再定义全局平均池化,再定义几个线性层和softmax函数,注意每一层的输入输出值。

d = max(in_channels//r, L)
self.M = M
self.out_channels = out_channels
self.conv = nn.ModuleList()
for i in range(M):
    self.conv.append(nn.Sequential(nn.Conv2d(in_channels, out_channels, 3, stride, padding=1+i, dilation=1+i, groups=32, bias=False),
                                   nn.BatchNorm2d(out_channels),
                                   nn.ReLU(inplace=True)))
self.global_pool = nn.AdaptiveAvgPool2d(output_size=1)
self.fc1 = nn.Sequential(nn.Conv2d(out_channels, d, 1, bias=False),
                           nn.BatchNorm2d(d),
                           nn.ReLU(inplace=True))
self.fc2 = nn.Conv2d(d, out_channels*M, 1, 1, bias=False)
self.softmax = nn.Softmax(dim=1)

    在前馈函数里,首先需要执行split的过程,使用reduce将对初始特征图采用不同卷积块卷积后的特征图进行相加。然后全局池化,之后进行两个线性层,再通过softmax,后续操作和Se-net相同,注意一下每一层的参数,和怎么进行拼贴等问题就行了。

def forward(self, input):
    batch_size = input.size(0)
    output = []

    for i, conv in enumerate(self.conv):
        output.append(conv(input))
    U = reduce(lambda x, y:x+y, output)

    s = self.global_pool(U)
    z = self.fc1(s)
    a_b = self.fc2(z)
    a_b = a_b.reshape(batch_size,self.M,self.out_channels,-1)
    a_b = self.softmax(a_b)

    a_b = list(a_b.chunk(self.M,dim=1))
    a_b = list(map(lambda x:x.reshape(batch_size,self.out_channels,1,1),a_b))
    V = list(map(lambda x,y:x*y,output,a_b))
    V = reduce(lambda x,y:x+y,V)
    return V

    SK-net网络和Se-net网络其实是一样的不能称作一个完整的网络,它可以是一个增加模块嵌入到一些网络中,SK-net也可以嵌入和Resnet中进行补强,嵌入和方法和Se-net类似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值