Java tutorial
/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 F. Herrera (herrera@decsai.ugr.es) L. Snchez (luciano@uniovi.es) J. Alcal-Fdez (jalcala@decsai.ugr.es) S. Garca (sglopez@ujaen.es) A. Fernndez (alberto.fernandez@ujaen.es) J. Luengo (julianlm@decsai.ugr.es) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ **********************************************************************/ package keel.Algorithms.Neural_Networks.NNEP_Common.neuralnet; import java.util.ArrayList; import javolution.xml.XmlElement; import javolution.xml.XmlFormat; import org.apache.commons.lang.builder.HashCodeBuilder; /** * <p> * @author Written by Pedro Antonio Gutierrez Penya, Aaron Ruiz Mora (University of Cordoba) 17/07/2007 * @version 0.1 * @since JDK1.5 * </p> */ public abstract class AbstractNeuralNet implements INeuralNet { /** * <p> * Implementation of a neural net * </p> */ ///////////////////////////////////////////////////////////////// // ------------------------------------- Marshal/unmarshal format ///////////////////////////////////////////////////////////////// /** * <p> * Marshal/Unmarshal input layer, hidden layers and output layer * </p> */ protected static final javolution.xml.XmlFormat<AbstractNeuralNet> XML = new XmlFormat<AbstractNeuralNet>( AbstractNeuralNet.class) { public void format(AbstractNeuralNet source, XmlElement xml) { // Marshal input layer xml.add(source.inputLayer, "input-layer"); // Marshal hidden layers xml.add(source.hiddenLayers, "hidden-layers"); // Marshal output layers xml.add(source.outputLayer, "output-layer"); } public AbstractNeuralNet parse(XmlElement xml) { // Resulting object AbstractNeuralNet result = (AbstractNeuralNet) xml.object(); // Unmarshal input layer result.inputLayer = xml.<InputLayer>get("input-layer"); // Unmarshal hidden layers result.hiddenLayers = xml.<ArrayList<LinkedLayer>>get("hidden-layers"); // Update neuron references ILayer<? extends INeuron> previousLayer = result.inputLayer; for (LinkedLayer hiddenLayer : result.hiddenLayers) { for (int i = 0; i < hiddenLayer.getNofneurons(); i++) { Link[] links = hiddenLayer.getNeuron(i).getLinks(); for (int j = 0; j < links.length; j++) { links[j].setTarget(hiddenLayer.getNeuron(i)); if (!links[j].isBroken() && j < previousLayer.getMaxnofneurons()) links[j].setOrigin(previousLayer.getNeuron(j)); else links[j].setOrigin(null); } } previousLayer = hiddenLayer; } // Unmarshal output layer result.outputLayer = xml.<LinkedLayer>get("output-layer"); // Update neuron references for (int i = 0; i < result.outputLayer.getNofneurons(); i++) { Link[] links = ((LinkedNeuron) result.outputLayer.getNeuron(i)).getLinks(); for (int j = 0; j < links.length; j++) { links[j].setTarget(result.outputLayer.getNeuron(i)); if (!links[j].isBroken() && j < previousLayer.getMaxnofneurons()) links[j].setOrigin(previousLayer.getNeuron(j)); else links[j].setOrigin(null); } } // Return result return result; } public String defaultName() { return "neural-net"; } }; ///////////////////////////////////////////////////////////////// // --------------------------------------- Serialization constant ///////////////////////////////////////////////////////////////// /** Generated by eclipse */ private static final long serialVersionUID = -5162585162983545056L; ///////////////////////////////////////////////////////////////// // ------------------------------------------ Protected Variables ///////////////////////////////////////////////////////////////// /** Input layer */ protected InputLayer inputLayer; /** Hidden layer */ protected ArrayList<LinkedLayer> hiddenLayers = new ArrayList<LinkedLayer>(); /** Ouput layer */ protected LinkedLayer outputLayer; ///////////////////////////////////////////////////////////////// // -------------------------------------------------- Constructor ///////////////////////////////////////////////////////////////// /** * <p> * Empty constructor * </p> */ public AbstractNeuralNet() { super(); } ///////////////////////////////////////////////////////////////// // ---------------------------- Implementing INeuralNet interface ///////////////////////////////////////////////////////////////// /** * <p> * Returns the number of hidden layers of the neural net * </p> * @return int Number of hidden layers */ public int getNofhlayers() { return hiddenLayers.size(); } /** * <p> * Returns the input layer of this neural net * </p> * @return InputLayer Input layer of the net */ public InputLayer getInputLayer() { return inputLayer; } /** * <p> * Sets the input layer of this neural net * </p> * @param inputLayer New input layer of the net */ public void setInputLayer(InputLayer inputLayer) { this.inputLayer = inputLayer; } /** * <p> * Adds a new layer to the neural net * </p> * @param layer New layer */ public void addHlayer(LinkedLayer layer) { hiddenLayers.add(layer); } /** * <p> * Returns a specific hidden layer of the neural net * </p> * @param index Number of layer to return * @return LinkedLayer Hidden layer */ public LinkedLayer getHlayer(int index) { return hiddenLayers.get(index); } /** * <p> * Returns the output layer of this neural net * </p> * @return LinkedLayer Output layer of the net */ public LinkedLayer getOutputLayer() { return outputLayer; } /** * <p> * Sets the output layer of this neural net * </p> * @param outputLayer New output layer of the net */ public void setOutputLayer(LinkedLayer outputLayer) { this.outputLayer = outputLayer; } /** * <p> * Checks if this neural net is equal to another * </p> * @param other Other neural net to compare * @return true if both neural nets are equals */ public boolean equals(INeuralNet other) { if (this.hashCode() != other.hashCode()) return false; else return true; } /** * <p> * Returns an integer number that identifies the neural net * </p> * @return int Hashcode */ public int hashCode() { HashCodeBuilder hcb = new HashCodeBuilder(61, 67); hcb.append(outputLayer); return hcb.toHashCode(); } /** * <p> * Checks if this neural net is full of neurons * </p> * @return true if the neural net is full of neurons */ public boolean neuronsFull() { for (LinkedLayer layer : hiddenLayers) { if (!layer.neuronsFull()) return false; } return true; } /** * <p> * Checks if this neural net is empty of neurons * </p> * @return true if the neural net is empty of neurons */ public boolean neuronsEmpty() { for (LinkedLayer layer : hiddenLayers) { if (!layer.neuronsEmpty()) return false; } return true; } /** * <p> * Checks if this neural net is full of links * </p> * @return true if the neural net is full of links */ public boolean linksFull() { // If here is not hidden layers if (hiddenLayers.size() == 0) { if (!outputLayer.linksFull(inputLayer)) return false; } else { // First hidden layer with input layer if (!hiddenLayers.get(0).linksFull(inputLayer)) return false; // Hidden layer with its previous hidden layer for (int i = 1; i < hiddenLayers.size(); i++) if (!hiddenLayers.get(i).linksFull(hiddenLayers.get(i - 1))) return false; // Output layer with the last hidden layer if (!outputLayer.linksFull(hiddenLayers.get(hiddenLayers.size() - 1))) return false; } return true; } /** * <p> * Checks if this neural net is empty of links * </p> * @return true if the neural net is empty of links */ public boolean linksEmpty() { for (LinkedLayer layer : hiddenLayers) { if (!layer.linksEmpty()) return false; } if (!outputLayer.linksEmpty()) return false; return true; } /** * <p> * Returns the number of hidden neurons of this neural net * </p> * @return int Number of hidden neurons */ public int getNofhneurons() { int nofhneurons = 0; for (LinkedLayer layer : hiddenLayers) { nofhneurons += layer.getNofneurons(); } return nofhneurons; } /** * <p> * Returns the number of effective links of this neural net * </p> * @return int Number of effective links */ public int getNoflinks() { int noflinks = 0; for (LinkedLayer layer : hiddenLayers) { noflinks += layer.getNoflinks(); } noflinks += outputLayer.getNoflinks(); return noflinks; } /** * <p> * Keep relevant links, that is, those links whose weight is higher * than certain number * </p> * @param significativeWeight Significative weight */ public void keepRelevantLinks(double significativeWeight) { for (LinkedLayer layer : hiddenLayers) { layer.keepRelevantLinks(significativeWeight); } outputLayer.keepRelevantLinks(significativeWeight); } /** * <p> * Returns a string representation of the neural net * </p> * @return String Representation of the neural net */ public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < outputLayer.getNofneurons(); i++) { String neuron = outputLayer.getNeuron(i).toString(); neuron = neuron.replace("+-", "-"); neuron = neuron.replace("-+", "-"); neuron = neuron.replace("--", "+"); // Add " " at the end of the string so the next step works correctly neuron += " "; // Add a "\n" at the end of each node int count = 0; for (int j = 0; j < neuron.length(); j++) { if (neuron.charAt(j) == '(') count++; if (neuron.charAt(j) == ')') { count--; if (count == 0) neuron = neuron.substring(0, j + 1) + "\n" + neuron.substring(j + 2, neuron.length()); } } sb.append(neuron); } return sb.toString(); } /** * <p> * Returns a copy of this neural net * </p> * @return INeuralNet Copy of this neural net */ public INeuralNet copy() { // Resulting neural net AbstractNeuralNet result = null; try { result = this.getClass().newInstance(); // Copy the input layer result.inputLayer = this.inputLayer.copy(); // Copy hidden layers ILayer<? extends INeuron> lastCopiedLayer = result.inputLayer; for (LinkedLayer hl : this.hiddenLayers) { // Copy hidden layer LinkedLayer hlr = hl.copy(lastCopiedLayer); result.addHlayer(hlr); // Update last copied layer lastCopiedLayer = hlr; } // Copy the output layer result.outputLayer = this.outputLayer.copy(lastCopiedLayer); } catch (InstantiationException e) { System.out.println("Instantiation Error " + e.getLocalizedMessage()); e.printStackTrace(); } catch (IllegalAccessException e) { System.out.println("Illegal Access Error " + e.getLocalizedMessage()); e.printStackTrace(); } return result; } }