注意力机制大总结( 二 )



上述提到的所有方法致力于开发更复杂的注意力模块,以获得更好的性能,不可避免地增加了计算负担 。为了克服性能与复杂度权衡的悖论,就是一种用于提高深度CNNs性能的超轻注意模块 。ECA模块,它只涉及k (k=9)参数,但带来了明显的性能增益 。ECA模块通过分析SEnet的结构了解到降维和跨通道交互的影响,作者通过实验证明了降维是没有作用的(讲道理和我之前想的一样,,),并通过自适应内核大小的一维卷积实现局部跨通道的信息交互 。

注意力机制大总结

文章插图
class eca_layer(nn.Module):"""Constructs a ECA module.Args:channel: Number of channels of the input feature mapk_size: Adaptive selection of kernel size"""def __init__(self, channel, k_size=3):super(eca_layer, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.conv = nn.Conv1d(1, 1, kernel_size=k_size, padding=(k_size - 1) // 2, bias=False) self.sigmoid = nn.Sigmoid()def forward(self, x):# x: input features with shape [b, c, h, w]b, c, h, w = x.size()# feature descriptor on the global spatial informationy = self.avg_pool(x)# Two different branches of ECA moduley = self.conv(y.squeeze(-1).transpose(-1, -2))y = y.transpose(-1, -2).unsqueeze(-1)# Multi-scale information fusiony = self.sigmoid(y)return x * y.expand_as(x)
④CASR
注意力机制大总结

文章插图
进来一个特征 Hi,先经过卷积-ReLU-卷积得到特征 U,卷积核都为 3×3 。
CA 单元包含全局空间池化-卷积-ReLU-卷积-,卷积核都为 1×1,第一层卷积通道数变为 C/r,第二层卷积通道数为 C 。
SA 单元包含卷积-ReLU-卷积-,卷积核都为 1×1,第一层卷积通道数变为 C*i,第二层卷积通道数为 1 。
得到通道和空间的两个 mask 后,分别和特征 U 相乘,然后再将两个结果拼接起来经过一个 1×1 的卷积将通道数变为 C,最后和 Hi 相加得到输出特征 Ho 。
在论文中,作者设置 r=16,i=2,CSAR 的一个实现如下所示 。
【注意力机制大总结】def CSAR(input, reduction, increase):"""@Channel-wise and Spatial Feature Modulation Network for Single Image Super-ResolutionChannel-wise and spatial attention residual block"""_, width, height, channel = input.get_shape()# (B, W, H, C)u = tf.layers.conv2d(input, channel, 3, padding='same', activation=tf.nn.relu)# (B, W, H, C)u = tf.layers.conv2d(u, channel, 3, padding='same')# (B, W, H, C)# channel attentionx = tf.reduce_mean(u, axis=(1, 2), keepdims=True)# (B, 1, 1, C)x = tf.layers.conv2d(x, channel // reduction, 1, activation=tf.nn.relu)# (B, 1, 1, C // r)x = tf.layers.conv2d(x, channel, 1, activation=tf.nn.sigmoid)# (B, 1, 1, C)x = tf.multiply(u, x)# (B, W, H, C)# spatial attentiony = tf.layers.conv2d(u, channel * increase, 1, activation=tf.nn.relu)# (B, W, H, C * i)y = tf.layers.conv2d(y, 1, 1, activation=tf.nn.sigmoid)# (B, W, H, 1)y = tf.multiply(u, y)# (B, W, H, C)z = tf.concat([x, y], -1)z = tf.layers.conv2d(z, channel, 1, activation=tf.nn.relu)# (B, W, H, C)z = tf.add(input, z)return z