Reconhecimento de Imagens com Redes Neurais
Rede Neural é um tipo de técnica que pode ser usada para reconhecimento de imagens.
Esse tutorial irá mostrar como usar uma Rede Neural Perceptron Multicamadas para reconhecimento de imagens. O Neuroph possui suporte integrado para reconhecimento
de imagens e assistente especializado para treinamento de redes neurais para reconhecimento de imagens. Bibliotecas para reconhecimento de imagens simples podem ser
encontradas em org.neuroph.contrib.imgrec, enquanto o assistente de reconhecimento de imagens em Neuroph Studio pode ser localizado em [Main Menu > File > New > Image recognition neural network]
Esse tutorial vai explicar o seguinte:
1. Princípios básicos de como Perceptrons Multicamada são usados para reconhecimento de imagem (uma abordagem possível é descrita aqui);
2. Como treinar redes neurais para reconhecimento de imagens com o Neuroph Studio;
3. Como usar redes neurais treinadas para reconhecimento de imagens nas suas aplicações.
Esse tutorial foi elaborado para o Neuroph v2.6.
1. Reconhecimento de Imagens com Perceptron Multicamadas
Toda imagem pode ser representada como um vetor bidimensional, onde todo elemento desse vetor contém informações de cor por cada pixel (Imagem 1)
Imagem 1. Cores da imagem
Cada cor pode ser representada como uma combinação de três cores básicas: vermelho, verde e azul (ou "red", "green" e "blue" == RGB).
Imagem 2. Sistema de cor RGB
Então, para representar alguma imagem em um sistema RGB, podemos usar três vetores bidimensionais, um para cada cor componente, onde cada elemento corresponde a um pixel da imagem:
int [][] redValues
int [][] greenValues
int [][] blueValues
Por exemplo, se o pixel no local [20, 10] tem a cor RGB[33, 66, 181] nós temos:
redValues[10][20] = 33;
greenValues[10][20] = 66;
blueValues[10][20] = 181;
As dimensões de cada um desses vetores são [alturaImagem][larguraImagem].
Podemos mesclar esses três vetores em um único vetor unidimensional para que contenha todos os valores vermelhos, verdes e azuis.
Assim é que criamos o vetor flattenedRgbValues[] (ou ValoresRgbachatados[]).
A dimensão desse vetor é [alturaImagem * larguraImagem * 3].
Agora podemos usar esse vetor unidimensional como entrada para a rede neural, para treiná-la a reconhecer ou classificá-las. Perceptrons Multicamadas são o tipo de rede neural adequado para essa tarefa (Imagem 3).
Imagem 3. Alimentando o Perceptron Multicamadas com informações de cores da imagem. Cada neurônio de entrada corresponde a uma cor componente (RGB) de cada pixel em um local específico.
Cada neurônio de saída corresponde a uma imagem ou classe de imagem. Então se a saída da rede é [1, 0, 0] isso significa que a entrada é reconhecida como "imagem A".
Podemos criar conjuntos de testes para treinar a rede neural como um conjunto de pares de entradas (vetores rgb achatados), e vetores de saída (em que o neurônio de imagem correspondente é 1).
A rede pode ser treinada usando o algoritmo de aprendizado Backpropagation (Retropropagação).
Na próxima seção iremos fornecer alguns detalhes sobre a rede neural e o algoritmo de aprendizado.
2. Treinando a Rede Neural para Reconhecimento de Imagens com Neuroph Studio
O Neuroph Studio fornece ambiente para criação e treinamento de redes neurais, as quais podem ser salvas como componentes Java "prontos-para-uso". Também fornece ferramenta de reconhecimento de imagem especializada para treinar redes neurais para reconhecimento de imagens. Criar e treinar redes neurais para reconhecimento de imagens consiste nos seguintes passos:
- Criar um projeto Neuroph;
- Criar uma rede neural para reconhecimento de imagens;
- Treinar a rede;
- Testar a rede;
- Salvar e implantar a rede.
Passo 1. Para criar um projeto Neuroph clique em File > New Project
Selecione Neuroph Project e clique em Next.
Entre com o nome do projeto e local e clique em Finish.
Isso irá criar um novo Projeto Neuroph.
Passo 2. A seguir, para criar uma rede de reconhecimento de imagens, clique em File > New File.
Selecione o tipo de arquivo Image Recognition e clique em Next.
Depois, escolha as imagens que você deseja que sejam reconhecidas, selecionando arquivos de imagens individuais ou adicionando o diretório inteiro da imagem. Você também pode fazer a edição básica das imagens como recortar e
redimensionar abrindo o editor de imagens simples com o botão edit.
Color Mode - Você pode usar o reconhecimento de imagem no modo de cor (Color Mode) ou em modo preto e branco (Black and White) binário. O modo preto e branco binário representa os pixels como [0, 1] e por isso usa menor número de neurônios de entrada.
Para algumas aplicações (como reconhecimento de caracteres, por exemplo) o modo binário preto e branco talvez seja a melhor solução.
No próximo passo, escolha a imagem que não deve ser reconhecida, a qual irá ajudar a evitar o falso reconhecimento. Geralmente essas são blocos de imagens inteiros vermelhos, verdes e azuis, mas também pode incluir outras.
Quando você testar a rede de reconhecimento de imagem, você irá descobrir o que faz sentido ser incluído aqui.
Então, entre com o Rótulo do Conjunto de Treinamento e a Resolução da Amostra de Imagem e clique em Next.
Rótulo do Conjunto de Treinamento - Já que você pode criar vários conjuntos de treinamento enquanto faz testes com a rede, é uma boa prática rotulá-los.
Resolução da Amostra de Imagem (largura x altura) - Todas as imagens fornecidas serão dimensionadas para esse tamanho (largura x altura). Dimensionar imagens as tornará menores, e assim mais fácil e mais rápido para aprende-las. As dimensões da imagem determinam o tamanho do vetor de entrada e o número de neurônios na camada de entrada (se você receber exceções heap do java para alguma dimensão, tente aumentar o tamanho do heap para JVM).
Para começar, você pode usar as configurações padrão (resolução 20x20 e modo de cor), e fornecer apenas as imagens.
A próxima coisa a fazer é criar a rede neural.
Para criar a rede neural você precisa do seguinte:
Rótulo da Rede - O rótulo para a rede neural, que é útil quando você cria várias redes neurais para o mesmo problema, e você está comparando elas.
Função de Transferência - Essa definição determina qual função de transferência será usada pelos neurônios. Na maioria dos casos, você pode deixar a definição padrão "Sigmóide", mas algumas vezes usar a "Tahn" pode fornecer resultados melhores.
Neurônios em Camadas Ocultas Contam - Essa é a definição mais importante que determina o número de camadas ocultas na rede e o número de neurônios em cada camada oculta. Camadas ocultas são camadas entre as camadas de entrada e saída. O truque é ter o menor número possível de camadas e neurônios que possam aprender com sucesso o conjunto de treinamento. Quanto menor o número de neurônios - mais rápido o aprendizado e melhor a generalização. O número apropriado de neurônios ocultos também depende do número de neurônios de entrada e saída e o melhor valor poderá ser descoberto através de experimentação. Para começar, tente imagens 8x8 e uma cada oculta com 12 neurônios, que é a definição padrão. Se você quiser aumentar o número de neurônios, simplesmente entre com o número, por exemplo "12" neurônios. Se você quiser adicionar mais de uma camada de neurônios, entre com o número de neurônios em cada camada separada por espaços. Por exemplo, se você entrar com "12 8 6" isso criará três camadas ocultas com 12, 8 e 6 neurônios.
Clique no botão 'Finish' para criar a rede neural. Depois de clicar, o botão new window com a rede neural criada irá abrir.
Passo 3. Treinando a rede. Para treinar a rede, selecione o conjunto de treinos pela árvore de projetos e clique no botão 'Train'.
Isso irá abrir o diálogo para definir os parâmetros de aprendizado. Use as definições padrão de aprendizado e apenas clique no botão Train.
O treinamento irá começar e um gráfico sobre o aprendizado da rede e do contador de iteração será exibido, assim você poderá observar o processo de aprendizado. Se o aprendizado ficar parado (o erro total da rede não diminuir) você pode tentar um número diferente de neurônios, camadas ou parâmetros de aprendizado. Para a taxa de aprendizado e momentum, use valores entre [0, 1] e para o erro, algum valor pequeno menor que 0.1 é recomendado. Como regra prática, valores entre 0.2 para taxa de aprendizado e 0.7 para momentum.
Passo 4. Testar a Rede
Depois de ter treinado a rede você pode testar como ela funciona no painel de testes. Clique no botão 'Select Test Image' para definir a imagem de entrada para a rede e a saída da rede será exibida como uma lista do rótulo da imagem e dos neurônios de saída correspondentes. A imagem reconhecida corresponde ao neurônio com a maior saída. Você pode testar o conjunto de dados completo clicando no botão 'Test whole data set'.
Passo 5. Salve a rede neural
Para salvar a rede neural como um componente Java, clique em [Main menu > File > Save] e use a extensão .nnet. A rede será salva como um objeto MultiLayerPerceptron.
3. Usando o Reconhecimento de Imagens do Neuroph em suas Aplicações
Aqui está um código de amostra que demonstra como usar a rede neural para reconhecimento de imagens criada e treinada com o Neuroph Studio. Você pode rodar essa amostra, apenas especifique nomes de arquivos corretos para a rede neural e alguma imagem de teste.
import org.neuroph.core.NeuralNetwork;
import org.neuroph.contrib.imgrec.ImageRecognitionPlugin;
import java.util.HashMap;
import java.io.File;
import java.io.IOException;
public class ImageRecognitionSample {
public static void main(String[] args) {
// load trained neural network saved with Neuroph Studio (especifique algum arquivo de rede neural existente aqui)
NeuralNetwork nnet = NeuralNetwork.load("MyImageRecognition.nnet"); // carrega rede neural treinada salva com o Neuroph Studio
// obtém o plugin de reconhecimento de imagem da rede neural
ImageRecognitionPlugin imageRecognition = (ImageRecognitionPlugin)nnet.getPlugin(ImageRecognitionPlugin.class); // obtém o plugin de reconhecimento de imagem da rede neural
try {
// image recognition is done here (especifique algum arquivo existente aqui)
HashMap<String, Double> output = imageRecognition.recognizeImage(new File("someImage.jpg"));
System.out.println(output.toString());
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
O reconhecimento de imagens real é feito com apenas um método chamado a partir de ImageRecognitionPlugin:
imageRecognition.recognizeImage(new File("someImage.jpg"));
O ImageRecognitionPlugin fornece uma interface de reconhecimento de imagens simples para a rede neural. Você pode reconhecer imagens de várias fontes como File, BufferedImage ou URL. Por exemplo:
imageRecognition.recognizeImage(new URL("http://www.example.com/someImage.jpg"));
Para mais detalhes, verifique as classes no pacote org.neuroph.contrib.imgrec.
Para usar classes de reconhecimento de imagens, você deve adicionar a referência ao neuroph.jar em seu projeto (clique com o botão direito em > Properties > Libraries > Add JAR/Folder)
Solução de Problemas
1. Use dimensões de imagem iguais para o treinamento a fim de evitar possíveis problemas.
2. Use o mesmo modo de cor e dimensões da imagem para o treinamento e o reconhecimento. Se a cor não for importante para você, use preto e branco já que para o treinamento é mais rápido.
3. Se você recebeu mensagens de falta de memória para imagens maiores, aumente o tamanho do JVM com as opções –Xms e –Xmx .
TRADUÇÕES
A tradução desse tutorial em Romeno está disponível aqui. Agradecimentos a Alexander Ovsov pela tradução!
The translation of this tutorial in portuguese is available here Thanks to Nicholas Braga for the translation!
Mais informações
Redes Neurais em Processamento de Imagens: http://www.egmont-petersen.nl/Journal-papers/Egmont-PR-Review2002.pdf
Várias outras pesquisas sobre redes neurais e processamento de imagens: http://www.egmont-petersen.nl/nn-review.html
Agradecimentos a Michael Egmont-Petersen por essa contribuição. |