Atualizado em 17 de abril de 2020
Camadas convolucionais são os principais blocos de construção usados em redes neurais convolucionais.
Uma convolução é a simples aplicação de um filtro a uma entrada que resulta em uma ativação. A aplicação repetida do mesmo filtro a uma entrada resulta em um mapa de ativações denominado mapa de características, indicando os locais e a força de uma característica detectada em uma entrada, como uma imagem.
A inovação do neural convolucional redes é a capacidade de aprender automaticamente um grande número de filtros em paralelo específicos para um conjunto de dados de treinamento sob as restrições de um problema de modelagem preditiva específico, como classificação de imagem. O resultado são recursos altamente específicos que podem ser detectados em qualquer lugar nas imagens de entrada.
Neste tutorial, você descobrirá como as convoluções funcionam na rede neural convolucional.
Depois de concluir este tutorial, você saberá:
- Redes neurais convolucionais aplicam um filtro a uma entrada para criar um mapa de recursos que resume a presença de recursos detectados na entrada.
- Filtros podem ser feitos à mão , como detectores de linha, mas a inovação das redes neurais convolucionais é aprender os filtros durante o treinamento no contexto de um problema de predição específico.
- Como calcular o mapa de características para convolucionais unidimensionais e bidimensionais camadas em uma rede neural convolucional.
Comece seu projeto com meu novo livro Deep Learning for Computer Vision, incluindo tutoriais passo a passo e os arquivos de código-fonte Python para todos os exemplos.
Vamos começar.
Um gentil Introdução às camadas convolucionais para redes neurais de aprendizado profundo
Foto de mendhak, alguns direitos reservados.
Visão geral do tutorial
Este tutorial é dividido em quatro partes; eles são:
- Convolução em redes neurais convolucionais
- Convolução em visão computacional
- Poder dos filtros aprendidos
- Exemplo trabalhado de Camadas convolucionais
Deseja resultados com aprendizado profundo para visão computacional?
Faça meu Curso intensivo gratuito de 7 dias por e-mail agora (com código de amostra).
Clique para se inscrever e também obter uma versão gratuita do e-book em PDF do curso.
Baixe o seu Mini GRATUITO Curso
Convolução em redes neurais convolucionais
A rede neural convolucional, ou CNN para breve, é um tipo especializado de modelo de rede neural projetado para trabalhar com dados de imagem bidimensionais, embora possam ser usados com dados unidimensionais e tridimensionais.
Central para a rede neural convolucional é a camada convolucional que dá à rede seu nome. Esta camada realiza uma operação chamada “convolução”.
No contexto de uma rede neural convolucional, uma convolução é uma operação linear que envolve a multiplicação de um conjunto de pesos com a entrada, muito parecido com um tradicional rede neural. Dado que a técnica foi projetada para entrada bidimensional, a multiplicação é realizada entre uma matriz de dados de entrada e uma matriz bidimensional de pesos, chamada de filtro ou kernel.
O filtro é menor que os dados de entrada e o tipo de multiplicação aplicado entre um patch do tamanho de um filtro da entrada e o filtro é um produto escalar. Um produto escalar é a multiplicação elemento a elemento entre o patch do tamanho do filtro da entrada e do filtro, que é então somado, sempre resultando em um único valor. Como resulta em um único valor, a operação costuma ser chamada de “produto escalar”.
Usar um filtro menor do que a entrada é intencional, pois permite que o mesmo filtro (conjunto de pesos) seja multiplicado pela matriz de entrada várias vezes em pontos diferentes na entrada. Especificamente, o filtro é aplicado sistematicamente a cada parte sobreposta ou patch do tamanho de um filtro dos dados de entrada, da esquerda para a direita, de cima para baixo.
Esta aplicação sistemática do mesmo filtro em uma imagem é uma ideia poderosa . Se o filtro for projetado para detectar um tipo específico de recurso na entrada, a aplicação desse filtro sistematicamente em toda a imagem de entrada permite ao filtro a oportunidade de descobrir esse recurso em qualquer lugar da imagem. Esta capacidade é comumente referida como invariância de tradução, por exemplo o interesse geral em saber se o recurso está presente em vez de onde estava.
A invariância para a tradução local pode ser uma propriedade muito útil se nos preocupamos mais com se algum recurso está presente do que exatamente onde está.Por exemplo, ao determinar se uma imagem contém um rosto, não precisamos saber a localização dos olhos com uma precisão de pixel perfeita, só precisamos saber que há um olho no lado esquerdo do rosto e um olho no lado direito lado da face.
– Página 342, Aprendizado profundo, 2016.
A saída da multiplicação do filtro pela matriz de entrada uma vez é um único valor. Como o filtro é aplicado várias vezes à matriz de entrada, o resultado é uma matriz bidimensional de valores de saída que representam uma filtragem da entrada. Como tal, a matriz de saída bidimensional desta operação é chamada de “mapa de feições”.
Depois que um mapa de feições é criado, podemos passar cada valor no mapa de feições por meio de uma não linearidade, como um ReLU, bem como fazemos para as saídas de uma camada totalmente conectada.
Exemplo de um filtro Aplicado a uma entrada bidimensional para criar um mapa de características
Se você vem de um campo de processamento de sinal digital ou área relacionada da matemática, pode entender a operação de convolução em uma matriz como algo diferente . Especificamente, o filtro (kernel) é invertido antes de ser aplicado à entrada. Tecnicamente, a convolução conforme descrito no uso de redes neurais convolucionais é na verdade uma “correlação cruzada”. No entanto, no aprendizado profundo, é referida como uma operação de “convolução”.
Muitas bibliotecas de aprendizado de máquina implementam correlação cruzada, mas a chamam de convolução.
– Página 333, Deep Learning, 2016.
Em resumo, temos uma entrada, como uma imagem de valores de pixel, e temos um filtro, que é um conjunto de pesos, e o filtro é aplicado sistematicamente aos dados de entrada para criar um mapa de características .
Convolução em visão computacional
A ideia de aplicar a operação convolucional a dados de imagem não é nova ou exclusiva para redes neurais convolucionais; é uma técnica comum usada em visão computacional.
Historicamente, os filtros eram projetados à mão por especialistas em visão computacional, que eram então aplicados a uma imagem para resultar em um mapa de recursos ou saída da aplicação do filtro. a análise da imagem é mais fácil de alguma forma.
Por exemplo, abaixo está um filtro de elemento 3 × 3 feito à mão para detectar linhas verticais:
1
2
3
|
0,0, 1,0, 0,0
0,0, 1,0, 0,0
0,0, 1,0, 0,0
|
Aplicando este filtro a um imagem resultará em um mapa de recursos que contém apenas linhas verticais. É um detector de linha vertical.
Você pode ver isso nos valores de peso no filtro; quaisquer valores de pixels na linha vertical central serão ativados positivamente e qualquer um dos lados será ativado negativamente. Arrastar este filtro sistematicamente pelos valores de pixel em uma imagem pode destacar apenas os pixels da linha vertical.
Um detector de linha horizontal também pode ser criado e também aplicado à imagem, por exemplo:
1
2
3
|
0,0, 0,0, 0,0
1.0, 1.0, 1.0
0.0, 0.0, 0.0
|
Combinar os resultados de ambos os filtros, por exemplo combinar os dois mapas de recursos resultará em todas as linhas de uma imagem em destaque.
Um conjunto de dezenas ou até centenas de outros pequenos filtros pode ser projetado para detectar outros recursos na imagem.
A inovação de usar a operação de convolução em uma rede neural é que os valores do filtro são pesos a serem aprendidos durante o treinamento da rede.
A rede aprenderá quais tipos de recursos devem ser extrair da entrada. Especificamente, no treinamento sob descida de gradiente estocástico, a rede é forçada a aprender a extrair recursos da imagem que minimizam a perda para a tarefa específica para a qual a rede está sendo treinada, por exemplo, extraia recursos que são os mais úteis para classificar imagens como cães ou gatos.
Nesse contexto, você pode ver que esta é uma ideia poderosa.
Poder dos filtros aprendidos
Aprender um único filtro específico para uma tarefa de aprendizado de máquina é uma técnica poderosa.
Ainda assim, as redes neurais convolucionais conseguem muito mais na prática .
Filtros múltiplos
As redes neurais convolucionais não aprendem um único filtro; eles, na verdade, aprendem vários recursos em paralelo para uma determinada entrada.
Por exemplo, é comum para uma camada convolucional aprender de 32 a 512 filtros em paralelo para uma determinada entrada.
Isso dá ao modelo 32, ou mesmo 512, diferentes maneiras de extrair recursos de uma entrada, ou muitas maneiras diferentes de “aprender a ver” e após o treinamento, muitas maneiras diferentes de “ver” os dados de entrada.
Esta diversidade permite especialização, por exemplo não apenas linhas, mas as linhas específicas vistas em seus dados de treinamento específicos.
Canais múltiplos
Imagens coloridas têm vários canais, normalmente um para cada canal de cor, como vermelho, verde, e azul.
De uma perspectiva de dados, isso significa que uma única imagem fornecida como entrada para o modelo é, na verdade, três imagens.
Um filtro deve sempre ter o mesmo número de canais como a entrada, muitas vezes referida como “profundidade”. Se uma imagem de entrada tiver 3 canais (por exemplo, uma profundidade de 3), então um filtro aplicado a essa imagem também deve ter 3 canais (por exemplo, uma profundidade de 3). Nesse caso, um filtro 3 × 3 seria de fato 3x3x3 ou para linhas, colunas e profundidade. Independentemente da profundidade da entrada e da profundidade do filtro, o filtro é aplicado à entrada usando uma operação de produto escalar que resulta em um único valor.
Isso significa que se uma camada convolucional tem 32 filtros, esses 32 filtros não são apenas bidimensionais para a entrada de imagem bidimensional, mas também são tridimensionais, com pesos de filtro específicos para cada um dos três canais. Ainda assim, cada filtro resulta em um único mapa de recursos. O que significa que a profundidade da saída da aplicação da camada convolucional com 32 filtros é 32 para os 32 mapas de feições criados.
Camadas múltiplas
As camadas convolucionais não são aplicadas apenas aos dados de entrada , por exemplo valores de pixel brutos, mas também podem ser aplicados à saída de outras camadas.
O empilhamento de camadas convolucionais permite uma decomposição hierárquica da entrada.
Considere que os filtros que operam diretamente nos valores de pixel brutos aprenderá a extrair recursos de nível inferior, como linhas.
Os filtros que operam na saída das camadas da primeira linha podem extrair recursos que são combinações de recursos de nível inferior, como recursos que compreendem várias linhas para expressar formas.
Esse processo continua até que camadas muito profundas estão extraindo rostos, animais, casas e assim por diante.
Isso é exatamente o que vemos na prática. A abstração de recursos para ordens cada vez mais altas conforme a profundidade da rede é aumentada.
Exemplo de trabalho de camadas convolucionais
A biblioteca de aprendizado profundo Keras fornece um conjunto de camadas convolucionais.
Podemos entender melhor a operação de convolução observando alguns exemplos trabalhados com dados inventados e filtros feitos à mão.
Nesta seção, veremos uma camada convolucional unidimensional e um exemplo de camada convolucional bidimensional para tornar a operação de convolução concreta e fornecer um exemplo prático de uso das camadas de Keras.
Exemplo de camada convolucional 1D
Podemos definir um entrada dimensional que tem oito elementos, todos com valor de 0,0, com uma saliência de dois elementos no meio com os valores 1,0.
1
|
|
A entrada para Keras deve ser tridimensional para uma camada convolucional 1D.
A primeira dimensão se refere a cada amostra de entrada; neste caso, temos apenas uma amostra. A segunda dimensão refere-se ao comprimento de cada amostra; neste caso, o comprimento é oito. A terceira dimensão refere-se ao número de canais em cada amostra; neste caso, temos apenas um único canal.
Portanto, o formato do array de entrada será.
1
2
3
|
# define a entrada data
data = asarray ()
data = data.reshape (1, 8, 1)
|
Definiremos um modelo que espera que as amostras de entrada tenham a forma.
O modelo terá um único filtro com a forma de 3 ou três elementos de largura. Keras refere-se ao formato do filtro como kernel_size.
1
2
3
|
# criar modelo
model = Sequential ()
model.add (Conv1D (1, 3, input_shape = (8, 1)))
|
Por padrão, os filtros em uma camada convolucional são inicializados com pesos aleatórios. Neste exemplo inventado, especificaremos manualmente os pesos para o único filtro. Definiremos um filtro capaz de detectar saliências, ou seja, um valor de entrada alto cercado por valores de entrada baixos, conforme definimos em nosso exemplo de entrada.
O filtro de três elementos que definiremos se parece com o seguinte:
1
|
|
A camada convolucional também tem um valor de entrada de polarização que também requer um peso que definiremos como zero.
Portanto, podemos forçar os pesos de nossa camada convolucional unidimensional a usar nosso filtro artesanal da seguinte maneira:
Os pesos devem ser especificados em em Estrutura tridimensional, em termos de linhas, colunas e canais. O filtro tem uma única linha, três colunas e um canal.
Podemos recuperar os pesos e confirmar que foram definidos corretamente.
1
2
|
# confirme que foram armazenados
print (model.get_weights ())
|
Finalmente, podemos aplicar o filtro único aos nossos dados de entrada.
Podemos fazer isso chamando a função predict () no modelo. Isso retornará o mapa de características diretamente: essa é a saída da aplicação do filtro sistematicamente na sequência de entrada.
1
2
3
|
# aplicar filtro aos dados de entrada
yhat = model.predict (data)
print (yhat )
|
Amarrando tudo isso junto, o exemplo completo é listados abaixo.
Executar o exemplo primeiro imprime os pesos da rede; essa é a confirmação de que nosso filtro artesanal foi definido no modelo como esperávamos.
Em seguida, o filtro é aplicado ao padrão de entrada e o mapa de características é calculado e exibido. Podemos ver a partir dos valores do mapa de recursos que a saliência foi detectada corretamente.
1
2
3
4
5
6
7
8
9
10
|
],
],
]], dtype = float32), array (, dtype = float32)]
]]
|
Vamos dar uma olhada no que aconteceu aqui.
Lembre-se de que a entrada é um vetor de oito elementos com os valores:.
Primeiro, o filtro de três elementos foi aplicado às três primeiras entradas do colocado calculando o produto escalar (operador “.”), que resultou em um único valor de saída no mapa de recursos de zero.
1
2
|
da importação numpy asarray
print (asarray (). dot (asarray ()))
|
Em nosso exemplo de manual, é o seguinte:
1
|
. = 0
|
O filtro foi então movido ao longo de um elemento de a seqüência de entrada e o processo foram repetidos; especificamente, o mesmo filtro foi aplicado à sequência de entrada nos índices 1, 2 e 3, o que também resultou em uma saída zero no mapa de recursos.
1
|
. = 0
|
Estamos sendo sistemáticos, então, novamente, o o filtro é movido ao longo de mais um elemento da entrada e aplicado à entrada nos índices 2, 3 e 4. Desta vez, a saída é um valor de um no mapa de recursos. Detectamos o recurso e ativamos adequadamente.
1
|
. = 1
|
O processo é repetido até calcularmos o todo mapa de recursos.
1
|
|
Observe que o mapa de feições tem seis elementos, enquanto nossa entrada tem oito elementos. Este é um artefato de como o filtro foi aplicado à sequência de entrada. Existem outras maneiras de aplicar o filtro à sequência de entrada que altera a forma do mapa de recursos resultante, como preenchimento, mas não discutiremos esses métodos neste post.
Você pode imaginar que com diferentes entradas, podemos detectar o recurso com mais ou menos intensidade, e com pesos diferentes no filtro, que detectaríamos diferentes recursos na sequência de entrada.
Exemplo de camada convolucional 2D
Podemos expandir o exemplo de detecção de saliência na seção anterior para um detector de linha vertical em uma imagem bidimensional.
Novamente , podemos restringir a entrada, neste caso, a uma imagem de entrada quadrada de 8 × 8 pixels com um único canal (por exemplo, tons de cinza) com uma única linha vertical no meio.
1
2
3
4
5
6
7
8
|
|
A entrada para uma camada Conv2D deve ser quadridimensional.
A primeira dimensão define as amostras; neste caso, existe apenas uma amostra. A segunda dimensão define o número de linhas; neste caso, oito. A terceira dimensão define o número de colunas, novamente oito neste caso, e finalmente o número de canais, que é um neste caso.
Portanto, a entrada deve ter a forma quadridimensional ou neste caso.
Definiremos o Conv2D com um único filtro como fizemos na seção anterior com o exemplo Conv1D.
O filtro será bidimensional e quadrado com a forma 3 × 3. A camada espera que as amostras de entrada tenham a forma ou.
1
2
3
|
# criar modelo
model = Sequential ()
model.add (Conv2D (1, (3,3), input_shape = (8, 8, 1)))
|
Vamos definir um vertical filtro detector de linha para detectar a única linha vertical em nossos dados de entrada.
O filtro tem a seguinte aparência:
1
2
3
|
0, 1, 0
0, 1, 0
0, 1, 0
|
Podemos implementar isso da seguinte maneira:
Finalmente, vamos aplique o filtro à imagem de entrada, o que resultará em um mapa de recursos que esperaríamos para mostrar a detecção da linha vertical na imagem de entrada.
1
2
|
# aplicar filtro aos dados de entrada
yhat = model.predict (data)
|
A forma da saída do mapa de feições será quadridimensional com a forma. Estaremos realizando um único lote e temos um único filtro (um filtro e um canal de entrada), portanto a forma de saída é. Podemos imprimir o conteúdo do mapa de característica única da seguinte maneira:
1
2
3
|
para r no intervalo (yhat.shape):
# imprime cada coluna na linha
print (para c no intervalo ( yhat.shape)])
|
Amarrando tudo isso junto , o exemplo completo está listado abaixo.
Executar o exemplo primeiro confirma que o filtro feito à mão foi definido corretamente nas espessuras de camada
Em seguida, o mapa de feições calculado é impresso. Podemos ver pela escala dos números que de fato o filtro detectou a única linha vertical com forte ativação no meio do mapa de recursos.
Vamos dar uma olhada mais de perto no que foi calculado.
Primeiro, o filtro foi aplicado ao canto superior esquerdo da imagem, ou um patch de imagem de 3 × 3 elementos. Tecnicamente, o patch da imagem é tridimensional com um único canal e o filtro tem as mesmas dimensões. Não podemos implementar isso em NumPy usando a função dot (), em vez disso, devemos usar a função tensordot () para que possamos somar apropriadamente em todas as dimensões, por exemplo:
Este cálculo resulta em um único valor de saída de 0,0, por exemplo, o recurso não foi detectado. Isso nos dá o primeiro elemento no canto superior esquerdo do mapa de recursos.
Manualmente, seria o seguinte:
1
2
3
|
0, 1, 0 0, 0, 0
0, 1, 0 0, 0, 0 = 0
0, 1, 0 0, 0, 0
|
O filtro é movido ao longo de uma coluna à esquerda e o processo é repetido. Novamente, o recurso não foi detectado.
1
2
3
|
0, 1, 0 0, 0, 1
0, 1, 0. 0, 0, 1 = 0
0, 1, 0 0, 0, 1
|
Mais um movimento para a esquerda para a próxima coluna e o recurso é detectado pela primeira vez, resultando em uma forte ativação.
1
2
3
|
0, 1, 0 0, 1, 1
0, 1, 0. 0, 1, 1 = 3
0, 1, 0 0, 1, 1
|
Este processo é repetido até que a borda do filtro encoste na borda ou coluna final da imagem de entrada. Isso fornece o último elemento na primeira linha completa do mapa de feições.
1
|
|
O filtro então desce uma linha e volta para a primeira coluna e o o processo está relacionado da esquerda para a direita para fornecer a segunda linha do mapa de características. E continue até que a parte inferior do filtro fique na parte inferior ou na última linha da imagem de entrada.
Novamente, como na seção anterior, podemos ver que o mapa de características é uma matriz 6 × 6, menor do que a imagem de entrada 8 × 8 devido às limitações de como o filtro pode ser aplicado à imagem de entrada.
Leitura adicional
Esta seção fornece mais recursos sobre o tópico se você for procurando ir mais fundo.
Postagens
- Curso intensivo de redes neurais convolucionais para aprendizado de máquina
Livros
- Capítulo 9: Redes convolucionais, aprendizado profundo, 2016.
- Capítulo 5: aprendizado profundo para visão computacional, aprendizado profundo com Python, 2017.
API
- API Keras Convolutional Layers
- API numpy.asarray
Resumo
Neste tutorial, você descobriu como as convoluções funcionam na rede neural convolucional.
Especificamente, você aprendeu:
- As redes neurais convolucionais aplicam um filtro a uma entrada para criar um mapa de recursos que resuma a presença de recursos detectados na entrada.
- Os filtros podem ser feitos à mão, como detectores de linha, mas a inovação das redes neurais convolucionais é aprender os filtros durante o treinamento no contexto de um problema de previsão específico.
- Como calcular o mapa de características para camadas convolucionais uni e bidimensionais em uma rede neural convolucional.
Você tem alguma dúvida?
Faça suas perguntas nos comentários abaixo e eu farei minha melhor responder.
Desenvolva modelos de aprendizado profundo para a visão hoje!
Desenvolva seus próprios modelos de visão em minutos
… com apenas algumas linhas de código python
Descubra como no meu novo e-book:
Deep Learning for Computer Vision
Ele fornece tutoriais de autoaprendizagem sobre tópicos como: classificação
, detecção de objetos (yolo e rcnn), reconhecimento de rosto (vggface e facenet) , preparação de dados e muito mais …
Finalmente, leve o aprendizado profundo para seus projetos de visão
Pule os estudos. Apenas resultados.
Veja o que há por dentro