deformable detr中的sampling_offsets初始化grid_init方式

deformable detr中根据参考点预测4个采样点,采样点网络是

self.sampling_offsets = nn.Linear(
            embed_dims, num_heads * num_levels * num_points * 2)

它有个更新linear层偏置的过程

def init_weights(self):
    """Default initialization for Parameters of Module."""
    constant_init(self.sampling_offsets, 0.)
    thetas = torch.arange(self.num_heads, dtype=torch.float32) * (2.0 * math.pi / self.num_heads)
    grid_init = torch.stack([thetas.cos(), thetas.sin()], -1)
    grid_init = (grid_init / grid_init.abs().max(-1, keepdim=True)[0]).view(self.num_heads, 1, 1, 2).repeat(1,
                                                                                                            self.num_levels,
                                                                                                            self.num_points,
                                                                                                            1)
    for i in range(self.num_points):
        grid_init[:, :, i, :] *= i + 1

    self.sampling_offsets.bias.data = grid_init.view(-1)
    xavier_init(self.value_proj, distribution='uniform', bias=0.)
    self._is_init = True

这个bias起什么作用呢?经过调试,我发现它初始化后8个head的grid是[8,1,4,2],是这个样子

把它画在一个二维坐标系中后,8个head是这个样子

而sample point坐标=W*input+bias,W初始化为0~1之间的一个很小的数字,所以最终采样坐标很大程度上是bias起作用。那么意思就很明显了,这是想让8个头在以参考点为中心的8个射线方向上做采样。

取一组样本,经过如下前传过程,

sampling_offsets = self.sampling_offsets(query).view( sample offsets
            bs, num_query, self.num_heads, self.num_levels, self.num_points,

 输出为

 

画了几个head的采样点,如下:

 

 可以看到,黑色集中在y轴正向,红色集中在x轴正向,蓝色集中在y=x正向。

所以最终结论:采样偏移层的bias的作用就是为了让采样点更均匀的分布在参考点reference_points周围。

猜你喜欢

转载自blog.csdn.net/qq_42897796/article/details/127588009