Introdução ao Neuroph

Introdução ao Neuroph

1. Introdução

Este artigo analisaNeuroph - uma biblioteca de código aberto para a criação de redes neurais e utilização de aprendizado de máquina.

No artigo, examinamos os conceitos principais e vários exemplos de como reunir tudo.

2. Neuroph

Podemos interagir com a Neuroph usando:

  • uma ferramenta baseada em GUI

  • uma biblioteca Java

Ambas as abordagens dependem de uma hierarquia de classes subjacente que constrói redes neurais artificiais a partir de camadas deneurons.

Vamos nos concentrar no lado programático, mas nos referiremos a várias aulas compartilhadas da abordagem baseada em GUI da Neuroph para ajudar a esclarecer o que estamos fazendo.

Para obter mais informações sobre a abordagem baseada em GUI, dê uma olhada em Neurophdocumentation.

2.1. Dependências

Se você deseja usar o Neuroph, precisamos adicionar a seguinte entrada do Maven:


    org.beykery
    neuroph
    2.92

A versão mais recente pode ser encontradaon Maven Central.

3. Principais classes e conceitos

Todos os blocos de construção conceituais básicos usados ​​têm classes Java correspondentes.

Neurons são conectados aLayers que são agrupados emNeuralNetworks. NeuralNetworks são subsequentemente treinados usandoLearningRuleseDataSets.

3.1. Neuron

A classeNeuron tem quatro atributos principais:

  1. inputConnection: conexões ponderadas entreNeurons

  2. inputFunction: especificaweightsevector sums aplicado aos dados de conexão de entrada

  3. transferFunction: especificaweights evector sums aplicados aos dados de saída __

  4. output: o valor de saída resultante da aplicação detransferFunctionseinputFunctions a uminputConnection

Juntos, esses quatro atributos principais estabelecem o comportamento:

output = transferFunction(inputFunction(inputConnections));

3.2. Layer

Layers are essentially groupings of Neurons de modo que cadaNeuron emLayer é (normalmente) apenas conectado comNeurons noLayers anterior e subsequente.

Layers, portanto, passa informações entre eles por meio das funções ponderadas que existem em seusNeurons.

Neurons pode ser adicionado às camadas: __

Layer layer = new Layer();
layer.addNeuron(n);

3.3. NeuralNetwork

A superclasse de nível superiorNeuralNetwork é subdividida em vários tipos familiares de redes neurais artificiais, incluindo redes neurais convolucionais (subclasseConvolutionalNetwork), redes neurais de Hopfield (subclasseHopfield) e redes neurais perceptron multicamadas (subclasseMultilayerPerceptron).

All NeuralNetworks are composed of Layers que geralmente são organizados em uma tricotomia:

  1. camadas de entrada

  2. camadas ocultas

  3. camadas de saída

Se estivermos usando o construtor de uma subclasse deNeuralNetwork (comoPerceptron), podemos passar oLayers, o número deNeurons para cadaLayer , e seu índice usando este método simples:

NeuralNetwork ann = new Perceptron(2, 4, 1);

Às vezes, queremos fazer isso manualmente (e é bom ver o que está acontecendo por baixo do capô). A operação básica para adicionar umLayer a umNeuralNetwork é realizada assim:

NeuralNetwork ann = new NeuralNetwork();
Layer layer = new Layer();
ann.addLayer(0, layer);
ann.setInputNeurons(layer.getNeurons());

O primeiro argumento especifica o índice deLayer emNeuralNetwork; o segundo argumento especifica o próprioLayer. Layers adicionado manualmente deve ser conectado usando a classeConnectionFactory:

ann.addLayer(0, inputLayer);
ann.addLayer(1, hiddenLayerOne);
ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(1));

O primeiro e o últimoLayer também devem ser conectados:

ConnectionFactory.fullConnect(ann.getLayerAt(0),
  ann.getLayerAt(ann.getLayersCount() - 1), false);
ann.setOutputNeurons(ann.getLayerAt(
  ann.getLayersCount() - 1).getNeurons());

Lembre-se de que a força e a potência de aNeuralNetwork são amplamente dependentes de:

  1. o número deLayers emNeuralNetwork

  2. o número deNeurons em cadaLayer (e oweighted functions entre eles), e

  3. a eficácia dos algoritmos de treinamento / precisão doDataSet

3.4. Treinando NossoNeuralNetwork

NeuralNetworks são treinados usando as classesDataSeteLearningRule.

DataSet é usado para representar e fornecer as informações a serem aprendidas ou usadas para treinarNeuralNetwork. DataSets são caracterizados por seusinput size, outputsize, e linhas(DataSetRow).

int inputSize = 2;
int outputSize = 1;
DataSet ds = new DataSet(inputSize, outputSize);

DataSetRow rOne
  = new DataSetRow(new double[] {0, 0}, new double[] {0});
ds.addRow(rOne);
DataSetRow rTwo
  = new DataSetRow(new double[] {1, 1}, new double[] {0});
ds.addRow(rTwo);

LearningRule especifica a maneira comoDataSet é ensinado ou treinado porNeuralNetwork. As subclasses deLearningRule incluemBackPropagationeSupervisedLearning.

NeuralNetwork ann = new NeuralNetwork();
//...
BackPropagation backPropagation = new BackPropagation();
backPropagation.setMaxIterations(1000);
ann.learn(ds, backPropagation);

4. Juntando tudo

Agora vamos colocar esses blocos de construção juntos em um exemplo real. Vamos começar porcombining several layers together into the familiar input layer, hidden layer, and output layer pattern exemplificado pela maioria das arquiteturas de rede neural.

4.1. Camadas

Vamos montar nossoNeuralNetwork combinando quatro camadas. Nosso objetivo é construir um (2, 4, 4, 1)NeuralNetwork.

Vamos primeiro definir nossa camada de entrada:

Layer inputLayer = new Layer();
inputLayer.addNeuron(new Neuron());
inputLayer.addNeuron(new Neuron());

Em seguida, implementamos a camada oculta um:

Layer hiddenLayerOne = new Layer();
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());

E camada oculta dois:

Layer hiddenLayerTwo = new Layer();
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());

Por fim, definimos nossa camada de saída:

Layer outputLayer = new Layer();
outputLayer.addNeuron(new Neuron());

4.2. NeuralNetwork

A seguir, podemos colocá-los juntos em umNeuralNetwork:

NeuralNetwork ann = new NeuralNetwork();
ann.addLayer(0, inputLayer);
ann.addLayer(1, hiddenLayerOne);
ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(1));
ann.addLayer(2, hiddenLayerTwo);
ConnectionFactory.fullConnect(ann.getLayerAt(1), ann.getLayerAt(2));
ann.addLayer(3, outputLayer);
ConnectionFactory.fullConnect(ann.getLayerAt(2), ann.getLayerAt(3));
ConnectionFactory.fullConnect(ann.getLayerAt(0),
  ann.getLayerAt(ann.getLayersCount()-1), false);
ann.setInputNeurons(inputLayer.getNeurons());
ann.setOutputNeurons(outputLayer.getNeurons());

4.3. Treinamento

Para fins de treinamento, vamos juntar umDataSet especificando o tamanho do vetor de entrada e de saída resultante:

int inputSize = 2;
int outputSize = 1;
DataSet ds = new DataSet(inputSize, outputSize);

Adicionamos uma linha elementar ao nossoDataSet aderindo às restrições de entrada e saída definidas acima - nosso objetivo neste exemplo é ensinar nossa rede a fazer operações XOR básicas (exclusivas ou):

DataSetRow rOne
  = new DataSetRow(new double[] {0, 1}, new double[] {1});
ds.addRow(rOne);
DataSetRow rTwo
  = new DataSetRow(new double[] {1, 1}, new double[] {0});
ds.addRow(rTwo);
DataSetRow rThree
  = new DataSetRow(new double[] {0, 0}, new double[] {0});
ds.addRow(rThree);
DataSetRow rFour
  = new DataSetRow(new double[] {1, 0}, new double[] {1});
ds.addRow(rFour);

A seguir, vamos treinar nossoNeuralNetwork com oBackPropogation LearningRule integrado:

BackPropagation backPropagation = new BackPropagation();
backPropagation.setMaxIterations(1000);
ann.learn(ds, backPropagation);

4.4. Teste

Agora que nossoNeuralNetwork está treinado, vamos testá-lo. Para cada par de valores lógicos passados ​​em nossoDataSet comoDataSetRow, executamos o seguinte tipo de teste:

ann.setInput(0, 1);
ann.calculate();
double[] networkOutputOne = ann.getOutput();

Uma coisa importante a lembrar é queNeuralNetworks only output a value on the inclusive interval of 0 and 1. Para produzir algum outro valor, devemosnormalizeedenormalize nossos dados.

Nesse caso, para operações lógicas, 0 e 1 são perfeitos para o trabalho. A saída será:

Testing: 1, 0 Expected: 1.0 Result: 1.0
Testing: 0, 1 Expected: 1.0 Result: 1.0
Testing: 1, 1 Expected: 0.0 Result: 0.0
Testing: 0, 0 Expected: 0.0 Result: 0.0

Vemos que nossoNeuralNetwork prevê com sucesso a resposta certa!

5. Conclusão

Acabamos de revisar os conceitos básicos e classes usadas pela Neuroph.

Mais informações sobre esta biblioteca estão disponíveishere, e os exemplos de código usados ​​neste artigo podem ser encontradosover on GitHub.