首页 > 编程知识 正文

计算机网络五层体系,计算机网络五层模型

时间:2023-05-04 20:01:45 阅读:201574 作者:2197

论文地址:https://arxiv.org/abs/1903.06586
代码地址:https://github.com/implus/SKNet

SENet是对特征图的通道注意力机制的研究,之前的CBAM提到了对特征图空间注意力机制的研究。这里SKNet针对卷积核的注意力机制研究。
不同大小的感受视野(卷积核)对于不同尺度(远近、大小)的目标会有不同的效果。 尽管比如Inception这样的增加了多个卷积核来适应不同尺度图像,但是一旦训练完成后,参数就固定了,这样多尺度信息就会被全部使用了(每个卷积核的权重相同)。
SKNet提出了一种机制,即卷积核的重要性,即 不同的图像能够得到具有不同重要性的卷积核

SKNet对不同图像使用的卷积核权重不同,即一种针对不同尺度的图像动态生成卷积核。 整体结构如下图所示:

此图为GiantPandaCV公众号作者根据代码重画的网络图

网络主要由Split、Fuse、Select三部分组成。

Split 部分是对原特征图经过不同大小的卷积核部分进行卷积的过程,这里可以有多个分支。对输入X使用不同大小卷积核分别进行卷积操作(图中的卷积核size分别为3x3和5x5两个分支,但是可以有多个分支)。操作包括卷积、efficient grouped/depthwise convolutions、BN。

Fuse部分是计算每个卷积核权重的部分。将两部分的特征图按元素求和

U通过全局平均池化(GAP)生成通道统计信息。得到的Sc维度为C * 1

经过全连接生成紧凑的特征z(维度为d * 1), δ是RELU激活函数,B表示批标准化(BN),z的维度为卷积核的个数,W维度为d×C, d代表全连接后的特征维度,L在文中的值为32,r为压缩因子。



Select 部分是根据不同权重卷积核计算后得到的新的特征图的过程。
进行softmax计算每个卷积核的权重,计算方式如下图所示。如果是两个卷积核,则 ac + bc = 1。z的维度为(d * 1)A的维度为(C * d),B的维度为(C * d),则a = A x z的维度为1 * C。

Ac、Bc为A、B的第c行数据(1 * d)。ac为a的第c个元素,这样分别得到了每个卷积核的权重。

将权重应用到特征图上。其中V = [V1,V2,…,VC], Vc 维度为(H x W),如果

select中softmax部分可参考下图(3个卷积核)

基于pytorch的代码实现:

class SKConv(nn.Module): def __init__(self, features, WH, M, G, r, stride=1, L=32): """ Constructor Args: features: input channel dimensionality. WH: input spatial dimensionality, used for GAP kernel size. M: the number of branchs. G: num of convolution groups. r: the radio for compute d, the length of z. stride: stride, default 1. L: the minimum dim of the vector z in paper, default 32. """ super(SKConv, self).__init__() d = max(int(features / r), L) self.M = M self.features = features self.convs = nn.ModuleList([]) for i in range(M): # 使用不同kernel size的卷积 self.convs.append( nn.Sequential( nn.Conv2d(features, features, kernel_size=3 + i * 2, stride=stride, padding=1 + i, groups=G), nn.BatchNorm2d(features), nn.ReLU(inplace=False))) self.fc = nn.Linear(features, d) self.fcs = nn.ModuleList([]) for i in range(M): self.fcs.append(nn.Linear(d, features)) self.softmax = nn.Softmax(dim=1) def forward(self, x): for i, conv in enumerate(self.convs): fea = conv(x).unsqueeze_(dim=1) if i == 0: feas = fea else: feas = torch.cat([feas, fea], dim=1) fea_U = torch.sum(feas, dim=1) fea_s = fea_U.mean(-1).mean(-1) fea_z = self.fc(fea_s) for i, fc in enumerate(self.fcs): print(i, fea_z.shape) vector = fc(fea_z).unsqueeze_(dim=1) print(i, vector.shape) if i == 0: attention_vectors = vector else: attention_vectors = torch.cat([attention_vectors, vector], dim=1) attention_vectors = self.softmax(attention_vectors) attention_vectors = attention_vectors.unsqueeze(-1).unsqueeze(-1) fea_v = (feas * attention_vectors).sum(dim=1) return fea_v

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。