Condational-DERT

deformable DERT 通过将计算稀疏化来成功实现减少计算量

但是conditional DERT 并没有那么做

作者们观察到在DERT中,内容潜入的贡献量远远大于空间迁入的贡献量

Our approach is motivated by high dependence on content embeddings and minor contributions made by the spatial embeddings in cross-attention. The empirical results in
DETR [3] show that if removing the positional embeddings in keys and the object queries from the second decoder layer and only using the content embeddings in keys and queries,
the detection AP drops slightly

内容嵌入与图像嵌入的不同:

内容嵌入(Content Embedding)

  • 本质:从图像特征图中提取的视觉语义信息(如物体的纹理、颜色、形状等)
  • 生成方式:CNN骨干网络提取特征 → Transformer编码器进一步提炼 → 得到编码器输出特征
  • 作用:判断"这是什么物体"(分类)和"物体的细节特征"(定位辅助)

空间嵌入(Spatial Embedding)

  • 本质:表示位置信息的坐标编码(与图像内容无关)
  • 生成方式:通过正弦函数将2D坐标转化为高维向量(类似原始Transformer的位置编码)
  • 作用:告诉模型"特征在图像中的位置"

Conditional Cross-Attention 条件交叉注意力

注意,下面的内容主要是用在 decoder 中的,conditional DERT 本身对于 DERT 的改良都是集中在 decoder 进行的。

在DERT中,内容嵌入和空间迁入(这里的迁入在原文中是 embedding,我们可以将其理解为是“信息”)是直接加到一起的,各自作为Q和K。所以二者的注意力权重的计算是:

(cq+pq)(ck+pk)=cqck+cqpk+pqck+pqpk=cqck+cqpk+oqck+oqpk\begin{aligned}& \left(c_{q} + p_{q}\right)^{\top}\left(c_{k} + p_{k}\right) \\= & c_{q}^{\top} c_{k} + c_{q}^{\top} p_{k} + p_{q}^{\top} c_{k} + p_{q}^{\top} p_{k} \\= & c_{q}^{\top} c_{k} + c_{q}^{\top} p_{k} + o_{q}^{\top} c_{k} + o_{q}^{\top} p_{k}\end{aligned}

为什么有两个 C 和 P?因为充当了不同的觉得、计算方式也不同。

而这篇文章提出的条件交叉注意力,是讲这两个矩阵拼接到了一起,没有相加:

q=[cqpq],k=[ckpk]q = \begin{bmatrix} c_q \\ p_q \end{bmatrix}, \quad k = \begin{bmatrix} c_k \\ p_k \end{bmatrix}

注意,是先后经过了线性层之后再进行的拼接。随后再进行点积,得到了这样的公式:

qk=[cqpq][ckpk]=cqck+pqpkq^\top k = \left[ c_q^\top \quad p_q^\top \right] \begin{bmatrix} c_k \\ p_k \end{bmatrix} = c_q^\top c_k + p_q^\top p_k

这就是再条件交叉注意力中新的注意力权重计算方法。这样做的好处是什么?文中解释道:

Different from the original DETR cross-attention, our mechanism separates the roles of content and spatial queries so that spatial and content queries focus on the spatial and
content attention weights, respectively.

简单翻译就是空间信息和内容信息相互独立地发挥着自己的作用,虽然最后还是加在了一起,但是重点是在计算相似度的时候,二者的分开的。


从前一个 decoder 的输出计算新的空间查询

空间查询是文章提出的新概念,它是相对于目标查询来说的

空间查询:pq and 目标查询:oq\text{空间查询:}p_q \text{ and 目标查询:}o_q

目标查询oqo_q

目标查询其实就是我们再原始的 DERT 中所说的 Q。用于在decoder 中参与多头交叉注意力的计算。Q 的大小是[N,bmodel][N,b_{model}],一般来说bmodelb_{model}的大小为 256(Transformer影响)。在最开始是随机生成的,到了后来就是 decoder 之间层层接力,每一层 decoder 的输出就是下一层 decoder 的 Q。同时有 N 个“锚点”(“参考点”),再论文中用 s 表示,一个 槽对应了一个 s 点,这是他们用来描述相对位置的参照。所有的 s 点再最开始的时候都是初始化为(0,0)的。

空间查询pqp_q

空间查询的给出其实还涉及到了一个新的创新点——动态参考点。

动态参考点计算方式一:可学习参数(Learnable Parameters)

  • 核心逻辑
    每个查询对象对应一组独立的可学习二维坐标s=(sx,sy)s = (s_x, s_y),在训练过程中通过梯度下降优化。
  • 实现细节
    • 初始化:随机初始化在[,+][-∞, +∞]范围内,通过sigmoid\text{sigmoid}函数映射到[0,1][0, 1]区间,对应图像归一化坐标。

    • 代码示例(PyTorch风格):

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      class ConditionalDETR(nn.Module):
      def __init__(self, num_queries=300, d_model=256):
      super().__init__()
      # 为每个查询对象创建独立的参考点参数
      self.reference_points = nn.Parameter(torch.randn(num_queries, 2))

      def forward(self, x):
      # 将参考点通过sigmoid归一化到[0,1]
      reference_points = torch.sigmoid(self.reference_points) # [num_queries, 2]
      # ...后续处理...

动态参考点计算方式二:目标查询生成(Object Query Generation)

  • 核心逻辑
    通过前馈网络(FFN)从目标查询oqo_q中动态预测参考点ss,公式为:

s=FFN(oq)s = \text{FFN}(o_q)

其中oqo_q是解码器的输入查询(维度为dmodeld_{\text{model}}),FFN通常包含线性层+ReLU+线性层。

  • 实现细节
    • 网络结构

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      class ReferencePointGenerator(nn.Module):
      def __init__(self, d_model=256):
      super().__init__()
      self.ffn = nn.Sequential(
      nn.Linear(d_model, d_model),
      nn.ReLU(),
      nn.Linear(d_model, 2) # 输出二维坐标(x,y)
      )

      def forward(self, object_query):
      # object_query: [batch_size, num_queries, d_model]
      s = self.ffn(object_query) # [batch_size, num_queries, 2]
      return s

    • 归一化处理
      预测的ss同样通过sigmoid\text{sigmoid}映射到[0,1][0, 1]

s^=(sigmoid(sx),sigmoid(sy)) \hat{s} = (\text{sigmoid}(s_x), \text{sigmoid}(s_y))

空间查询的计算

首先是是对每一个动态参考点 s 进行归一化,因为之前的两种计算 s 的方法都不能保证 s 的范围。

归一化完成之后,将每一个点映射到一个正弦位置编码中的一个向量。这样就可以形成一个二维矩阵,大小是[N,dmodel][N,d_{model}]

接下来针对每一个向量(也就是每一个 s),乘上各自的缩放因子λq\lambda_q

λq\lambda_q有两种计算方式:

  • 直接是一组可学习的参数
  • 通过λq=σ(fscale(pq))\lambda_q = \sigma(f_{\text{scale}}(p_q))来计算,其中fscalef_{\text{scale}}是一个将其输入映射成一个对角阵的映射函数,σ\sigma是激活函数

λq\lambda_q的本质可以看做是一个对角阵,这样两个矩阵相乘的话也是也就是给右边矩阵中的每一行进行矩阵数乘。

为什么要这样做?因为在 Conditional DETR 等模型中,查询向量pqp_q的生成通常包含两部分:

  • 参考点 s:表示目标的大致中心位置(由编码器特征或解码器动态生成)。
  • 缩放因子 λq\lambda_q:对参考点周围的空间范围进行缩放,形成最终的查询区域。
    数学上,假设初始查询区域为以 s 为中心的单位正方形(或固定范围),则缩放后的区域可表示为:调整后区域=s+λq基础偏移量\text{调整后区域} = s + \lambda_q \cdot \text{基础偏移量}
    其中,λq\lambda_q 越大,区域覆盖范围越大(对应大目标);λq\lambda_q 越小,区域越集中(对应小目标)。

原始DETRConditional DETRpq=oqpq=λqsinusoidal(sigmoid(s))q=cq+pqq=[cq;pq]Attention=(cq+pq)(ck+pk)Attention=cqck+pqpk\begin{array}{c|c}\text{原始DETR} & \text{Conditional DETR} \\p_q = o_q & p_q = \lambda_q \odot \text{sinusoidal}(\text{sigmoid}(s)) \\q = c_q + p_q & q = [c_q; p_q] \\\text{Attention} = (c_q + p_q)^\top (c_k + p_k) & \text{Attention} = c_q^\top c_k + p_q^\top p_k \\\end{array}

成功计算出pqp_q之后

接下来就是将pqp_q参与到条件交叉注意力的计算之中去。


总结

总的来看,conditional DERT 主要是通过对锚点 s 的灵活化来实现加速收敛

通过基于锚点生成的空间查询pqp_q进一步提高收敛速度——因为查询的位置和锚点的坐标更相关,而不是相互隔离,学习成本降低。同时也大大增加了模型的灵活性和自由度。

缩放因子λq\lambda_q的引入使得模型更能够聚焦于更小尺度的物体

Donate
  • Copyrights © 2015-2025 Xinyu Zhuang
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信