Posted in

Como o Vision Transformer (VIT) funciona em 10 minutos: uma imagem vale 16×16 palavras

Desta vez, vou ser afiado e curto. Em 10 minutos, indicarei as pequenas modificações da arquitetura do transformador para classificação da imagem.

Como é um artigo de acompanhamento, fique à vontade para aconselhar meus artigos anteriores sobre Transformador e atenção Se você não se sente tão confortável com os termos.

Agora, senhoras e senhores, você pode começar seus relógios!

Os transformadores não têm os vieses indutivos das redes neurais convolucionais (CNNs), como invariância de tradução e uma restrição localmente restrita campo receptivo. Você provavelmente ouviu isso antes.

Mas o que isso realmente significa?

Bem, invariância significa que você pode reconhecer uma entidade (ou seja, objeto) em uma imagem, mesmo quando sua aparência ou posição varia. Tradução Na visão computacional implica que cada pixel de imagem foi movido por uma quantidade fixa em uma direção específica.

Além disso, lembre -se de que a convolução é um operador local linear. Vemos apenas os valores do vizinho, conforme indicado pelo kernel.

Por outro lado, o transformador é por design invariante de permutação. A má notícia é que ele não pode processar dados estruturados em grade. Precisamos de sequências! Para esse fim, converteremos um sinal não sequencial espacial em uma sequência!

Vamos ver como.

Como o transformador de visão funciona em poucas palavras

A arquitetura total é chamada Vision Transformer (Vit em abreviação). Vamos examiná -lo passo a passo.

  1. Divida uma imagem em patches

  2. Achate os remendos

  3. Produzir incorporações lineares de menor dimensão a partir dos remendos achatados

  4. Adicione incorporações posicionais

  5. Alimente a sequência como uma entrada para um codificador de transformador padrão

  6. Pré -“o modelo com rótulos de imagem (totalmente supervisionada em um enorme conjunto de dados)

  7. Finetune no conjunto de dados a jusante para classificação de imagem

Vision-transformer-gif
Fonte: Google AI Blog

Os patches de imagem são basicamente os tokens de sequência (como palavras). De fato, o bloco do codificador é idêntico ao transformador original proposto por Vaswani et al. (2017) como temos extensivamente descrito:




O-Transformer-Block-Vit


O bem conhecido bloco de transformadores. Imagem de Alexey Dosovitskiy et al 2020. Fonte:Uma imagem vale 16×16 palavras: transformadores para reconhecimento de imagem em escala

A única coisa que muda é o número desses blocos. Para esse fim, e para provar ainda que, com mais dados, eles podem treinar variantes maiores de VIT, foram propostos 3 modelos:




Table Vit-Models-Description


Alexey Dosovitskiy et al 2020. Fonte:Uma imagem vale 16×16 palavras: transformadores para reconhecimento de imagem em escala

Cabeças se referem Atenção de várias cabeçasenquanto o tamanho do MLP se refere ao módulo azul na figura. O MLP significa perceptron de várias camadas, mas na verdade é um monte de camadas de transformação lineares.

Tamanho oculto DD é o tamanho de incorporação, que é mantido fixado ao longo das camadas. Por que mantê -lo fixo? Para que possamos usar resíduos curtos pular conexões.

Caso você tenha perdido, existe não decodificador no jogo. Apenas uma camada linear extra para a classificação final chamada MLP Head.

Mas isso é suficiente?

Sim e não. Na verdade, precisamos de uma quantidade enorme de dados e, como resultado, recursos computacionais.

Detalhes importantes

Especificamente, se o VIT for treinado em conjuntos de dados com mais de 14m (pelo menos: P), ele pode se aproximar ou vencer os CNNs de última geração.

Caso contrário, é melhor você ficar com resinações ou EFABIFITYNETS.

O VIT é pré-treinado no grande conjunto de dados e depois ajustado para pequenos. A única modificação é descartar a cabeça de previsão (cabeça do MLP) e anexar um novo D×KD \ vezes k

Achei interessante que os autores afirmem que é melhor ajustar resoluções mais altas do que o pré-treinamento.

Para ajustar as resoluções mais altas, 2D interpolação das incorporações de posição pré-treinadas são realizadas. O motivo é que eles modelam incorporações posicionais com camadas lineares treináveis. Dito isto, a parte principal de engenharia deste artigo tem tudo a ver com alimentar uma imagem no transformador.

Representando uma imagem como uma sequência de patches

Eu também estava super curioso como você pode remodelar elegantemente a imagem em patches. Para uma imagem de entrada (x)RH×C×C\ textbf (x) \ em r^{h \ times w \ times c}

Se você não percebeu o patch de imagem, ou seja, (16,16,3) é achatado para 16x16x3. Espero que agora o título faça sentido;)

Vou usar o Einops Biblioteca que funciona acima de Pytorch. Você pode instalá -lo via PIP:

$ pip install einops

E então algum código compacto pytorch:

from einops import rearrange

p = patch_size

x_p = rearrange(img, 'b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1 = p, p2 = p)

Em suma, cada símbolo ou cada parêntese indica uma dimensão. Para mais informações sobre operações de Einsum, consulte nosso blogpost nas operações de Einsum.

Observe que os patches de imagem são sempre quadrados para simplificar.

E quanto a ir de patch para incorporação? É apenas uma camada de transformação linear que leva uma sequência de P2CP^{2} c elementos e saídas DD.

patch_dim = (patch_size**2) * channels

patch_to_embedding = nn.Linear(patch_dim, dim)

Você pode ver o que está faltando?

Aposto que você faz! Precisamos fornecer algum tipo de ordem.

Incorporações posicionais

Embora muitos esquemas de incorporação posicional tenham sido aplicados, nenhuma diferença significativa foi encontrada. Provavelmente, isso se deve ao fato de o codificador transformador operar em um nível de patch. O aprendizado de incorporações que capturam as relações de ordem entre patches (informações espaciais) não é tão crucial. É relativamente mais fácil entender as relações entre os remendos de P X P do que de uma altura da imagem completa x largura.

Intuitivamente, você pode imaginar resolver um quebra -cabeça de 100 peças (patches) em comparação com 5000 peças (pixels).

Portanto, após a projeção linear de baixa dimensão treinável A incorporação de posição é adicionada às representações do patch. É interessante ver como são essas incorporações de posição após o treinamento:




Visualizando posicional-codificações-vit


Alexey Dosovitskiy et al 2020. Fonte:Uma imagem vale 16×16 palavras: transformadores para reconhecimento de imagem em escala

Primeiro, há algum tipo de estrutura 2D. Segundo, os padrões entre linhas (e colunas) têm representações semelhantes. Para altas resoluções, foi utilizada uma estrutura sinusoidal.

Principais descobertas

Nos primeiros dias do Conv, costumávamos visualizar as primeiras camadas.

Por que?

Porque acreditamos que redes bem treinadas geralmente mostram bom e suave filtros.




Visualizando-Conv-filters-vs-vit


Esquerda: AlexNet Fileters Visualização. Fonte:Curso de Standford CS231N Certo: Vit Aprendido Filtros. Fonte:Uma imagem vale 16×16 palavras: transformadores para reconhecimento de imagem em escala

Peguei emprestado a imagem do curso de Stanford CS231N: Redes neurais convolucionais para reconhecimento visual.

Como afirmou perfeitamente no CS231N:

“Observe que os pesos da primeira camada são muito agradáveis ​​e suaves, indicando uma rede bem convergida. Os recursos de cor/escala de cinza estão agrupados porque o Alexnet contém dois fluxos separados de processamentoE uma aparente consequência dessa arquitetura é que um fluxo desenvolve recursos de alta frequência em escala de cinza e os outros recursos de cor de baixa frequência. ” ~ Curso Stanford CS231: Visualizando o que os Convnets aprendem

Para tais visualizações PCA é usado. Dessa forma, o autor mostrou que as representações antecipadas da camada podem Compartilhe recursos semelhantes.

Próxima pergunta, por favor.

Quão longe as interações não locais aprendidas estão?

Resposta curta: Para o tamanho do patch P, máximo p*P, que no nosso caso é 128, mesmo da 1ª camada!

Não precisamos de convocação sucessiva. camadas para chegar a pixels de 128 anos. Com convoluções sem dilatação, o campo receptivo é aumentado linearmente. Usando a auto-atimento, temos interação entre representações de pixels na 1ª camada e pares de representações na 2ª camada e assim por diante.




VIT-CEADS-MEAN-ATENÇÃO DISTANCE-VS-CONVOLUÇÕES


Direita: Imagem gerada usando Fomoro você tem um computador Esquerda: imagem por Alexey Dosovitskiy et al 2020

Com base no diagrama à esquerda do VIT, pode -se argumentar que:

  • De fato, existem cabeças que já atendem a todo o patch nas camadas iniciais.

  • Pode -se justificar o ganho de desempenho com base nas interações de pixel de acesso antecipado. Parece mais crítico para as primeiras camadas terem acesso a todo o patch (informações globais). Em outras palavras, as cabeças que pertencem à parte superior esquerda da imagem podem ser o principal motivo do desempenho superior.

  • Curiosamente, a distância de atenção aumenta com a profundidade da rede semelhante ao campo receptivo das operações locais.

  • Também há cabeças de atenção com distâncias de atenção consistentemente pequenas nas camadas baixas. À direita, uma camada de 24 camadas com convoluções 3×3 padrão tem um campo receptivo de menos de 50. Precisávamos de aproximadamente 50 convivências, para atender a um campo receptivo ~ 100, sem dilatação ou agrupamento de camadas.

  • Para aplicar essa idéia de cabeças de atenção altamente localizadas, os autores experimentaram modelos híbridos que aplicam uma resnet antes do transformador. Eles encontraram cabeças menos altamente localizadas, como esperado. Juntamente com a visualização do filtro, sugere que pode servir a uma função semelhante à das camadas convolucionais iniciais nos CNNs.

Distância da atenção e visualização

No entanto, acho essencial entender como eles mediram a distância média de atenção. É análogo ao campo receptivo, mas não exatamente o mesmo.

A distância da atenção foi calculada como A distância média entre o pixel de consulta e o restante do patchmultiplicado pelo peso da atenção. Eles usaram 128 imagens de exemplo e calculou a média de seus resultados.

Um exemplo: se um pixel estiver a 20 pixels de distância e o peso da atenção é 0,5, a distância é 10.

Finalmente, o modelo atende a imagens de regiões semanticamente relevantes para a classificação, conforme ilustrado abaixo:




Visualizando-se-Attention-Vit


Alexey Dosovitskiy et al 2020. Fonte:Uma imagem vale 16×16 palavras: transformadores para reconhecimento de imagem em escala

Implementação

Confira o nosso repositório Encontrar módulos de auto-ataque para a visão de computação. Dada uma implementação da baunilha Codificador do transformadorVit parece tão simples assim:

import torch

import torch.nn as nn

from einops import rearrange

from self_attention_cv import TransformerEncoder

class ViT(nn.Module):

def __init__(self, *,

img_dim,

in_channels=3,

patch_dim=16,

num_classes=10,

dim=512,

blocks=6,

heads=4,

dim_linear_block=1024,

dim_head=None,

dropout=0, transformer=None, classification=True):

"""

Args:

img_dim: the spatial image size

in_channels: number of img channels

patch_dim: desired patch dim

num_classes: classification task classes

dim: the linear layer's dim to project the patches for MHSA

blocks: number of transformer blocks

heads: number of heads

dim_linear_block: inner dim of the transformer linear block

dim_head: dim head in case you want to define it. defaults to dim/heads

dropout: for pos emb and transformer

transformer: in case you want to provide another transformer implementation

classification: creates an extra CLS token

"""

super().__init__()

assert img_dim % patch_dim == 0, f'patch size {patch_dim} not divisible'

self.p = patch_dim

self.classification = classification

tokens = (img_dim // patch_dim) ** 2

self.token_dim = in_channels * (patch_dim ** 2)

self.dim = dim

self.dim_head = (int(dim / heads)) if dim_head is None else dim_head

self.project_patches = nn.Linear(self.token_dim, dim)

self.emb_dropout = nn.Dropout(dropout)

if self.classification:

self.cls_token = nn.Parameter(torch.randn(1, 1, dim))

self.pos_emb1D = nn.Parameter(torch.randn(tokens + 1, dim))

self.mlp_head = nn.Linear(dim, num_classes)

else:

self.pos_emb1D = nn.Parameter(torch.randn(tokens, dim))

if transformer is None:

self.transformer = TransformerEncoder(dim, blocks=blocks, heads=heads,

dim_head=self.dim_head,

dim_linear_block=dim_linear_block,

dropout=dropout)

else:

self.transformer = transformer

def expand_cls_to_batch(self, batch):

"""

Args:

batch: batch size

Returns: cls token expanded to the batch size

"""

return self.cls_token.expand((batch, -1, -1))

def forward(self, img, mask=None):

batch_size = img.shape(0)

img_patches = rearrange(

img, 'b c (patch_x x) (patch_y y) -> b (x y) (patch_x patch_y c)',

patch_x=self.p, patch_y=self.p)

img_patches = self.project_patches(img_patches)

if self.classification:

img_patches = torch.cat(

(self.expand_cls_to_batch(batch_size), img_patches), dim=1)

patch_embeddings = self.emb_dropout(img_patches + self.pos_emb1D)

y = self.transformer(patch_embeddings, mask)

if self.classification:

return self.mlp_head(y(:, 0, :))

else:

return y

Conclusão

A parte principal da engenharia deste trabalho é a formulação de um problema de classificação de imagem como um problema seqüencial usando patches de imagem como tokens e processando -o por um transformador. Isso parece bom e simples, mas precisa de dados enormes. Infelizmente, o Google possui o conjunto de dados pré -treinado para que os resultados não sejam reproduzíveis. E mesmo que fossem, você precisaria ter poder de computação suficiente.

Aprendizagem profunda no livro de produção 📖

Aprenda a construir, treinar, implantar, escalar e manter modelos de aprendizado profundo. Entenda a infraestrutura de ML e os MLOPs usando exemplos práticos.

Saber mais

* Divulgação: Observe que alguns dos links acima podem ser links de afiliados e, sem nenhum custo adicional, ganharemos uma comissão se você decidir fazer uma compra depois de clicar.

Luis es un experto en Ciberseguridad, Computación en la Nube, Criptomonedas e Inteligencia Artificial. Con amplia experiencia en tecnología, su objetivo es compartir conocimientos prácticos para ayudar a los lectores a entender y aprovechar estas áreas digitales clave.

Leave a Reply

Your email address will not be published. Required fields are marked *