package aima.core.learning.neural; import aima.core.learning.framework.DataSet; import aima.core.util.math.Matrix; import aima.core.util.math.Vector; /** * @author Ravi Mohan * */ public class FeedForwardNeuralNetwork implements FunctionApproximator { public static final String UPPER_LIMIT_WEIGHTS = "upper_limit_weights"; public static final String LOWER_LIMIT_WEIGHTS = "lower_limit_weights"; public static final String NUMBER_OF_OUTPUTS = "number_of_outputs"; public static final String NUMBER_OF_HIDDEN_NEURONS = "number_of_hidden_neurons"; public static final String NUMBER_OF_INPUTS = "number_of_inputs"; // private final Layer hiddenLayer; private final Layer outputLayer; private NNTrainingScheme trainingScheme; /* * constructor to be used for non testing code. */ public FeedForwardNeuralNetwork(NNConfig config) { int numberOfInputNeurons = config .getParameterAsInteger(NUMBER_OF_INPUTS); int numberOfHiddenNeurons = config .getParameterAsInteger(NUMBER_OF_HIDDEN_NEURONS); int numberOfOutputNeurons = config .getParameterAsInteger(NUMBER_OF_OUTPUTS); double lowerLimitForWeights = config .getParameterAsDouble(LOWER_LIMIT_WEIGHTS); double upperLimitForWeights = config .getParameterAsDouble(UPPER_LIMIT_WEIGHTS); hiddenLayer = new Layer(numberOfHiddenNeurons, numberOfInputNeurons, lowerLimitForWeights, upperLimitForWeights, new LogSigActivationFunction()); outputLayer = new Layer(numberOfOutputNeurons, numberOfHiddenNeurons, lowerLimitForWeights, upperLimitForWeights, new PureLinearActivationFunction()); } /* * ONLY for testing to set up a network with known weights in future use to * deserialize networks after adding variables for pen weightupdate, * lastnput etc */ public FeedForwardNeuralNetwork(Matrix hiddenLayerWeights, Vector hiddenLayerBias, Matrix outputLayerWeights, Vector outputLayerBias) { hiddenLayer = new Layer(hiddenLayerWeights, hiddenLayerBias, new LogSigActivationFunction()); outputLayer = new Layer(outputLayerWeights, outputLayerBias, new PureLinearActivationFunction()); } public void processError(Vector error) { trainingScheme.processError(this, error); } public Vector processInput(Vector input) { return trainingScheme.processInput(this, input); } public void trainOn(NNDataSet innds, int numberofEpochs) { for (int i = 0; i < numberofEpochs; i++) { innds.refreshDataset(); while (innds.hasMoreExamples()) { NNExample nne = innds.getExampleAtRandom(); processInput(nne.getInput()); Vector error = getOutputLayer() .errorVectorFrom(nne.getTarget()); processError(error); } } } public Vector predict(NNExample nne) { return processInput(nne.getInput()); } public int[] testOnDataSet(NNDataSet nnds) { int[] result = new int[] { 0, 0 }; nnds.refreshDataset(); while (nnds.hasMoreExamples()) { NNExample nne = nnds.getExampleAtRandom(); Vector prediction = predict(nne); if (nne.isCorrect(prediction)) { result[0] = result[0] + 1; } else { result[1] = result[1] + 1; } } return result; } public void testOn(DataSet ds) { // TODO Auto-generated method stub } public Matrix getHiddenLayerWeights() { return hiddenLayer.getWeightMatrix(); } public Vector getHiddenLayerBias() { return hiddenLayer.getBiasVector(); } public Matrix getOutputLayerWeights() { return outputLayer.getWeightMatrix(); } public Vector getOutputLayerBias() { return outputLayer.getBiasVector(); } public Layer getHiddenLayer() { return hiddenLayer; } public Layer getOutputLayer() { return outputLayer; } public void setTrainingScheme(NNTrainingScheme trainingScheme) { this.trainingScheme = trainingScheme; trainingScheme.setNeuralNetwork(this); } }