最近在使用InsightFace_Pytorch-master pytorch工程,然后有使用到SE_ResNet50,所以想要分析相应的网络结构(包括网络层名和读取对应层相应参数)

了解什么叫做SE模块?

SE是Squeeze-and-Excitation(SE)的缩写,该模块的提出主要是考虑到模型通道之间的相互依赖性。SE网络的使用结构如下图所示:

回归问题 汤普森采样 回归中的se_回归问题 汤普森采样


上左图是将SE模块嵌入到Inception结构的一个示例。方框旁边的维度信息代表该层的输出。这里我们使用global average pooling作为Squeeze操作。紧接着两个Fully Connected 层组成一个Bottleneck结构去建模通道间的相关性,并输出和输入特征同样数目的权重。我们首先将特征维度降低到输入的1/16,然后经过ReLu激活后再通过一个Fully Connected 层升回到原来的维度。这样做比直接用一个Fully Connected层的好处在于:1)具有更多的非线性,可以更好地拟合通道间复杂的相关性;2)极大地减少了参数量和计算量。然后通过一个Sigmoid的门获得0~1之间归一化的权重,最后通过一个Scale的操作来将归一化后的权重加权到每个通道的特征上。

除此之外,SE模块还可以嵌入到含有skip-connections的模块中。上右图是将SE嵌入到 ResNet模块中的一个例子,操作过程基本和SE-Inception一样,只不过是在Addition前对分支上Residual的特征进行了特征重标定。如果对Addition后主支上的特征进行重标定,由于在主干上存在0~1的scale操作,在网络较深BP优化时就会在靠近输入层容易出现梯度消散的情况,导致模型难以优化。

目前大多数的主流网络都是基于这两种类似的单元通过repeat方式叠加来构造的。由此可见,SE模块可以嵌入到现在几乎所有的网络结构中。通过在原始网络结构的building block 单元中嵌入SE模块,我们可以获得不同种类的SENet 。如SE-BN-Inception、SE-ResNet 、SE-ReNeXt、SE-Inception-ResNet-v2等等。(摘录自:https://www.sohu.com/a/161793789_642762)

在工程中,打印出相应的网络结构,拿出其中bottleneck结构可以看到:

(4): bottleneck_IR_SE(
        (shortcut_layer): MaxPool2d(kernel_size=1, stride=1, padding=0, dilation=1, ceil_mode=False)
        (res_layer): Sequential(
          (0): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (2): PReLU(num_parameters=128)
          (3): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (4): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
          (5): SEModule(
            (avg_pool): AdaptiveAvgPool2d(output_size=1)
            (fc1): Conv2d(128, 8, kernel_size=(1, 1), stride=(1, 1), bias=False)
            (relu): ReLU(inplace)
            (fc2): Conv2d(8, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
            (sigmoid): Sigmoid()
          )
        )
      )

其中:

SEModule(
            (avg_pool): AdaptiveAvgPool2d(output_size=1)
            (fc1): Conv2d(128, 8, kernel_size=(1, 1), stride=(1, 1), bias=False)
            (relu): ReLU(inplace)
            (fc2): Conv2d(8, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
            (sigmoid): Sigmoid()
          )

就是在resnet中加入的se结构;

以上代码出自工程:InsightFace(https://github.com/TreB1eN/InsightFace_Pytorch)