Playground de convolução e mapas de características

veja quais padrões visuais sobrevivem a cada escolha de núcleo

A carregar a simulação interativa...

Sem preenchimento, uma rede profunda encolhe a imagem até o nada

Um núcleo 3×3 sem preenchimento, com passo 1, retira um píxel a cada borda; por isso, a entrada 28×28 desta ferramenta produz uma saída 26×26. Parece inofensivo até se sobreporem camadas: dez reduzem a imagem a 8×8 e, depois de catorze, já não resta nada. É precisamente para evitar isso que existe o preenchimento "same": acrescentar uma borda de um píxel repõe as dimensões da entrada na saída e permite construir uma rede tão profunda quanto se queira. O passo atua no sentido oposto e o efeito acumula-se por divisão, não por subtração: uma desfocagem com passo 2 transforma 28×28 em 14×14 numa só camada. As duas definições desta ferramenta estão longe de ser meramente cosméticas: determinam quantas camadas a arquitetura comporta antes de a imagem desaparecer.

Uma janelinha que desliza

Uma convolução desliza uma pequena grade de números, o kernel, sobre a imagem. Em cada parada, multiplica os valores sobrepostos e os soma em um único pixel de saída. O resultado é um mapa de características que se ilumina onde o padrão do kernel aparece. Experimente aqui o kernel de detecção de bordas: regiões planas escurecem e as fronteiras se acendem, porque o kernel responde à mudança, não ao brilho em si.

Não é bem uma convolução

A operação que quase toda CNN chama de "convolução" é na verdade uma correlação cruzada. A convolução matemática verdadeira primeiro inverte o kernel de cima para baixo e da esquerda para a direita antes de deslizá-lo; as bibliotecas de aprendizado profundo pulam essa inversão. Como a rede aprende os pesos de qualquer forma, um kernel invertido seria simplesmente aprendido ao contrário e daria um resultado idêntico, e por isso o nome errado pegou. Com um kernel simétrico como o de desfoque, as duas são indistinguíveis.

Intuição errada comum

Um mapa de características mais profundo nem sempre é "melhor". Um stride alto ou núcleos agressivos podem remover informações de que as camadas posteriores precisavam.

Problema resolvido na íntegra

  1. Tamanho do mapa de saída para um mapa de entrada 28×28 e kernel sobel-x 3×3 6 passos

    A camada: um mapa de entrada de 28×28, um núcleo sobel-x de 3×3, passo 1, preenchimento mesmo. Calcule o tamanho do mapa de saída e o custo de uma passagem em multiplicações-adições — depois determine quantas camadas destas têm de ser empilhadas antes que um único píxel de saída dependa de todos os píxeis da imagem.

    1. O preenchimento fixa o tamanho, por isso resolva-o primeiro. O preenchimento mesmo coloca uma borda de zeros de um píxel em redor do mapa, o que é exatamente o suficiente para uma janela de 3×3 ficar centrada num píxel do canto em vez de ficar pendurada fora da extremidade. A borda de que um núcleo precisa é metade da sua dimensão, sem contar com o centro.

      P=Ks−12=3−12=1P=\frac{K_s-1}{2}=\frac{3-1}{2}=1
    2. Deslize a janela ao longo de uma linha. A sua extremidade esquerda começa em 0 e avança segundo o passo até que a sua extremidade direita alcance o fim da linha com preenchimento, pelo que contar os píxeis de saída é uma contagem de postes de vedação: o número de avanços, mais 1 para a posição inicial. Ao passo 1, a borda devolve exatamente as 2 colunas que o núcleo retira, razão pela qual recebe o nome de mesmo.

      Nout=⌊Nin+2P−KsS⌋+1=⌊28+2−31⌋+1=28N_{out}=\left\lfloor\frac{N_{in}+2P-K_s}{S}\right\rfloor+1=\left\lfloor\frac{28+2-3}{1}\right\rfloor+1=28
    3. Cada um dos 784 píxeis de saída é uma soma ponderada de 9 valores de entrada. Some os pesos de sobel-x e eles anulam-se para 0, de modo que qualquer janela cujas 9 entradas sejam todas iguais devolve exatamente 0 — independentemente do brilho dessa região. O mapa fica escuro onde quer que a imagem seja uniforme e responde apenas onde a coluna esquerda da janela difere da direita.

      y=∑i,jwijxij,∑i,jwij=(−1+0+1)+(−2+0+2)+(−1+0+1)=0y=\sum_{i,j}w_{ij}x_{ij},\qquad \sum_{i,j}w_{ij}=(-1+0+1)+(-2+0+2)+(-1+0+1)=0
    4. A conta aritmética resulta daqui: 9 multiplicações-acumulações por píxel de saída, um píxel de saída por posição da janela. O painel apresenta essa contagem.

      MACs=Nout2×Ks2=282×9=7056\mathrm{MACs}=N_{out}^{2}\times K_s^{2}=28^{2}\times9=7056
    5. A profundidade é a parte interessante. Após uma camada, um píxel de saída vê 3 píxeis de entrada de largura. Adicione uma segunda e cada um desses 3 era ele próprio uma janela de 3 — mas as janelas vizinhas sobrepõem-se em 2, pelo que o alcance atinge 5, não 9. Cada camada adicional 3×3 de passo 1 alarga-o em exatamente 2.

      r1=3,rL=rL−1+2⟹rL=2L+1r_1=3,\qquad r_L=r_{L-1}+2\quad\Longrightarrow\quad r_L=2L+1
    6. Defina o alcance para cobrir todas as 28 colunas e determine a profundidade. 13 camadas atingem 27 e ficam a faltar uma coluna; a 14.ª é a primeira cujos píxeis de saída podem ser influenciados pela imagem inteira.

      2L+1≥28⟹L≥13.5⟹L=14, r14=292L+1\ge28\quad\Longrightarrow\quad L\ge13.5\quad\Longrightarrow\quad L=14,\ r_{14}=29

    Resposta

    Saída de 28×28, 7056 multiplicações-adições por camada, e 14 camadas antes que um píxel veja a imagem inteira. Agora calcule o custo desse alcance. As 14 camadas empilhadas gastam 14 × 9 = 126 multiplicações-acumulações por píxel de saída. Uma única camada que alcance a mesma distância necessita de um núcleo de 29×29, a 841 por píxel de saída — 6,7 vezes mais aritmética para exatamente o mesmo campo de visão. A profundidade compra alcance de forma muito mais barata do que a largura, razão pela qual as redes de visão são pilhas longas de núcleos de 3×3 em vez de pilhas curtas de núcleos grandes.

    29214×32=841126=6.7\frac{29^{2}}{14\times3^{2}}=\frac{841}{126}=6.7
Referências (1)
  • Insight block 3 — the operation called convolution is cross-correlation: I. Goodfellow, Y. Bengio and A. Courville, Deep Learning, ch. 9. MIT Press, 2016. ISBN 978-0-262-03561-3 — "many machine learning libraries implement cross-correlation but call it convolution".