见:D:\pythonCodes\深度学习实验\4.1_经典分类网络\inference代码汇总\models\se_resnet.py
一、SE-ResNet的实现方法
读了senet这篇论文之后,可以知道senet并没有提出一个新的网络,而是提出了一个即插即用的模块。这个模块叫做SE Block(在实现的时候,为了防止与SEBasicBlock这个名字混淆,叫做SELayer)。
本文希望实现se_resnet网络,也就是将SE Block嵌入到ResNet中形成的网络。se_resnet与resnet的差别就是,就是在BasicBlock(resnet18/34使用的是BasicBlock堆叠,而resnet50/101/152使用的是Bottleneck进行堆叠,这里就以BasicBlock举例,Bottleneck完全一样)中增加了SE Block这个操作。
比如下图,上面是BasicBlock的结构,下图就是SEBasic的结构,就是多出来了一个小圈圈。
通过读resnet的源码,我们知道是通过Resnet()这个类来组织成整个网络的。比如:
resnet34 = ResNet(BasicBlock, [3,4,6,3])
resnet18 = ResNet(BasicBlock, [2,2,2,2])
resnet50 = ResNet(Bottleneck, [3,4,6,3])
resnet101 = ResNet(Bottleneck, [3,4,23,3])
resnet152 = ResNet(Bottleneck, [3,8,36,3])
ResNet()接收两个参数,一个是block,另一个是堆叠的次数layers。只要传入参数,就能组织成一个网络了。比如传入的是BasicBlock,[3,4,6,3]就能得到resnet34了。这个函数就会自动地用3个BasicBlock组成layer1,用4个BasicBlock组成layer2,用6个BasicBlock组成layer3,用3个BasicBlock组成layer3,然后加上头尾等,组成一个网络。
我们可以利用ResNet()函数来构建我们的se_resent网络。只要给ResNet()传入SEBasicBlock和[3,4,6,3]就可以得到se_resnet34了。。
因此最关键的就是实现SEBasicBlock。而SEBasicBlock代码简直就是照抄BasicBlock代码,只要加上SELayer就行了。
(1) SELayer的实现
就是论文中的SE Block,在实现的时候,为了防止与SEBasicBlock这个名字混淆,叫做SELayer。
就是实现下面这个操作:
代码:
class SELayer(nn.Module):
def __init__(self, channel, reduction=16):
super(SELayer, self).__in