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:
-
inputConnection: conexões ponderadas entreNeurons
-
inputFunction: especificaweightsevector sums aplicado aos dados de conexão de entrada
-
transferFunction: especificaweights evector sums aplicados aos dados de saída __
-
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:
-
camadas de entrada
-
camadas ocultas
-
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:
-
o número deLayers emNeuralNetwork
-
o número deNeurons em cadaLayer (e oweighted functions entre eles), e
-
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.