/*
* Encog(tm) Examples v2.4
* http://www.heatonresearch.com/encog/
* http://code.google.com/p/encog-java/
*
* Copyright 2008-2010 by Heaton Research Inc.
*
* Released under the LGPL.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
* Encog and Heaton Research are Trademarks of Heaton Research, Inc.
* For information on Heaton Research trademarks, visit:
*
* http://www.heatonresearch.com/copyright.html
*/
package org.encog.examples.neural.recurrent;
import org.encog.engine.network.activation.ActivationSigmoid;
import org.encog.engine.util.Format;
import org.encog.neural.data.NeuralDataSet;
import org.encog.neural.data.basic.BasicNeuralDataSet;
import org.encog.neural.networks.BasicNetwork;
import org.encog.neural.pattern.FeedForwardPattern;
import org.encog.neural.pattern.JordanPattern;
import org.encog.util.logging.Logging;
import org.encog.util.simple.EncogUtility;
/**
* This is a very simple example that shows where a temporal neural network, in
* this case an Jordan neural network, can be useful. A binary message is
* constantly coming into the neural network. The neural network has a single
* input neuron and a single output neuron. The network should detect a
* "distress signal" in the stream of bits. A distress signal is defined to be
* three 1's, or "111".
*
* Training data is provided with some sample signals, and several distress
* signals. The "!" character is placed after each distress signal, for
* training. The neural network should produce a "1" on the same cycle as the
* final "1" in the distress signal.
*
* An Jordan neural network becomes quite good at detecting the signal.
* Feedforward is never really able to do it. A feedforward is only looking at
* one bit at a time, and because the distress signal spans 3 bits, the neural
* network must have some sort of short term memory, to remember the past few
* patterns. A short-term memory is exactly what an Jordan neural network has.
*/
public class TemporalString {
public final static String DATA = "000000111!00000111!000000";
private double[][] input;
private double[][] ideal;
/**
* Generate training from the input sequence. The input sequence is a string
* of 0's and 1's. Three 1's("111") is a "distress signal", and is indicated
* by a "!".
*/
public void generateTraining()
{
// first figure out the length
int length = DATA.length();
for(int i=0;i<DATA.length();i++) {
char ch = DATA.charAt(i);
switch(ch) {
case '1':
case '0':
// don't care
break;
case '!':
length--;
break;
default:
System.out.println("Bad format!");
System.exit(0);
}
}
// allocate input and ideal
this.input = new double[length][1];
this.ideal = new double[length][1];
int index = 0;
for(int i=0;i<DATA.length();i++)
{
char ch = DATA.charAt(i);
switch(ch)
{
case '1':
this.input[index][0] = 1.0;
this.ideal[index][0] = 0.0;
index++;
break;
case '0':
this.input[index][0] = 0.0;
this.ideal[index][0] = 0.0;
index++;
break;
case '!':
this.ideal[index-1][0] = 1.0;
break;
}
}
}
public BasicNetwork createFeedForward()
{
FeedForwardPattern pattern = new FeedForwardPattern();
pattern.setInputNeurons(this.input[0].length);
pattern.setOutputNeurons(this.ideal[0].length);
pattern.addHiddenLayer(8);
pattern.setActivationFunction(new ActivationSigmoid());
return pattern.generate();
}
public BasicNetwork createJordan()
{
JordanPattern pattern = new JordanPattern();
pattern.setInputNeurons(this.input[0].length);
pattern.setOutputNeurons(this.ideal[0].length);
pattern.addHiddenLayer(16);
pattern.setActivationFunction(new ActivationSigmoid());
return pattern.generate();
}
public void run()
{
Logging.stopConsoleLogging();
generateTraining();
BasicNetwork ffNetwork = createFeedForward();
BasicNetwork jordanNetwork = createJordan();
NeuralDataSet trainingSet = new BasicNeuralDataSet(this.input, this.ideal);
// train the neural network
EncogUtility.trainConsole( jordanNetwork, trainingSet, 1);
EncogUtility.trainConsole( ffNetwork, trainingSet, 1);
System.out.println("Final Jordan Error: " + Format.formatPercent(jordanNetwork.calculateError(trainingSet)));
System.out.println("Final Feedforwd Error: " + Format.formatPercent(jordanNetwork.calculateError(trainingSet)));
System.out.println("However, the error rate can be misleading. Consider the evaluations of each network.");
System.out.println("Feedforward Evaluation:");
EncogUtility.evaluate(ffNetwork, trainingSet);
System.out.println("Jordan Evaluation:");
EncogUtility.evaluate(jordanNetwork, trainingSet);
}
public static void main(final String args[]) {
TemporalString test = new TemporalString();
test.run();
}
}