Algoritmo de visão computacional - Detecção de alvo baseada em transformador (DETR / DETRable Deformable / DETR 3D)

Algoritmo de visão computacional - Detecção de alvo baseada em transformador (DETR / DETRable Deformable / DETR 3D)

DETR é a abreviação de DEtection TRansformer. Este método foi publicado no ECCV em 2020. O artigo original foi intitulado "End-to-End Object Detection with Transformers".

A detecção de alvo tradicional é baseada nos métodos Proposta, Âncora ou Nenhuma Âncora e requer pelo menos supressão não máxima para pós-processar os resultados da saída da rede, que envolve um processo complexo de ajuste de parâmetros. O DETR usa a estrutura Transformer Encoder-Decoder e realiza um verdadeiro método de detecção de ponta a ponta por meio da perda de previsão coletiva . Como o Transformer Encoder-Decoder é implementado? Qual é a perda de previsão do conjunto? Os detalhes serão dados posteriormente.

Os alunos que não estão muito familiarizados com a direção da detecção de alvos podem consultar o algoritmo de visão computacional - resumo da rede de detecção de alvos .

1. DETR

A estrutura da rede DETR é mostrada na figura abaixo:
insira a descrição da imagem aqui
Primeiro, o primeiro passo é extrair recursos da imagem de entrada por meio de uma CNN e, em seguida, endireitar o mapa de recursos no Transformer Encoder-Decoder. A parte do Transformer Encoder da segunda etapa é fazer com que a rede aprenda melhor os recursos globais; a terceira etapa usa o Transformer Decoder e o Object Query para aprender o objeto a ser detectado a partir dos recursos; a quarta etapa é comparar os resultados do Object Query com a correspondência do gráfico bipartido do valor real (perda de conjunto para conjunto) e, finalmente, calcule a perda de classificação e a perda de regressão de posição nos resultados correspondentes.

O descrito acima é o processo básico de treinamento. A única diferença no processo de raciocínio está na quarta etapa. Na quarta etapa, o resultado final da detecção é gerado definindo um valor limite para a consulta de objeto. Esse resultado não precisa de nenhuma postagem -processing, mas é usado diretamente como saída final.

Abaixo combinamos o código para expandir os detalhes do Transformer Encoder-Decoder e Set-to-Set Loss:

1.1 Transformador Codificador-Decodificador

A estrutura do Codificador-Decodificador do Transformer é mostrada na figura abaixo, onde o comentário vermelho é a entrada é 3 × 800 × 1066 3\times 800\times 10663×800×Após a imagem de tamanho 1066 , o tamanho do recurso de cada etapa.
insira a descrição da imagem aqui
A função de encaminhamento do Transformer Encoder-Decoder é a seguinte:

def forward(self, src, mask, query_embed, pos_embed):
        # flatten NxCxHxW to HWxNxC
        bs, c, h, w = src.shape
        src = src.flatten(2).permute(2, 0, 1)
        pos_embed = pos_embed.flatten(2).permute(2, 0, 1)
        query_embed = query_embed.unsqueeze(1).repeat(1, bs, 1)
        mask = mask.flatten(1)

        tgt = torch.zeros_like(query_embed)
        memory = self.encoder(src, src_key_padding_mask=mask, pos=pos_embed)
        hs = self.decoder(tgt, memory, memory_key_padding_mask=mask,
                          pos=pos_embed, query_pos=query_embed)
        return hs.transpose(1, 2), memory.permute(1, 2, 0).view(bs, c, h, w)

Entre eles ,
src é o recurso extraído pelo Backbone, que precisa ser nivelado antes de ser inserido no Codificador;
pos_embed é o código de posição, que é um código de posição com um valor fixo no DETR. Para obter detalhes, consulte a introdução em 1.3 abaixo ;
query_embed é um código de posição apreensível, ou seja, a consulta de objeto mencionada acima, sua função no decodificador é fazer atenção cruzada continuamente por meio do recurso e query_embed após o codificador, e cada dimensão do query_embed é a saída de um resultado de detecção ; a máscara
é DETR Para ser compatível com diferentes imagens de resolução como entrada, diferentes imagens serão Zero Padding em uma resolução fixa durante a entrada. A parte Zero Padding não contém nenhuma informação, portanto não pode ser usada para calcular Atenção, então o autor reserva a parte de Zero Padding aqui. Digite src_key_padding_mask.

A parte do Codificador-Decodificador a seguir é quase a mesma que em "Atenção é tudo que você precisa". A estrutura da camada do Codificador é mostrada na figura abaixo: o
insira a descrição da imagem aquicódigo é o seguinte:

def forward_post(self,
                 src,
                 src_mask: Optional[Tensor] = None,
                 src_key_padding_mask: Optional[Tensor] = None,
                 pos: Optional[Tensor] = None):
    q = k = self.with_pos_embed(src, pos)
    src2 = self.self_attn(q, k, value=src, attn_mask=src_mask,
                          key_padding_mask=src_key_padding_mask)[0]
    src = src + self.dropout1(src2)
    src = self.norm1(src)
    src2 = self.linear2(self.dropout(self.activation(self.linear1(src))))
    src = src + self.dropout2(src2)
    src = self.norm2(src)
    return src

A estrutura do Decoder é mostrada na figura abaixo:
insira a descrição da imagem aquio código é o seguinte:

def forward_post(self, tgt, memory,
                 tgt_mask: Optional[Tensor] = None,
                 memory_mask: Optional[Tensor] = None,
                 tgt_key_padding_mask: Optional[Tensor] = None,
                 memory_key_padding_mask: Optional[Tensor] = None,
                 pos: Optional[Tensor] = None,
                 query_pos: Optional[Tensor] = None):
    q = k = self.with_pos_embed(tgt, query_pos)
    tgt2 = self.self_attn(q, k, value=tgt, attn_mask=tgt_mask,
                          key_padding_mask=tgt_key_padding_mask)[0]
    tgt = tgt + self.dropout1(tgt2)
    tgt = self.norm1(tgt)
    tgt2 = self.multihead_attn(query=self.with_pos_embed(tgt, query_pos),
                               key=self.with_pos_embed(memory, pos),
                               value=memory, attn_mask=memory_mask,
                               key_padding_mask=memory_key_padding_mask)[0]
    tgt = tgt + self.dropout2(tgt2)
    tgt = self.norm2(tgt)
    tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt))))
    tgt = tgt + self.dropout3(tgt2)
    tgt = self.norm3(tgt)
    return tgt

Aqui um detalhe, Exceto pela primeira camada, query_embed precisa fazer uma Auto Atenção antes de fazer Atenção Cruzada, cada Consulta de Auto Atenção entende a informação dominada por outra Consulta.

Em conclusão, quais são os benefícios do Transformer Encoder-Decoder?
Acho que o Transformer Encoder-Decoder deve ser um dos motivos do sucesso do Set-to-Set . a rede não era forte o suficiente, não funcionou muito bem. O Transformer Encoder-Decoder aprende os recursos globais, o que pode fazer com que um dos recursos interaja com outros recursos no global, e a rede pode saber com mais clareza onde está um objeto, onde está outro objeto, um objeto deve corresponder a uma saída , que está mais de acordo com a suposição de Set-to-Set.

1.2 Perda Set-to-Set

A chamada Perda Set-to-Set é o processo de adicionar um processo de correspondência de gráfico bipartido antes de calcular a perda da rede, de modo que o resultado final da previsão calcule apenas a perda com o valor verdadeiro correspondente, conforme mostrado na seguinte fórmula: σ ^ = arg ⁡ min ⁡ σ ∈ SN ∑ i NL match ⁡ ( yi , y ^ σ ( i ) ) \hat{\sigma}=\underset{\sigma \in \mathfrak{S}_{N}}{\ arg \min } \sum_{i }^{N} \mathcal{L}_{\operatorname{match}}\left(y_{i}, \hat{y}_{\sigma(i)}\right)p^=σ Snar gmineuneupartida( yeu,y^σ ( i )) dos quaisyi y_{i}yeué verdadeiro, y ^ σ ( i ) \hat{y}_{\sigma(i)}y^σ ( i )é o valor previsto, L match ⁡ \mathcal{L}_{\operatorname{match}}eupartidaPara o algoritmo de correspondência de gráfico bipartido, os alunos que não estão familiarizados com a correspondência de gráfico bipartido podem consultar a introdução em Visual SLAM Summary - SuperPoint / SuperGlue . A diferença é que a função linear_sum_assignment na biblioteca scipy é chamada na implementação do código DETR código. A entrada da função A M × NM\vezes NM×Matriz de custo de tamanho N pode calcularMMM eNNA relação de correspondência entre N , a matriz Custo no DETR é composta pela perda de classificaçãop ^ σ ( i ) ( ci ) \hat{p}_{\sigma(i)}\left(c_{i}\right)p^σ ( i )( ceu) e Box损失L box ( bi , b ^ σ ( i ) ) \mathcal{L}_{\mathrm{box}}\left(b_{i}, \hat{b}_{\sigma(i)} \certo)eucaixa( beu,b^σ ( i )) consiste em duas partes, a perda de classificação é a probabilidade de Softmax negativo e a perda de caixa é a perda de L1 e a perda de IOU generalizada. As duas partes são as seguintes:

def forward(self, outputs, targets):
        """ Performs the matching

        Params:
            outputs: This is a dict that contains at least these entries:
                 "pred_logits": Tensor of dim [batch_size, num_queries, num_classes] with the classification logits
                 "pred_boxes": Tensor of dim [batch_size, num_queries, 4] with the predicted box coordinates

            targets: This is a list of targets (len(targets) = batch_size), where each target is a dict containing:
                 "labels": Tensor of dim [num_target_boxes] (where num_target_boxes is the number of ground-truth
                           objects in the target) containing the class labels
                 "boxes": Tensor of dim [num_target_boxes, 4] containing the target box coordinates

        Returns:
            A list of size batch_size, containing tuples of (index_i, index_j) where:
                - index_i is the indices of the selected predictions (in order)
                - index_j is the indices of the corresponding selected targets (in order)
            For each batch element, it holds:
                len(index_i) = len(index_j) = min(num_queries, num_target_boxes)
        """
        bs, num_queries = outputs["pred_logits"].shape[:2]

        # We flatten to compute the cost matrices in a batch
        out_prob = outputs["pred_logits"].flatten(0, 1).softmax(-1)  # [batch_size * num_queries, num_classes]
        out_bbox = outputs["pred_boxes"].flatten(0, 1)  # [batch_size * num_queries, 4]

        # Also concat the target labels and boxes
        tgt_ids = torch.cat([v["labels"] for v in targets])
        tgt_bbox = torch.cat([v["boxes"] for v in targets])

        # Compute the classification cost. Contrary to the loss, we don't use the NLL,
        # but approximate it in 1 - proba[target class].
        # The 1 is a constant that doesn't change the matching, it can be ommitted.
        cost_class = -out_prob[:, tgt_ids]

        # Compute the L1 cost between boxes
        cost_bbox = torch.cdist(out_bbox, tgt_bbox, p=1)

        # Compute the giou cost betwen boxes
        cost_giou = -generalized_box_iou(box_cxcywh_to_xyxy(out_bbox), box_cxcywh_to_xyxy(tgt_bbox))

        # Final cost matrix
        C = self.cost_bbox * cost_bbox + self.cost_class * cost_class + self.cost_giou * cost_giou
        C = C.view(bs, num_queries, -1).cpu()

        sizes = [len(v["boxes"]) for v in targets]
        indices = [linear_sum_assignment(c[i]) for i, c in enumerate(C.split(sizes, -1))]
        return [(torch.as_tensor(i, dtype=torch.int64), torch.as_tensor(j, dtype=torch.int64)) for i, j in indices]

Depois de obter o resultado correspondente σ ^ \hat{\sigma}p^ De acordo com a equação:L Húngaro ( y , y ^ ) = ∑ i = 1 N [ − log ⁡ p ^ σ ^ ( i ) ( ci ) + 1 { ci ≠ ∅ } L caixa ( bi , b ^ σ ^ ( i ) ) ] \mathcal{L}_{\text {húngaro}}(y, \hat{y})=\sum_{i=1}^{N}\left[-\log \hat{ p} _{\hat{\sigma}(i)}\left(c_{i}\right)+\mathbb{1}_{\left\{c_{i}\right\varnothing\right\}}\ mathcal{ L}_{\mathrm{box}}\left(b_{i}, \hat{b}_{\hat{\sigma}}(i)\right)\right]euHúngaro ( s ,y^)=eu = 1n[ -pouco tempop^p^ (eu)( ceu)+1{ ceu= }eucaixa( beu,b^p^( i ) ) ] é ligeiramente diferente da perda usada no processo de correspondência. A perda de classificação aqui usa a perda geral de entropia cruzada. Por que existe essa diferença? O artigo parece não mencioná-la. Conforme mencionado acima, o processo de correspondência binária ocorre apenas durante o processo de treinamento e o resultado final da saída é obtido passando diretamente o resultado da saída da rede por um limite durante o processo de teste.

1.3 Incorporação Posicional

O Positional Embedding no DETR é um valor fixo. O código do Positional Embedding é o seguinte. Vamos analisá-lo brevemente:

class PositionEmbeddingSine(nn.Module):
    """
    This is a more standard version of the position embedding, very similar to the one
    used by the Attention is all you need paper, generalized to work on images.
    """
    def __init__(self, num_pos_feats=64, temperature=10000, normalize=False, scale=None):
        super().__init__()
        self.num_pos_feats = num_pos_feats
        self.temperature = temperature
        self.normalize = normalize
        if scale is not None and normalize is False:
            raise ValueError("normalize should be True if scale is passed")
        if scale is None:
            scale = 2 * math.pi
        self.scale = scale

    def forward(self, tensor_list: NestedTensor):
        x = tensor_list.tensors
        mask = tensor_list.mask
        assert mask is not None
        not_mask = ~mask
        y_embed = not_mask.cumsum(1, dtype=torch.float32)
        x_embed = not_mask.cumsum(2, dtype=torch.float32)
        if self.normalize:
            eps = 1e-6
            y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale
            x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale

        dim_t = torch.arange(self.num_pos_feats, dtype=torch.float32, device=x.device)
        dim_t = self.temperature ** (2 * (dim_t // 2) / self.num_pos_feats)

        pos_x = x_embed[:, :, :, None] / dim_t
        pos_y = y_embed[:, :, :, None] / dim_t
        pos_x = torch.stack((pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4).flatten(3)
        pos_y = torch.stack((pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4).flatten(3)
        pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2)
        return pos

Para fazer com que a rede perceba as informações de localização de diferentes entradas, a maneira mais intuitiva é atribuir 1 1 ao primeiro Recurso1 , a segunda atribuição de recursos2 22 , mas esse método de atribuição não é amigável para entradas maiores, então alguém propõe usar a função seno para controlar o valor em− 1 -11 e1 11 , mas a função seno é periódica, o que pode ocasionar o mesmo valor em posições diferentes.

Assim, o autor estendeu a função seno para ddd- vetor dimensional, diferentes canais possuem diferentes comprimentos de onda, como segue:
PE ( pos , 2 i ) = sin ⁡ ( pos / 1000 0 2 i / d model ) P E_{(pos, 2 i)}=\sin \left (pos / 10000^{2 i / d_{\texto {modelo}}}\direita)P E( pos , 2 i ) _=pecado( p os /1000 02i / d _modelo ) PE ( pos , 2 i + 1 ) = cos ⁡ ( pos / 1000 0 2 i / d modelo ) P E_{(\text {pos }, 2 i+1)}=\cos \left(pos / 10000^ {2 i / d_{\texto {modelo}}}\direita)P E( pos  , 2 i + 1 )=porque( p os /1000 02i / d _modelo ) dos quaisiii é o número de canais, por exemplo, definimosd = 6 d=6d=6N : i = [1, 2, 3, 4, 5, 6] {i}=[1,2,3,4,5,6]eu=[ 1 ,2 ,3 ,4 ,5 ,6 ] wi = [1 1000 0 1/6, 1 1000 0 2/6, 1 1000 0 3/6, 1 1000 0 4/6, 1 1000 0 5/6, 1 1000 0 6/6] w_i=\ esquerda[\frac{1}{10000^{1 / 6}}, \frac{1}{10000^{2 / 6}}, \frac{1}{10000^{3 / 6}}, \frac{ 1}{10000^{4 / 6}}, \frac{1}{10000^{5 / ​​6}}, \frac{1}{10000^{6 / 6}}\direita]ceu=[1000 01/61,1000 02/61,1000 03/61,1000 04/61,1000 05/61,1000 06/61]P oision = 2 Poision = 2P oi s i n o _=2时,得到: Codificação de posição = [ sin ⁡ ( 2 w 0 ) , cos ⁡ ( 2 w 1 ) , sin ⁡ ( 2 w 2 ) , cos ⁡ ( 2 w 3 ) , sin ⁡ ( 2 w 4 ) , cos ⁡ ( 2 w 5 ) ] Codificação de posição=\esquerda[\sen \esquerda(2 w_{0}\direita), \cos \esquerda(2 w_{1}\direita), \sin \esquerda(2 w_ {2}\direita), \cos \left(2 w_{3}\direita), \sin \left(2 w_{4}\direita), \cos \left(2 w_{5}\direita)\direita ]Codificação de posição _ _ _ _ _ _ _ _ _ _=[ pecado( 2 w0),porque( 2 w1),pecado( 2 w2),porque( 2 w3),pecado( 2 w4),porque( 2 w5) ] Um vetor multidimensional obtido desta formaé difícil de ser o mesmo em diferentes posições, então o efeito de codificação de diferentes posições é alcançado.

Depois que o DETR foi apresentado, ele rapidamente atraiu a atenção de todos com sua estrutura simples. O próprio DETR também tem muitos problemas, como a velocidade de convergência de treinamento não é rápida o suficiente, o resultado não é SOTA suficiente e o efeito de detecção em objetos pequenos é ruim , então existem muitos outros problemas. Algoritmos relacionados ao DETR, como DETRable Deformable, Anchor DETR, etc., bem como DETR3D aplicado ao campo de direção autônoma, etc., aqui eu resumi brevemente alguns dos algoritmos.

2. DETR deformável

O DETR deformável resolve principalmente os problemas de baixa velocidade de treinamento do DETR original e efeito de detecção ruim em objetos pequenos . A lenta velocidade de convergência do DETR se deve principalmente ao processo de treinamento demorado do Mapa de Atenção, da distribuição uniforme à distribuição esparsa, e o efeito de detecção ruim para objetos pequenos ocorre principalmente porque o Backbone não possui recursos multiescala, mas mesmo se existem, não é realista inserir recursos multiescala no Transformer , porque a complexidade computacional do Transformer é O ( n 2 ) O(n^2)O ( n2 ), os recursos de alta resolução trarão grande consumo de memória e tempo.

Para isso, o Deformable DETR propõe o módulo Defomer Attention, que resolve bem os problemas acima.

2.1 Módulo de Atenção Deformável

O autor introduziu pela primeira vez a fórmula do mecanismo de atenção multicabeçal no Transformer original no artigo:  MultiHeadAttn ( zq , x ) = ∑ m = 1 MW m [ ∑ k ∈ Ω k A mqk ⋅ W m ′ xk ] \text { MultiHeadAttn }\ left(z_{q}, x\right)=\sum_{m=1}^{M} W_{m}\left[\sum_{k \in \Omega_{k}} A_{mqk} \cdot W_{ m}^{\prime} x_{k}\direita] MultiHeadAttn ( zq,x )=m = 1mCm[k ΩkAm q kCmxk] É a mesma fórmula que costumamos ver, mas a expressão é um pouco diferente. ondezq , x z_{q}, xzq,x são dois conjuntos de vetores para Atenção,V mx V_{m} xVmx得到Key Embedding,U mzq U_{m} z_{q}vocêmzqObter incorporação de consulta, A mqk A_{mqk}Am q kO peso é obtido pela normalização após a multiplicação de pontos de Query Embedding e Key Embedding, que é proporcional a exp ⁡ { zq TU m TV mxk C v } \exp \left\{\frac{z_{q}^{T} U_ {m} ^{T} V_{m} x_{k}}{\sqrt{C_{v}}}\direita\}exp{ Cv zqTvocêmTVmxk}W m ′ xk W_{m}^{\prime} x_{k}Cmxk为 Incorporação de valor, W m W_{m}CmEle é responsável por agregar os resultados multi-head após o Concate. onde U m , V m , W m ′ , W m U_{m}, V_{m}, W_{m}^{\prime}, W_{m}vocêm,Vm,Cm,Cmsão os parâmetros aprendidos. No DETR, esse mecanismo de atenção multicabeça original é aplicado à autoatenção do codificador e à atenção cruzada do decodificador.

Em seguida, o autor introduziu o princípio do Módulo de Atenção Deformável, cuja fórmula de expressão é: DeformAttn ⁡ ( zq , pq , x ) = ∑ m = 1 MW m [ ∑ k = 1 KA mqk ⋅ W m ′ x ( pq + Δ pmqk ) ] \operatorname{DeformAttn}\left(\boldsymbol{z}_{q}, \boldsymbol{p}_{q}, \boldsymbol{x}\right)=\sum_{m=1}^{M} \boldsymbol {W}_{m}\left[\sum_{k=1}^{K} A_{mqk} \cdot \boldsymbol{W}_{m}^{\prime} \boldsymbol{x}\left (\ boldsymbol{p}_{q}+\Delta \boldsymbol{p}_{mqk}\direita)\direita]DeformAttn( zq,pq,x )=m = 1mCm[k = 1KAm q kCmx( pq+p_ _m q k) ] ondeδ pmqk \delta p_{mqk}p_ _m q ké o deslocamento de posição obtido de Query Embedding e A mqk A_{mqk} na fórmulaAm q kNão é mais o peso obtido através do produto escalar do Query Embedding e Key Embedding, mas sim o peso obtido diretamente do Query Embedding. Este processo pode ser entendido através da figura a seguir:
insira a descrição da imagem aqui
:

  1. O mecanismo de atenção multicabeçal usado no DETR usa recursos globais como o valor da chave, enquanto a atenção deformável está próxima a cada consulta e seleciona independentemente KK por meio da incorporação de consultasK valores-chave;
  2. O mecanismo de atenção multi-head usado no DETR obtém pesos através do produto interno de Key Embedding e Query Embedding, enquanto Deformable Attention é obtido diretamente de Query Embedding através de uma camada linear.

São também as duas diferenças acima que tornam a Atenção Deformável mais eficiente do que o mecanismo de Atenção original . Além disso, Atenção Deformável e Convolução Deformável também são diferentes.Atenção Deformável é prever diretamente vários deslocamentos em um ponto na posição da Consulta, enquanto a Convolução Deformável é prever um viés para cada pixel no kernel da convolução.

Com base no Módulo de Atenção Deformável, o autor propôs ainda o Módulo de Atenção Deformável em Multiescala, a fórmula é a seguinte: MSDeformAttn ⁡ ( zq , p ^ q , { xl } l = 1 L ) = ∑ m = 1 MW m [ ∑ l = 1 L ∑ k = 1 KA mlqk ⋅ W m ′ xl ( ϕ l ( p ^ q ) + Δ pmlqk ) ] \operatorname{MSDeformAttn}\left(z_{q}, \hat{\boldsymbol{p}} _{ q},\esquerda\{x^{l}\direita\}_{l=1}^{L}\direita)=\sum_{m=1}^{M} W_{m}\esquerda[ \sum_ {l=1}^{L} \sum_{k=1}^{K} A_{mlqk} \cdot \boldsymbol{W}_{m}^{\prime} \boldsymbol{x}^{l }\ left(\phi_{l}\left(\hat{\boldsymbol{p}}_{q}\right)+\Delta \boldsymbol{p}_{mlqk}\right)\right]MSDeformAttn( zq,p^q,{ xeu }l = 1L)=m = 1mCm[l = 1Lk = 1KAm lq kCmxeu( ϕeu(p^q)+p_ _m lq k) ] Comparado com o Módulo de Atenção Deformável, a principal diferença é que o Módulo de Atenção Deformável amostraKKPosições K , enquanto o Módulo de Atenção Deformável Multiescala é daLLCada camada da camada L amostra KKK posições, totalLK LKL K posições de amostragem. Dessa forma, a rede realiza a fusão de recursos multiescalaa um custo pequeno.

2.2 Codificador-Decodificador do Transformador Deformável

A estrutura do Codificador-Decodificador do Transformador Deformável é mostrada na figura abaixo:
insira a descrição da imagem aqui
No Codificador , o autor substitui todos os Módulos de Auto-Atenção por Módulos de Atenção Deformáveis, e a entrada e saída de cada Codificador são mapas de recursos multiescala de mesma resolução. O mapa de recursos multiescala vem diretamente dos últimos três estágios do ResNet. Conforme mostrado na figura abaixo:
insira a descrição da imagem aqui
Além disso, com base na retenção da incorporação posicional, é adicionada uma incorporação de nível de escala que pode ser aprendida relacionada ao número de camadas de feição.

No Decoder , o autor mantém a auto-atenção inalterada e substitui a atenção cruzada pela atenção deformável. Para cada incorporação de consulta de objeto, a camada linear e o sigmóide aprendem seu ponto de referência correspondente e consultam a saída de recursos do codificador. A incorporação de valor correspondente é obtida , e finalmente a soma ponderada é realizada com base nos pesos aprendidos pela camada linear e Softmax. Quando li isso pela primeira vez, tive uma pergunta: Object Query Embedding é um valor predefinido, se a posição e o peso do ponto de referência forem inferidos a partir de Object Query Embedding (no DETR, todos eles estão associados ao Encoder Feature obtido), como podemos garantir que o alvo de detecção está correto? Depois de pensar sobre isso com cuidado, o ponto de referência ou peso da primeira camada de Decode Layer pode realmente ser um valor fixo ou um valor aleatório, mas as informações do Encoder Feature já estão incluídas na saída Object Query Embedding pela primeira camada de Decode Layer A posição do ponto de referência gerado pelo Decoder Layer começará a se correlacionar com a imagem, e com a superposição do Decoder Layer, essa correlação ficará cada vez mais forte.

Além disso, um pouco diferente do DETR é que o Deformable DETR prevê que o Bounding Box não regride diretamente as coordenadas absolutas do Object Query, mas regride a distância ao ponto de referência, porque o peso e a posição do ponto de referência são todos do mesmo Object Query A incorporação é inferida, portanto, o método de regressão relativo ao ponto de referência pode acelerar a convergência .

2.3 Conclusão

O conhecimento sobre DETRable Deformable é muito mais do que os dois pontos resumidos acima neste artigo. O artigo DETRable Deformable também apresenta outras estruturas de rede, como DETR Defomable de dois estágios, e você pode ir mais fundo. Aqui, comparamos a melhoria do DETR Deformable relativo para DETR:
A seguir, uma comparação da velocidade de treinamento. A velocidade de convergência de treinamento do Deformable DETR melhorou muito:
insira a descrição da imagem aqui
Pela tabela abaixo, podemos ver que o Deformable melhorou muito na precisão da detecção de objetos pequenos: A
insira a descrição da imagem aqui
proposta do DETR baseia-se principalmente em seu fim-a-fim A estrutura de rede do terminal está fora do círculo, mas seu desempenho pode não ter atingido o SOTA naquele momento, mas com o suporte do Deformable DETR, esse tipo de método já pode competir com o método SOTA. Os resultados da comparação são os seguintes:
insira a descrição da imagem aqui

3. DETR3D

O DETR3D aplica o DETR ao campo da direção autônoma para realizar a detecção de objetos 3D sob a perspectiva da entrada multicâmera BEV, conforme mostrado na figura abaixo: seu princípio é muito semelhante insira a descrição da imagem aqui
ao transformador deformável mencionado acima. Vamos resumir brevemente o transformador em BEV O aplicativo sob a tarefa de perspectiva é como outra postagem de blog para aprender mais tarde.

O diagrama de estrutura da rede é mostrado na figura abaixo:
insira a descrição da imagem aqui
a rede primeiro extrai recursos multiescala para cada entrada de câmera por meio de ResNet e FPN, que é a parte de extração de recursos de imagem na figura. A entrada de recursos 2D para transformação de recursos 3D para estudo mais aprofundado, o que se segue é uma introdução detalhada a esta parte.

3.1 Transformador 2D para 3D

Para cada entrada de câmera, extraímos características de quatro escalas, que são registradas como F 1 , F 2 , F 3 , F 4 \mathcal{F}_{1}, \mathcal{F}_{2}, \mathcal{ F }_{3}, \mathcal{F}_{4}F1,F2,F3,F4, sob a configuração do papel, há um total de seis entradas de câmera: F k = { fk 1 , … , fk 6 } ⊂ RH × W × C \mathcal{F}_{k}=\left\{\ boldsymbol{f} _{k 1}, \ldots, \boldsymbol{f}_{k 6}\right\} \subset \mathbb{R}^{H \times W \times C}Fk={ fk 1,,fk 6}RA × L × C. _

No algoritmo DETR3D, não há parte do codificador baseado no Transfomer, mas os recursos de imagem extraídos acima são inseridos diretamente na parte do decodificador. Acho que o motivo deve ser que a parte do codificador tem muito cálculo e a parte do decodificador é a mesma que DETR ou DETR deformável. Atenção cruzada é realizada por meio da incorporação de consulta de objeto e do recurso de entrada e, em seguida, o objeto correspondente é retornado do saída final Object Query Embedding.No DETR3D, a maior diferença é a posição no espaço 3D da regressão, e a entrada é o recurso da imagem 2D, portanto, é necessário um decodificador de transformador 2D para 3D.

O Decodificador do DETR3D ainda é composto por Auto-Atenção e Atenção Cruzada. Os métodos em Auto-Atenção e DETR são basicamente os mesmos. A função principal é garantir que cada consulta saiba o que a outra está fazendo e evitar extração repetida do mesmos recursos. Atenção cruzada é bem diferente, vejamos as etapas específicas abaixo:

  1. Primeiro através de uma rede independente Φ ref \Phi^{\text {ref }}Phiref  retorna uma posição 3D do Object Query Embedding, que é um pouco semelhante à operação de Deformable DETR:c ℓ i = Φ ref ( q ℓ i ) \boldsymbol{c}_{\ell i}=\Phi^{\mathrm {ref}}\left(\boldsymbol{q}_{\ell i}\right)c eu=Phiref( q eu) ondec ℓ i \boldsymbol{c}_{\ell i}c eupode ser considerado como iiA posição central da i Box.
  2. Através dos parâmetros da câmera, a posição c ℓ i \boldsymbol{c}_{\ell i}c euProjete para o recurso de cada câmera para obter a posição 3D da caixa usada para incorporação de chave e incorporação de valor para refinar a previsão: c ℓ i ∗ = c ℓ i ⊕ 1 \boldsymbol{c}_{\ell i}^{* }= \boldsymbol{c}_{\ell i} \oplus 1ceu=c eu1 c ℓ mi = T mc ℓ i ∗ \boldsymbol{c}_{\ell mi}=T_{m} \boldsymbol{c}_{\ell i}^{*}c milhas=Tmceuonde T m T_{m}Tmé o parâmetro da câmera.
  3. Como cada entrada é um mapa de recursos multiescala, para evitar a influência de diferentes resoluções de recursos de escala, a interpolação bilinear é usada para interpolar o mapa de recursos e, se as coordenadas estiverem fora da imagem, preencha com zeros: f ℓ kmi = f bilinear ( F km , c ℓ mi ) \boldsymbol{f}_{\ell kmi}=f^{\text {bilinear }}\left(\mathcal{F}_{km}, \boldsymbol{c}_ {\ ell mi}\direita)f km=fbilinear ( Fkm,c milhas)
  4. Adicione os recursos acima e, finalmente, adicione-os ao Object Query Embedding para refinamento: f ℓ i = 1 ∑ k ∑ m σ ℓ kmi + ϵ ∑ k ∑ mf ℓ kmi σ ℓ kmi \boldsymbol{f}_{\ell i }= \frac{1}{\sum_{k} \sum_{m} \sigma_{\ell kmi}+\epsilon} \sum_{k} \sum_{m} \boldsymbol{f}_{\ell kmi} \sigma_ {\bem kmi}f eu=kmp km+ϵ1kmf kmp kmq ( ​​ℓ + 1 ) i = f ℓ i + q ℓ i \boldsymbol{q}_{(\ell+1) i}=\boldsymbol{f}_{\ell i}+\boldsymbol{q}_{ \bem eu}q( + 1 ) eu=f eu+q euAcho que este é realmente o passo equivalente ao somatório ponderado de atenção cruzada.No DETR, este passo é atualizar a consulta ponderando o valor de incorporação de valor multiplicando o peso de incorporação de consulta e incorporação de chave. Em Deformable, a etapa de Query Embedding e Key Embedding ponto de multiplicação é omitida, e o peso da regressão é realizado diretamente através do Query Embedding, e então o Value Embedding é ponderado. Aqui, o autor equivale a adicionar Value Embedding e Query Embedding , omitindo ainda mais a quantidade de cálculo. (Esta parte é minha conclusão com base na descrição do artigo e no resumo de outros blogs. Pode ser diferente da implementação do código. Se houver algum erro, por favor, indique ao leitor)
  5. Depois de iterar as operações acima muitas vezes, a categoria e a posição são finalmente regredidas da Incorporação de Consulta: b ^ ℓ i = Φ ℓ reg ( q ℓ i ) \hat{\boldsymbol{b}}_{\ell i}=\ Phi_ {\ell}^{\mathrm{reg}}\left(\boldsymbol{q}_{\ell i}\right)b^ eu=Phiregular( q eu) c ^ ℓ i = Φ ℓ cls ( q ℓ i ) \hat{c}_{\ell i}=\Phi_{\ell}^{\mathrm{cls}}\left(\boldsymbol{q}_{ \ bem i} \ certo)c^ eu=Phicls( q eu)

O acima é o entendimento da parte do decodificador DETR3D. Como não há tempo para ler o código-fonte, o entendimento pode não ser suficiente e muitos detalhes podem ser ignorados. Desde o Tesla AI Day no ano passado, todo mundo tem feito muita pesquisa sobre a aplicação do Transformer no campo da direção autônoma. Pretendo ir mais longe no futuro. Como associar recursos 2D em 3D é muito interessante.

O resumo relevante do DETR neste artigo está aqui por enquanto, e irei adicioná-lo mais tarde quando tiver tempo. Se você tiver alguma dúvida, dê conselhos e troque ~

Acho que você gosta

Origin blog.csdn.net/weixin_44580210/article/details/125951431
Recomendado
Clasificación