Inteligencia Artificial

Como fazer predição com MNIST usando arquivos externos

Eu não sei se procurei errado, mas não achei “1” tutorial mostrando como fazer predição com MNIST sem ser utilizando arquivos do dataset. Talvez seja básico demais para alguém dar importância, sei lá.  De qualquer modo, resolvi experimentar e compartilhar com vocês, tenho certeza que será do interesse de mais pessoas.

Predição com MNIST

O MNIST é um dataset consagrado, acredito que seja o “hello world” das redes neurais até. Todos os projetos o utilizam como exemplo´ TensorFlow, Theano, Caffe, Keras etc. Mas tudo o que se encontra nesses tutoriais é a construção do model e a predição com a base de testes. Vamos além, fazendo predição com arquivos do disco e minhas impressões.

Salvar o model

Para o MNIST é bastante simples compilar toda a vez que for utilizar. Coisa de 5 epochs e o model já estará em seu melhor estado. Fazer muitos repasses é problemático por causa de overfitting, que é quando a rede pára de aprender e começa a “viciar” nos dados do dataset. Daí, qualquer predição externa resultará em falso-positivo. Com apenas 1 epoch já consegue-se obter um bom resultado e para testes em CPU o MNIST também é uma boa opção. De qualquer modo, com 6 epochs já é bom considerar o salvamento do model. Para tanto, é necessário apenas uma chamada após compilar a rede neural, passando o nome do arquivo como referência. O problema é que em meus testes eu costumo salvar cópias das redes neurais para fazer testes sem modificar a versão anterior (usar git para isso acho que daria mais trabalho) e por vezes esquecia de mudar o nome do arquivo.  Por isso, coloquei ao inicio do programa a definição do nome do model baseado no nome do arquivo, assim não precisa mais mudar o nome e vira uma rotina para os próximos programas:

E após chamar a função fit, basta chamar a função save_weights para salvar os pesos. No caso do código utililzado para esse artigo, o objeto do model está nomeado como cnn_n. Então:

Criei uma função para o model, facilitando assim ter várias modelagens para testes. Basta chamar a respectiva função que se deseja utilizar na compilação do model:

Outra função para agilizar o processo é a de conversão da imagem externa para o formato de array necessário. Sempre vai precisar de um tapinha, mas é melhor do que escrever tudo de novo:

Sei que do jeito que fiz para manipular a imagem para o MNIST não é correta, porque enquanto analisava os dados percebi anomalias no formato, mas quebrou o galho, como você vai ver mais adiante.

O restante é meio padrão. Coloquei uma validação de argumentos para saber se é para treinar ou se é para predizer. Se não houver argumentos, ele inicia o treinamento, senão, varre o parâmetro em busca de arquivos. O parâmetro deve ser o nome de um diretório.

Se for para predizer, pressupõe-se que o modelo já foi treinado, portanto basta carregá-lo do HD/SSD. Se for treinamento, logo após o fit ele será salvo, como nota-se na porção de código disposto acima.

Código completo

Esse programa leva um pouco de OpenCV para converter imagens RGB em escala de cinza, assim como exibir a imagem na tela, plotando o valor da predição.

A compilação teve uma acurácia de quase 98% – o que não significa predição perfeita. O resultado da predição depende da qualidade do model, na variedade e quantidade de amostragens, na modelagem da rede, na densidade da rede, nas funções de ativação utilizadas, no número ideal de epochs e por fim, as imagens que serão passadas para a predição.

Acredito fortemente que não atingi um resultado melhor por falta de experiência, mas dentro do possível, tive um resultado satisfatório. E, se tratando do MNIST, foi possível deduzir um pouco do que ele espera para cada dígito. No vídeo eu mostro e explico as predições positivas e os falsos-positivos.

Sobre a predição com MNIST

Para compilar o modelo, basta executar o código disposto acima, sem passar parâmetros. Depois, passe o diretório contendo dígitos únicos para a predição.

Para fazer o teste, criei algumas imagens no Gimp, no formato 140×140, que é 5x o tamanho da imagem utilizada no modelo. No código está sendo feito o resize, a imagem de origem pode ser de qualquer tamanho, desde que mantenha as proporções.

Treinar o modelo

Para treinar o modelo:

Se já tiver treinado um modelo e esqueceu de salvar os pesos antes de rodar o programa novamente, pode interromper com Ctrl+C durante a execução dos epochs.

Fazer predição

Para fazer a predição com MNIST, basta passar como parâmetro o nome do diretório contendo as imagens. Certifique-se de que o diretório tem apenas imagens, ainda que não sejam dígitos escritos à mão.

O diretório de imagens deve estar no mesmo nível de diretório do programa.

Imagens do dataset do MNIST

O dataset é bastante padronizado, inclusive o formato dos dígitos são muito semelhantes, apesar de serem escritos à mão. Não estou dizendo que seja isso, mas parece que todos os dados foram escritos pela mesma pessoa. Na predição com MNIST os falsos-positivos eram os lideres. Daí dei uma olhada no formato das imagens do dataset e tentei escrever de forma parecida, porque minha escrita à mão é bem diferente e fiz minhas imagens de dígitos no Gimp, como já citei.

Predição com MNIST

Uma das predições que deu certo depois que compreendi o que a rede neural esperava é a da imagem de destaque.

Vídeo

Tão logo seja possível, disponibilizo um vídeo no nosso canal DobitAoByteBrasil no Youtube mostrando a predição com MNIST. Se não é inscrito, passe por lá e se inscreva, clique no sininho e aguarde a notificação de vídeo novo, ok?

Se gostou do artigo, aproveite também para deixar seu like na nossa página do facebook, clicando ali em cima na coluna da direita.

Até a próxima!