Pesquisa de site

Filtros em redes neurais convolucionais


Em Multi Layer Perceptrons (MLP), os parâmetros que podem ser aprendidos são os pesos da rede que são mapeados para vetores de recursos. No contexto de Redes Neurais Convolucionais, entretanto, os parâmetros que podem ser aprendidos são chamados de filtros, filtros que são matrizes/matrizes bidimensionais geralmente de tamanho quadrado. Neste artigo, exploraremos o que esses filtros realmente fazem com uma imagem à medida que ela passa pelas camadas de uma Rede Neural Convolucional (CNN).

Pré-requisitos

É necessário um conhecimento básico de código Python e redes neurais para acompanhar este tutorial. Recomendamos este artigo para codificadores intermediários a avançados com experiência no desenvolvimento de novas arquiteturas.

O código neste artigo pode ser executado em um PC doméstico normal ou no DigitalOcean Droplet.

Redes Neurais e Extração de Recursos

Uma capacidade essencial das redes neurais é a capacidade de extrair características dos dados para depois utilizá-los no arquivamento de um determinado objetivo, seja classificação, regressão etc. Em MLPs, esse processo é fácil de conceituar, pontos de dados que muitas vezes são atributos de uma instância específica de dados são mapeados para pesos treinados, a fim de combiná-los ou transformá-los de alguma forma em recursos essenciais. Por outro lado, a extração de características não é tão clara quando se trata de CNNs, pois elas não lidam com um vetor de atributos, mas sim com imagens que são uma matriz bidimensional de atributos (pixels).

Além disso, o que representaria uma característica quando se trata de imagens? Ao falar sobre um conjunto de dados tabular de casas, por exemplo, colunas que contêm atributos como número de quartos ou tamanho da sala são consideradas características de uma instância específica de casa. Então, que tal uma imagem de definição aprimorada (480p) de um gato com tamanho de (640, 480) pixels? Esta imagem possui 640 colunas e 480 linhas, num total de 307.200 atributos (pixels), o que representa características neste caso?

Imagens na borda

Muitos dos detalhes do que constitui uma imagem estão, na verdade, contidos em suas bordas ou contornos. É uma das razões pelas quais podemos distinguir facilmente objetos em desenhos animados. Na verdade, existem numerosos estudos que sugerem que a percepção de bordas é uma das primeiras técnicas utilizadas pelo cérebro humano ao processar sinais visuais provenientes dos olhos (Willian Mcllhagga, 2018). A percepção de borda não se limita apenas à visão humana, alguns estudos argumentam que é uma das razões pelas quais os Avians (pássaros) são tão hábeis em desviar de obstáculos no meio do vôo em velocidades tão altas, bem como pousar em pequenos alvos de tão longe. com extrema precisão (Partha Bhagavatula et al, 2009).

A única informação que temos são arestas e todos sabemos o que é isso.

CNNs e visão humana

Tem-se falado muito sobre como as redes neurais imitam o cérebro humano. Um cenário que dá alguma credibilidade a isso é o fato de que assim como o cérebro humano começa a processar sinais visuais vindos dos olhos percebendo bordas, as Redes Neurais Convolucionais também começam a extrair características de imagens detectando bordas, na verdade pode-se dizer que as bordas representam características da imagem. As ferramentas que utiliza para este fim são os seus parâmetros que podem ser aprendidos, os seus filtros.

Esse é especificamente o propósito dos filtros em uma Rede Neural Convolucional, eles existem para ajudar a extrair características das imagens. Embora as primeiras camadas de uma CNN sejam compostas por filtros de detecção de bordas (extração de recursos de baixo nível), as camadas mais profundas geralmente aprendem a focar em formas e objetos específicos na imagem. Para os fins deste artigo, focarei na detecção de bordas nas primeiras camadas, pois é um processo bastante intrigante e os filtros são facilmente compreensíveis.

Filtrando bordas

O legal das redes neurais convolucionais é que elas podem aprender filtros personalizados de detecção de bordas com base na distribuição de probabilidade de pixels em um determinado conjunto de dados e no objetivo específico da rede. Não obstante, existem alguns filtros clássicos de detecção de bordas formulados manualmente que podem ser usados para desenvolver uma intuição de como é a detecção de bordas em um contexto de visão computacional. São eles os filtros Prewitt, Sobel, Laplacian, Robinson Compass e Krisch Compass.

Para realmente examinar o que esses filtros fazem, vamos fazer um trabalho pesado aplicando-os às imagens usando a função de convolução escrita manualmente fornecida abaixo.

import numpy as np
import torch
import torch.nn.functional as F
import cv2
from tqdm import tqdm
import matplotlib.pyplot as plt


def convolve(image_filepath, filter, title=''):
    """
    This function performs convolution and
    returns both the original and convolved
    images.
    """

    #  reading image in grayscale format
    image = cv2.imread(image_filepath, cv2.IMREAD_GRAYSCALE)

    #  defining filter size
    filter_size = filter.shape[0]

    #  creating an array to store convolutions (x-m+1, y-n+1)
    convolved = np.zeros(((image.shape[0] - filter_size) + 1, 
                      (image.shape[1] - filter_size) + 1))
    
    #  performing convolution
    for i in tqdm(range(image.shape[0])):
      for j in range(image.shape[1]):
        try:
          convolved[i,j] = (image[i:(i+filter_size),
                                  j:(j+filter_size)] * filter).sum()
        except Exception:
          pass

    #  converting to tensor
    convolved = torch.tensor(convolved)
    #  applying relu activation
    convolved = F.relu(convolved)

    #  producing plots
    figure, axes = plt.subplots(1,2, dpi=120)
    plt.suptitle(title)
    axes[0].imshow(image, cmap='gray')
    axes[0].axis('off')
    axes[0].set_title('original')
    axes[1].imshow(convolved, cmap='gray')
    axes[1].axis('off')
    axes[1].set_title('convolved')
    pass

Função de convolução.

Esta função replica o processo de convolução com uma etapa adicional de ativação do ReLU conforme esperado em uma convnet típica. Utilizando esta função, detectaremos bordas na imagem abaixo usando os filtros listados acima.

Amostra

Filtros Prewitt

Os filtros Prewitt verticais e horizontais.

O operador Prewitt é composto por dois filtros que ajudam a detectar bordas verticais e horizontais. O filtro horizontal (direção x) ajuda a detectar bordas na imagem que cortam perpendicularmente através do eixo horizontal e vice-versa para o filtro vertical (direção y).

# utilizing the horizontal filter
convolve('image.jpg', horizontal)

# utilizing the vertical filter
convolve('image.jpg', vertical)

Filtros Sobel

Os filtros Sobel verticais e horizontais

Assim como o operador Prewitt, o operador Sobel também é composto por um filtro de detecção de bordas vertical e horizontal. As bordas detectadas são bastante semelhantes aos resultados obtidos usando filtros Prewitt, mas com uma distinção de maior intensidade de pixels nas bordas. Em outras palavras, as bordas detectadas pelos filtros Sobel são mais nítidas em comparação aos filtros Prewitt.

# utilizing the horizontal filter
convolve('image.jpg', horizontal)

# utilizing the vertical filter
convolve('image.jpg', vertical)

Filtro Laplaciano

O filtro Laplaciano

Ao contrário dos filtros Prewitt e Sobel, o filtro Laplaciano é um filtro único que detecta arestas de orientação diferente. Do ponto de vista matemático, ele calcula derivadas de segunda ordem de valores de pixel, ao contrário dos filtros Prewitt e Sobel que calculam derivadas de primeira ordem.

# utilizing the filter
convolve('image.jpg', filter)

Máscaras de bússola Robinson

Todas as 8 máscaras Robinson Compass

As máscaras Robinson Compass são filtros de detecção de bordas compostos por 8 filtros diferentes que respondem pelas 8 direções geográficas da bússola, conforme mostrado na imagem acima. Esses filtros ajudam a detectar bordas orientadas nas direções da bússola. Para resumir, apenas dois dos filtros são usados para fins ilustrativos.

# utilizing the north_west filter
convolve('image.jpg', north_west)

# utilizing the north_east filter
convolve('image.jpg', north_east)

Máscaras Bússola Krisch

Todas as 8 máscaras Krisch Compass

Semelhante às máscaras Robinson Compass, a máscara Krisch Compass também é composta por 8 filtros que ajudam a detectar bordas nas direções geográficas da bússola. dois dos filtros são usados abaixo.

# utilizing the south_west filter
convolve('image.jpg', south_west)

# utilizing the south_east filter
convolve('image.jpg', south_east)

Filtrar notações

Há uma afirmação muito importante acima que você provavelmente não percebeu,

O filtro horizontal (direção x) ajuda a detectar bordas na imagem que cortam perpendicularmente através do eixo horizontal e vice-versa para o filtro vertical (direção y).

Essa afirmação pode parecer um pouco confusa, mas irei detalhá-la mais detalhadamente nesta seção. Considere a imagem abaixo, a figura da direita é o que o olho humano vê, enquanto a figura da esquerda é o que um computador percebe. Como é evidente na imagem, a linha branca delineia uma borda vertical clara na 'tela' preta, para o olho humano isso é evidente por causa do contraste entre essa linha e seu entorno (Na mesma palheta, um computador precisa ser capaz de perceber essa mudança de contraste no nível do pixel e é essencialmente isso que a detecção de bordas envolve).

No entanto, para encontrar fisicamente essa borda, seria necessário passar o dedo da esquerda para a direita (horizontalmente) ou vice-versa. O mesmo se aplica aos filtros de detecção de bordas; para detectar uma borda vertical, você precisa utilizar um filtro horizontal.

O que você vê versus o que um computador ‘vê’

Vamos tentar detectar bordas na imagem usando os filtros Prewitt horizontais e verticais. A matemática por trás do processo de detecção de bordas é ilustrada na imagem abaixo. A matemática por trás do processo de convolução é bastante fácil de seguir conforme descrito;

  1. Coloque o filtro no canto superior esquerdo.
  2. Execute a multiplicação elemento a elemento.
  3. Calcule uma soma cumulativa.
  4. Retorna a soma obtida como um pixel correspondente em uma matriz vazia.
  5. Desloque o filtro um pixel para a direita e repita as etapas 1 a 4 enquanto continua a preencher a primeira linha na matriz vazia à direita.
  6. Pare quando o filtro sair dos limites.
  7. Desloque o filtro para baixo em um pixel para a segunda linha.
  8. Repita as etapas 1 a 6 ao preencher a segunda linha na matriz vazia.
  9. Faça o mesmo para todas as linhas até que o filtro saia dos limites no eixo vertical (dim 1).

A ativação é feita usando a função ReLU que simplesmente converte qualquer pixel negativo em 0. Após a convolução e ativação, a borda vertical é destacada pelo filtro horizontal enquanto o filtro vertical retorna uma imagem escurecida (todos com zero pixels), o que significa que não detectou nenhuma borda .

Matemática de detecção de bordas

A borda detectada resultante é visualizada abaixo. Seguindo a mesma lógica, se a linha fosse horizontal, representando uma borda horizontal, o filtro vertical destacaria a borda horizontal enquanto o filtro horizontal retornaria uma imagem escurecida.

Borda detectada pelo filtro horizontal

Usando a função de convolução

Para aqueles que desejam usar a função de convolução acima em uma imagem diferente ou testar diferentes filtros para detecção de bordas ou outras tarefas de processamento de imagem, esta seção é um guia rápido sobre como fazer isso.

A função leva 3 parâmetros, a saber, ‘image_filepath’, ‘filter’ e ‘title’.

‘Image_filepath’

Refere-se à localização da imagem desejada em sua unidade local ou nuvem. No caso de sua imagem estar no diretório de trabalho atual, tudo o que você precisa fazer é inserir o nome da imagem completo com sua extensão de arquivo. Caso contrário, você precisará fornecer um caminho absoluto, algo no formato ‘C:/Users/Username/Downloads/image_name.jpg’ (barra neste caso, pois estamos trabalhando em Python).

Filtro

Na verdade, este é o filtro que você gostaria de usar no processo de convolução. Os filtros são muito fáceis de fazer usando NumPy, conforme demonstrado abaixo. Tudo o que você precisa fazer depois é fornecer o objeto de filtro na função.

#  creating a Prewitt horizontal filter
prewitt_x = np.array(([-1, 0, 1],
                      [-1, 0, 1],
                      [-1, 0, 1]))
                       creating a laplacian filter
laplacian = np.array(([-1, -1, -1],
                      [-1, 8, -1],
                      [-1, -1, -1]))

Título

Este será o título da visualização da imagem fornecida quando a função for utilizada. É uma string vazia por padrão, mas fique à vontade para fornecer um título adequado conforme desejado.

Considerações Finais

O que torna as Redes Neurais Convolucionais especiais é sua capacidade de extrair recursos de uma representação bidimensional de dados, como pixels de imagem. Os recursos são extraídos como arestas usando ferramentas contidas na rede neural chamadas filtros.

Neste artigo, examinamos como é a detecção de bordas/extração de recursos do ponto de vista da visão computacional usando alguns filtros predefinidos. É digno de nota, entretanto, que uma CNN não usará esses filtros predefinidos para detecção de bordas, mas sim aprenderá os melhores filtros para detectar bordas e extrair recursos no conjunto de dados de interesse.

Artigos relacionados: