Detection Head
Uma cabeça de detecção é a parte final de um detector de objetos, que transforma os recursos do backbone e do neck em caixas e pontuações de classe em cada posição da grade.
Uma cabeça de deteção é o conjunto final de camadas de uma rede de deteção de objetos. Lê os mapas de características produzidos pelas camadas anteriores e gera, em cada localização candidata, uma caixa delimitadora e uma pontuação por classe. O seu design determina como as caixas são codificadas — como deslocamentos em relação a caixas âncora ou como distâncias a partir de um ponto —, quantas caixas candidatas o modelo produz e se uma etapa de pós-processamento, como a supressão não máxima (NMS), tem de eliminar duplicados.
Onde se encontra a cabeça#
Os detetores modernos são compostos por três etapas. Um backbone, geralmente uma rede convolucional ou um vision transformer, transforma os píxeis em mapas de características cuja resolução diminui e cujo conteúdo semântico aumenta com a profundidade. Um neck, como uma rede de pirâmide de características (FPN), combina mapas profundos e superficiais para que cada escala de saída contenha detalhes finos e contexto. A cabeça executa então pequenos ramos convolucionais em cada nível da pirâmide, normalmente com passos 8, 16 e 32, para que os mapas finos encontrem objetos pequenos e os mapas grosseiros encontrem objetos grandes.
Os detetores de estágio único têm uma única cabeça densa que faz previsões em cada célula da grelha. Os detetores de dois estágios, como o Faster R-CNN, têm duas: uma rede de propostas de regiões que classifica âncoras em cada localização e, em seguida, uma cabeça de região de interesse que classifica e refina as poucas centenas de regiões propostas.
Como uma cabeça prevê caixas e classes#
Em cada célula da grelha, uma cabeça densa prevê três tipos de valores:
- Pontuações de classe: Uma por classe, cada uma passando por uma função sigmoide para que uma localização possa pontuar cada classe de forma independente.
- Regressão de caixas: Quatro números que posicionam uma caixa: deslocamentos que movem e redimensionam uma caixa âncora ou as distâncias entre o centro da célula e as quatro bordas da caixa.
- Qualidade e saídas da tarefa: Uma pontuação de objetividade (YOLOv1 até YOLOv5) ou de centralidade (FCOS) que ordena as caixas, além de valores específicos da tarefa, como coeficientes de máscara para segmentação de instâncias ou pontos-chave para estimativa de pose.
A codificação das caixas distingue os detetores baseados em âncoras dos detetores sem âncoras. Cada ramo é composto por algumas convoluções que terminam numa convolução 1 × 1 com um canal de saída por valor previsto. O RetinaNet e o FCOS já usavam ramos separados de classificação e regressão, e o YOLOX introduziu esta cabeça desacoplada no YOLO em 2021, relatando uma convergência de treino muito mais rápida do que a camada de saída partilhada única do YOLOv3. O esquema abaixo constrói essas camadas finais 1 × 1 para os três níveis da pirâmide de uma imagem de 640 × 640 e transforma as respetivas saídas numa única lista de candidatos:
import torch
from torch import nn
# Neck outputs for a 640x640 image at strides 8, 16, and 32 (80x80, 40x40, and 20x20 grids)
channels = (64, 128, 256)
features = [torch.randn(1, c, 640 // s, 640 // s) for c, s in zip(channels, (8, 16, 32))]
# Decoupled head: a box branch (4 values) and a class branch (80 scores) for every pyramid level
box_branches = nn.ModuleList(nn.Conv2d(c, 4, 1) for c in channels)
cls_branches = nn.ModuleList(nn.Conv2d(c, 80, 1) for c in channels)
# Flatten each level's grid and concatenate, giving one candidate per grid cell
boxes = torch.cat([branch(f).flatten(2) for branch, f in zip(box_branches, features)], dim=2)
scores = torch.cat([branch(f).flatten(2) for branch, f in zip(cls_branches, features)], dim=2).sigmoid()
print(f"boxes {tuple(boxes.shape)}, class scores {tuple(scores.shape)}")Imprime boxes (1, 4, 8400), class scores (1, 80, 8400): cada uma das 6.400 + 1.600 + 400 células da grelha propõe uma caixa com 80 pontuações de classe.
Das saídas brutas às deteções#
O treino determina quantas previsões cada objeto recebe. A atribuição um-para-muitos marca várias células perto de cada objeto como positivas, dando à cabeça mais sinais de treino e deixando várias caixas sobrepostas por objeto durante a inferência; assim, a NMS mantém a melhor. A atribuição um-para-um, usada pelo DETR e pela cabeça de inferência do YOLOv10, treina exatamente uma previsão por objeto, pelo que as saídas não precisam de NMS.
A cabeça do YOLO26 prevê diretamente as distâncias às quatro bordas, eliminando a saída de 16 bins por borda da Perda Focal de Distribuição usada pelo YOLOv8 e pelo YOLO11, e treina uma cópia um-para-muitos e outra um-para-um de seus ramos de caixas delimitadoras e de classificação. Por padrão, o YOLO26 aplica NMS às saídas um-para-muitos, e passar nms=False ativa os ramos um-para-um, que retornam no máximo 300 caixas delimitadoras por imagem sem etapa de NMS.
Design da cabeça na prática#
- Ajuste fino para novas classes: O ramo de classes termina num canal de saída por classe; por isso, o treino com um conjunto de dados que tenha um número diferente de classes requer uma nova camada final de classificação, enquanto os pesos pré-treinados do backbone e do neck são mantidos.
- Implementação: Todas as operações da cabeça são executadas no dispositivo de destino, por isso a descodificação simples de caixas e as saídas sem NMS facilitam a exportação e reduzem o tempo de pós-processamento.
- Objetos pequenos: Adicionar um nível de pirâmide com passo 4 oferece à cabeça uma grelha mais fina para objetos minúsculos, com um custo computacional adicional: para uma entrada de 640 × 640, acrescenta 160 × 160 = 25.600 células, quatro vezes mais do que o nível com passo 8.










