/*
 This is a proprietary part of DataMelt package.
 License: the Creative Commons Attribution-Share Alike License; either version 3.0 of the License, 
 or any later version.
 http://creativecommons.org/licenses/by-sa/3.0/
 

Redistributions of the source code, or parts of the source codes, must retain the copyright notice, this list of conditions and the following disclaimer (all at the top of each source code) and requires the written permission from DataMelt.

Redistribution in binary form of all or parts of a class must reproduce the copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution and requires the written permission of ScaVis

Details about license agreement or commercial use are: http://jwork.org/scavis/ */ package jhpro.nnet; import java.io.*; import java.util.Enumeration; import java.util.Vector; /** * * Backpropagation is a supervised learning algorithm and is mainly used by * Multi-Layer-Perceptrons to change the weights connected to the net's hidden * neuron layer(s). * * The backpropagation algorithm uses a computed output error to change the * weight values in backward direction. * * To get this net error, a forwardpropagation phase must have been done before. * While propagating in forward direction, the neurons are being activated using * the sigmoid activation function. * */ public class BackpropagationNet extends NeuralNet { /** * Construct Backpropagation. */ public BackpropagationNet() { super.learningCycle = 0; super.maxLearningCycles = -1; minimumError = 0.00050000000000000001D; super.learningRate = 0.25D; error = 1000D; multiplier = 0; accuracy = 0.20000000000000001D; neuronLayerVector = new Vector(); super.stopLearning = false; resetTime(); } /** * Adds a neuron layer with size neurons. Note that neuron layers are * sequentially added to the net. * * @param i */ public void addNeuronLayer(int i) { neuronLayerVector.addElement(new NeuronLayer(i * multiplier)); } /** * Connects all neuron layers with weight matrices. Must be called after all * neuron layers have been added. */ public void connectLayers() { weightMatrixArray = new WeightMatrix[neuronLayerVector.size() - 1]; neuronLayerArray = new NeuronLayer[neuronLayerVector.size()]; int i = 0; for (Enumeration enumeration = neuronLayerVector.elements(); enumeration .hasMoreElements();) neuronLayerArray[i++] = (NeuronLayer) enumeration.nextElement(); neuronLayerVector = null; for (int j = 0; j < weightMatrixArray.length; j++) { weightMatrixArray[j] = new WeightMatrix(neuronLayerArray[j].size(), neuronLayerArray[j + 1].size(), true); weightMatrixArray[j].init(); } lastLayer = neuronLayerArray.length - 1; lastMatrix = weightMatrixArray.length - 1; } /** * Sets the minimum error of a neural net. * * @param d */ public void setMinimumError(double d) { minimumError = d; } /** * Returns the minimum error of a neural net. */ public double getMinimumError() { return minimumError; } /** * Sets the accuracy value. * * @param d */ public void setAccuracy(double d) { accuracy = d; } /** * Returns the accuracy value. * * @return */ public double getAccuracy() { return accuracy; } /** * Returns the weight values of weight matrix matrixNr. The values for * matrixNr start with zero! * * @param i * @return */ public float[][] getWeightValues(int i) { return weightMatrixArray[i].getWeights(); } /** * Returns the output values of all neurons in layer i * @param i layer * @return */ public float[] getNeuronOutputs(int i) { return neuronLayerArray[i].getOutput(); } public int getNumberOfLayers() { return neuronLayerArray.length; } public int getNumberOfNeurons(int i) { return neuronLayerArray[i].size(); } public int getNumberOfWeights() { int i = 0; for (int j = 0; j <= lastMatrix; j++) i += weightMatrixArray[j].size(); return i; } public int getNumberOfWeights(int i) { return weightMatrixArray[i].size(); } public int getNumberOfPatterns() { return inputPatternArray.length; } public String getInputPattern(int i) { return inputPatternArray[i].getPatternString(); } /** * Returns the target pattern with number patternNr. * * @param i * @return */ public String getTargetPattern(int i) { return targetPatternArray[i].getPatternString(); } /** * Returns the output pattern with number patternNr. * * @param i * @return */ public String getOutputPattern(int i) { String s = new String(); String s1 = new String(); float f = 0.0F; for (int j = 0; j < layerOutputError[0].length; j++) { float f1 = targetPatternArray[i].getValue(j) - layerOutputError[i][j]; s1 += (double) f1 >= accuracy / 10D ? "1" : "0"; } s = ""; for (int k = 0; k < s1.length(); k += multiplier) s += getAsciiValue(s1.substring(k, k + multiplier)); return s; } /** * Returns the error of output pattern patternNr. * * @param i * @return */ public float getPatternError(int i) { float f = 0.0F; for (int j = 0; j < layerOutputError[0].length; j++) f += Math.abs(layerOutputError[i][j]); return f; } /** * Returns the current error of the net. * * @return */ public double getError() { return error; } /** * Performs one learning step. */ public void learn() { if (error > minimumError && (super.learningCycle < super.maxLearningCycles || super.maxLearningCycles == -1)) { super.learningCycle++; for (int i = 0; i <= lastPattern; i++) { neuronLayerArray[0].setInput(inputPatternArray[i]); for (int j = 1; j <= lastLayer; j++) { neuronLayerArray[j].computeInput(neuronLayerArray[j - 1], weightMatrixArray[j - 1]); neuronLayerArray[j].computeOutput(); } neuronLayerArray[lastLayer] .computeLayerError(targetPatternArray[i]); layerOutputError[i] = neuronLayerArray[lastLayer] .getLayerError(); for (int k = lastMatrix; k >= 0; k--) { weightMatrixArray[k].changeWeights( neuronLayerArray[k].getOutput(), neuronLayerArray[k + 1].getLayerError(), super.learningRate); if (k > 0) neuronLayerArray[k].computeLayerError( neuronLayerArray[k + 1], weightMatrixArray[k]); } } double d = 0.0D; for (int l = 0; l < layerOutputError.length; l++) { for (int i1 = 0; i1 < layerOutputError[0].length; i1++) d += square(layerOutputError[l][i1]); } error = Math.abs(d * 0.5D); return; } else { super.stopLearning = true; return; } } /** * Tries to recall the correct output for a learned input pattern * recallInput. * * @param s * @return */ public String recall(String s) { Pattern pattern = new Pattern(s, conversionTable); float af[] = new float[targetPatternArray[0].size()]; neuronLayerArray[0].setInput(pattern); for (int i = 1; i <= lastLayer; i++) { neuronLayerArray[i].computeInput(neuronLayerArray[i - 1], weightMatrixArray[i - 1]); neuronLayerArray[i].computeOutput(); } af = neuronLayerArray[lastLayer].getOutput(); String s2; String s1 = s2 = ""; for (int j = 0; j < af.length; j++) s1 += (double) af[j] >= accuracy ? "1" : "0"; for (int k = 0; k < s1.length(); k += multiplier) s2 += getAsciiValue(s1.substring(k, k + multiplier)); return s2; } /** * Reads a conversion table for ASCII-binary values from file * conversionFileName. * * @param s */ public synchronized void readConversionFile(String s) { Object obj = null; DataInputStream datainputstream; try { datainputstream = new DataInputStream(new FileInputStream(s)); int i = Integer.parseInt(datainputstream.readLine()); conversionTable = new String[i][2]; for (int j = 0; j < i; j++) { String s1 = datainputstream.readLine(); conversionTable[j][0] = String.valueOf(s1.charAt(0)); conversionTable[j][1] = s1.substring(1); } multiplier = conversionTable[0][1].length(); return; } catch (FileNotFoundException _ex) { error(105); return; } catch (IOException _ex) { error(104); } } public String getAsciiValue(String s) { int i = 0; int j = conversionTable.length; boolean flag = false; boolean flag1 = false; while (i < j) { int k = i + j >> 1; int l = s.compareTo(conversionTable[k][1]); if (l == 0) return conversionTable[k][0]; if (l > 0) i = k; else j = k; } return "*"; } public synchronized void readPatternFile(String s) { Object obj = null; try { DataInputStream datainputstream = new DataInputStream( new FileInputStream(s)); try { int i = Integer.parseInt(datainputstream.readLine()); int j = Integer.parseInt(datainputstream.readLine()); if (j * multiplier != neuronLayerArray[0].size()) error(106); int k = Integer.parseInt(datainputstream.readLine()); if (k * multiplier != neuronLayerArray[lastLayer].size()) error(107); inputPatternArray = new Pattern[i]; targetPatternArray = new Pattern[i]; outputPatternArray = new String[i]; lastPattern = inputPatternArray.length - 1; layerOutputError = new float[lastPattern + 1][neuronLayerArray[lastLayer] .size()]; for (int l = 0; l < i; l++) { String s1 = datainputstream.readLine(); if (s1 == null) error(102); else if (s1.length() != j + k + 1) { error(100); } else { inputPatternArray[l] = new Pattern(s1.substring(0, j), conversionTable); targetPatternArray[l] = new Pattern( s1.substring(j + 1), conversionTable); outputPatternArray[l] = new String(); } } return; } catch (EOFException _ex) { error(102); } return; } catch (FileNotFoundException _ex) { error(105); return; } catch (IOException _ex) { error(104); } } Vector neuronLayerVector; NeuronLayer neuronLayerArray[]; WeightMatrix weightMatrixArray[]; Pattern inputPatternArray[]; Pattern targetPatternArray[]; String outputPatternArray[]; double minimumError; double error; double accuracy; float layerOutputError[][]; String conversionTable[][]; int lastLayer; int lastMatrix; int lastPattern; int multiplier; }

Ads help maintain this website.