vision transformer是利用多头自注意力机制动态生成权重来混合空间标记(mix spatial tokens),但是自注意输入量的 quadratic complexity极大的阻碍了vision transformer的应用。为此hornet并不向此前方法一样降低自注意力的复杂度,而是通过卷积核全连接层等简单操作实现空间相互作用。
看下gnconv的代码段:
class gnconv(nn.Module):
def __init__(self, dim, order=5, gflayer=None, h=14, w=8, s=1.0):
super().__init__()
self.order = order
self.dims = [dim // 2 ** i for i in range(order)]
self.dims.reverse()
self.proj_in = nn.Conv2d(dim, 2*dim, 1)
if gflayer is None:
self.dwconv = get_dwconv(sum(self.dims), 7, True)
else:
self.dwconv = gflayer(sum(self.dims), h=h, w=w)
self.proj_out = nn.Conv2d(dim, dim, 1)
self.pws = nn.ModuleList(
[nn.Conv2d(self.dims[i], self.dims[i+1], 1) for i in range(order-1)]
)
self.scale = s
print('[gnconv]', order, 'order with dims=', self.dims, 'scale=%.4f'%self.scale)
def forward(self, x, mask=None, dummy=False):
B, C, H, W = x.shape
fused_x = self.proj_in(x)
pwa, abc = torch.split(fused_x, (self.dims[0], sum(self.dims)), dim=1)
dw_abc = self.dwconv(abc) * self.scale
dw_list = torch.split(dw_abc, self.dims, dim=1)
x = pwa * dw_list[0]
for i in range(self.order -1):
x = self.pws[i](x) * dw_list[i+1]
x = self.proj_out(x)
return x
hornet的结构在最左边,其中gnconv的作用是通过门控卷积和递归设计高效实现任意阶空间相互作用。
我们展示了执行不同交互顺序的代表性空间建模操作。本文重点研究特征(红色)与其邻近区域(浅灰色)之间的显式空间相互作用。(a)标准卷积运算没有明确考虑空间相互作用。(b)动态卷积[26,4]和SE[24]引入动态权值来提高带有额外空间相互作用的卷积的建模能力。©[51]自注意操作通过两个连续的矩阵乘法执行二阶空间相互作用。(d) gnConv通过门控卷积和递归设计高效实现任意阶空间相互作用。
普通卷积是(a),就是普通的CNN形式,可以看到没有空间作用关联;(b)是诸如SENet这种动态调整权值方法实现空间相互作用的结构;
(c)就是普通transformer的自注意力结构,(d)是本文提出方法。
不同于CNN卷积多采用3×3的小卷积,transformer采用更大的卷积如7×7的结构,这样更容易捕获长期依赖关系。
HorNet:采用7×7卷积;
global filter(GF):GF层[43]将频域特征与可学习的全局滤波器相乘,相当于一个具有全局核大小和圆形填充的空间域卷积。我们使用了GF层的改进版本,其中一半的通道使用全局过滤器处理,另一半使用3×3深度卷积处理,并且只在后期使用GF层来保留更多的局部细节。
提出的gnConv可以实现具有有界复杂度的任意阶交互。同样值得注意的是,与宽度[63]和深度[22]等深度模型中的其他缩放因子类似,单纯增加空间相互作用的阶数而不考虑模型的总体容量并不会得到很好的权衡[48]。本文在分析设计良好的模型的空间交互顺序的基础上,重点研究了一种更强的可视化建模体系结构。我们相信对高阶空间相互作用进行更全面、更正式的讨论将是未来的一个重要方向。