综述
非常容易理解,这个机制的诞生。既然有可形变卷积,且表现出不错的效果,自然就会产生可形变注意力机制。可形变卷积更多是卷积每一个部分的偏移,可形变注意力是patch的大小和整体位置的改变。从整体上说可形变注意力在算力上影响并不大,因为位置的预测基本上是和整体任务分离的(不全是比如人脸位置定位),patch位置和大小一般是由一个线性连接层直接得到。
另外一件事,纯注意力机制+可形变注意力并没有出现。
文章
patch的位置和大小其实是可形变注意力机制的核心问题。
目前看到的带有“自定义patch位置和大小的论文”有(未完待续):
- Stand-Alone Inter-Frame Attention in Video Models CVPR2022 动作识别中的一部分机制
- Vision Transformer with Deformable Attention CVPR2021 形变注意力机制
- DPT: Deformable Patch-based Transformer for Visual Recognition ACM MM 2021 形变注意力机制
- Deformable DETR: Deformable Transformers for End-to-End Object Detection ICLR2021 加速DETR训练
- Sparse Local Patch Transformer for Robust Face Alignment and Landmarks Inherent Relation Learning CVPR2022 定位人脸
代码
这一部分主要集中于可形变注意力机制的patch位置是怎么生成的:
DPT: Deformable Patch-based Transformer for Visual
内容部分
这篇文章的程序有几个特点:
- 可学习的位置和patch大小
- plug&play 在PVT结构上进行的逐层改变,计算量增加小
“DePatch can adjust the position and scale of each patch based on the input image”
代码部分
主体结构没有改变主要是patch_embed的方式不同
x, (H, W) = self.patch_embed2(x)
if isinstance(x, tuple):
aux_results.append(x[1])
x = x[0]
x = x + self.pos_embed2
x = self.pos_drop2(x)
for blk in self.block2:
x = blk(x, H, W)
x = x.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()
patch_embed方式,第一阶段不变形后三个阶段变形。box_coder是个函数,怎么裁剪patch指定的形状。
Simple_DePatch用来使用box_coder把每个patch裁剪成指定形状。
def _build_patch_embeds(embed_dims, img_size, Depatch):
patch_embeds=[]
for i in range(4):
inchans = embed_dims[i-1] if i>0 else 3
in_size = img_size // 2**(i+1) if i>0 else img_size
patch_size = 2 if i > 0 else 4
if Depatch[i]:
box_coder = pointwhCoder(input_size=in_size, patch_count=in_size//patch_size, weights=(1.,1.,1.,1.), pts=3, tanh=True, wh_bias=torch.tensor(5./3.).sqrt().log())
patch_embeds.append(
Simple_DePatch(box_coder, img_size=in_size, patch_size=patch_size, patch_pixel=3, patch_count=in_size//patch_size,
in_chans=inchans, embed_dim=embed_dims[i], another_linear=True, use_GE=True