Reconhecimento de escrita manual com Redes Neurais Convolucionais

No final deste post (vídeo no final) você terá uma visão geral sobre o funcionamento das redes neurais convolucionais e saberá como usá-las para criar um modelo capaz de fazer o reconhecimento de escrita manual, mais particularmente reconhecer dígitos escritos à mão em imagens.

O reconhecimento de escrita manual — também conhecido como handwriting recognition, do inglês — é uma aplicação de software que ainda encontra bastante demanda hoje em dia. Se você já usou o GoodNotes no iPad, então sabe do que eu estou falando. O reconhecimento de assinaturas escritas à mão a partir de documentos digitalizados/escaneados, a captura de endereços postais escritos em envelopes, ou informações monetárias escritas em cheques bancários estão entre as aplicações mais comuns desta técnica.

De um modo geral, há duas situações nas quais isto pode ser feito:

On-line: Conforme o texto estiver sendo escrito, ocorrerá a conversão do sinal obtido a partir do traçado para códigos que correspondem às letras, os quais poderão ser utilizados no computador e em aplicativos de processamento de texto. Isto corre, por exemplo, no aplicativo GoodNotes.

Off-line: O cerne deste tipo de tarefa está em transcrever para dados eletrônicos as informações escritas à mão em qualquer folha de papel que tenha sido digitalizada, ou mesmo textos presentes em imagens naturais.

Sem dúvidas, este último cenário é talvez o que mais pode se beneficiar desta técnica, pois há muitos documentos impressos com dados escritos à mão cujas informações podem possuir grande valor, inclusive estratégico. Meu objetivo neste post é abordar justamente a aplicação do reconhecimento de escrita manual neste cenário, fazendo uso de um modelo gerado a partir de uma rede neural convolucional, com base em um conjunto de dados de treino, para reconhecer caracteres numéricos presentes em imagens ainda não vistas pelo modelo. Nós utilizaremos o dataset MNIST, que já é bem conhecido, e o framework Keras. O dataset MNIST possui 60k exemplos de treino e 10k exemplos de teste, sendo que todos estes dados correspondem a dígitos no intervalo 0–9, escritos à mão e digitalizados. Cada dígito é representado por uma imagem monocromática com 28x28 pixels.

Uma vez que nosso tutorial se baseia no uso de redes neurais convolucionais, é útil ter um certo conhecimento sobre como funciona esta arquitetura. Por este motivo, irei resumir um pouco deste funcionamento, mas é importante que você tenha uma visão mais completa em torno deste assunto. Por isso, eu recomendo que você leia este post.

Leia também — Machine Learning e a matemática da aprendizagem supervisionada

Uma visão geral das Redes neurais convolucionais

Não há muita diferença entre um rede neural regular e uma convolucional (doravante denominada ConvNet). O que difere estas arquiteturas é que as ConvNets basicamente foram concebidas para extrair features a partir de dados brutos presentes nos pixels de uma imagem. Elas possuem camadas com neurônios arranjados em três dimensões: largura, altura e profundidade. Trata-se de uma sequência de três tipos de camadas principais:

  • Convolutional Layer (Camada Convolucional) — Para cada sub-região presente na imagem, esta camada aplica um conjunto de operações matemáticas (transformações lineares) para produzir um simples valor no mapa de features que é gerado como saída da camada (cada convolução pode gerar um ou mais mapas de features). Uma função de ativação do tipo ReLU (Rectified Linear Unit) é comumente aplicada com o objetivo de promover a não linearidade ao modelo, uma das funções mais populares para esta finalidade. A camada convolucional pode gerar um ou mais mapas de features como saída.
Uma animação que ilustra como uma convolução acontece

Pooling Layer (Camada de subamostragem): A camada Pooling computa o máximo de valores obtidos em cada filtro da camada convolucional, só que o resultado desta operação é apenas uma pequena amostra do que a camada recebeu como entrada (uma pequena amostra com as informações mais representativas obtidas com cada filtro na camada convolucional). Uma vantagem desta camada é que ela reduz a dimensionalidade ao mesmo tempo em que consegue manter as informações mais úteis. É um dos motivos por trás da eficiência computacional das ConvNets

  • Fully-Connected Layer (Camada densamente conectada) é a camada final de uma ConvNet, onde se coloca o classificador. Trata-se de uma camada densamente conectada, na qual cada neurônio conectado a todos os outros de uma camada anterior e posterior. Basicamente, a FCL recebe uma entrada (que pode ser a saída de uma camada convolucional, ReLU ou Pooling) e gera como saída um vetor de dimensionalidade N, onde N é o número de classes que o modelo precisa predizer.

A camada final de uma ConvNet terá reduzido todos os dados brutos da imagem a um simples vetor com os scores atribuídos às classes. Assim, esta arquitetura transforma a imagem original, camada por camada a partir dos valores dos pixels originais em scores de classes (em nosso caso, scores que representam os dígitos 0–9).

Exemplo de aplicação: Reconhecendo escrita manual

Vamos partir de um ponto em que você já tenha instalado tudo o que é preciso para que este código funcione no seu computador:

  • Anaconda — O Anaconda é o ambiente ideal para quem trabalha com ciência de dados e Machine Learning em Python. Baixe o ambiente clicando aqui.
  • OpenCV — Library voltada para o desenvolvimento de aplicações em visão computacional. Neste caso, você precisa ter instalada a implementação em Python. Se tiver o Anaconda instalado, basta rodar este comando: $ conda install -c conda-forge opencv ou $ conda install -c conda-forge opencv=3.2.0
  • Keras — Uma library minimalista que usa a linguagem Python para nos permitir criar uma grande variedade de modelos de deep learning em cima dos frameworks TensorFlow e Theano, abstraindo a maior parte da complexidade envolvida no processo de criar modelos puramente nestes dois frameworks. Para instalar, siga as instruções presentes no próprio site da ferramenta.

Além disso, irei supor que você já saiba programar em Python e que conheça ao menos o básico do Keras.

Montando a rede neural

Você pode baixar o código atualizado, que foi criado como um notebook na ferramenta Jupyter (você pode baixar o Jupyter diretamente pelo ambiente Anaconda). O código foi desenvolvido durante o vídeo abaixo, mas foi atualizado algum tempo depois, com algumas falhas corrigidas.

O vídeo, que começa com uma breve introdução às redes convolucionais, abordando as classes do Keras que são necessárias para criar a rede, mostra em detalhes como montar uma ConvNet para reconhecer dígitos escritos à mão

Referências