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 LinkedLayer implements ILayer<LinkedNeuron> { /** * <p> * Base implementation of a hidden or output layer * </p> */ ///////////////////////////////////////////////////////////////// // ------------------------------------- Marshal/unmarshal format ///////////////////////////////////////////////////////////////// /** * <p> * Marshal/Unmarshal initial number of neurons, maximum number of * neurons, each neuron, layer type, weigth range, and a boolean * indicating if the layer is input-biased * </p> */ protected static final javolution.xml.XmlFormat<LinkedLayer> XML = new XmlFormat<LinkedLayer>( LinkedLayer.class) { public void format(LinkedLayer source, XmlElement xml) { // Marshal initialmaxnofneurons xml.setAttribute("initial-max-n-of-neurons", source.initialmaxnofneurons); // Marshal initialminnofneurons xml.setAttribute("min-n-of-neurons", source.minnofneurons); // Marshal maxnofneurons xml.setAttribute("max-n-of-neurons", source.maxnofneurons); // Marshal type xml.setAttribute("type", source.type); // Marshal biased xml.setAttribute("biased", source.biased); // Marshal each neuron xml.add(source.neurons, "neurons"); } public LinkedLayer parse(XmlElement xml) { // Resulting object LinkedLayer result = (LinkedLayer) xml.object(); // Unmarshal initialmaxnofneurons result.initialmaxnofneurons = xml.getAttribute("initial-max-n-of-neurons", 1); // Unmarshal maxnofneurons result.minnofneurons = xml.getAttribute("min-n-of-neurons", 1); // Unmarshal maxnofneurons result.maxnofneurons = xml.getAttribute("max-n-of-neurons", 1); // Unmarshal type result.type = xml.getAttribute("type", HIDDEN_LAYER); // Unmarshal biased result.biased = xml.getAttribute("biased", false); // Unmarshal each neuron result.neurons = xml.<ArrayList<LinkedNeuron>>get("neurons"); // Return result return result; } public String defaultName() { return "linked-layer"; } }; ///////////////////////////////////////////////////////////////// // ------------------------------------------------ Type of layer ///////////////////////////////////////////////////////////////// /** Defines hidden layer type */ public static final int HIDDEN_LAYER = 1; /** Defines output layer type */ public static final int OUTPUT_LAYER = 2; ///////////////////////////////////////////////////////////////// // --------------------------------------------------- Attributes ///////////////////////////////////////////////////////////////// /** Minimum number of neurons for the net */ protected int minnofneurons; /** Initial maximum number of neurons for the net */ protected int initialmaxnofneurons; /** Maximum number of neurons for the layer */ protected int maxnofneurons; /** Array of neurons of the layer */ protected ArrayList<LinkedNeuron> neurons = new ArrayList<LinkedNeuron>(); /** Type of layer (HIDDEN_LAYER or OUTPUT_LAYER) */ protected int type = 0; /** Is biased? */ protected boolean biased; ///////////////////////////////////////////////////////////////// // -------------------------------------------------- Constructor ///////////////////////////////////////////////////////////////// /** * <p> * Empty constructor * </p> */ public LinkedLayer() { super(); } ///////////////////////////////////////////////////////////////// // ------------------------------- Getting and setting attributes ///////////////////////////////////////////////////////////////// /** * <p> * Returns the minimum number of neurons of this layer * </p> * @return int Minimum number of neurons */ public int getMinnofneurons() { return minnofneurons; } /** * <p> * Sets the minimum number of neurons of this layer * </p> * @param initialnofneurons Minimum number of neurons */ public void setMinnofneurons(int minofneurons) { this.minnofneurons = minofneurons; } /** * <p> * Returns the initial maximum number of neurons of this layer * </p> * @return int Initial maximum number of neurons */ public int getInitialmaxnofneurons() { return initialmaxnofneurons; } /** * Sets the initial maximum number of neurons of this layer (without BIAS) * @param initialnofneurons Initial number of neurons */ public void setInitialmaxnofneurons(int initialmaxnofneurons) { this.initialmaxnofneurons = initialmaxnofneurons; } /** * <p> * Returns the type of this layer * </p> * @return int Type of layer */ public int getType() { return type; } /** * <p> * Sets the type of this layer * </p> * @param type New type of layer */ public void setType(int type) { this.type = type; } /** * <p> * Returns true if the layer has a bias neuron * </p> * @return true if the layer has a bias neuron */ public boolean isBiased() { return biased; } /** * <p> * Sets a boolean indicating if the layer has a bias neuron * </p> * @param isBiased Boolean has bias neuron */ public void setBiased(boolean isBiased) { this.biased = isBiased; } ///////////////////////////////////////////////////////////////// // -------------------------------- Implementing ILayer interface ///////////////////////////////////////////////////////////////// /** * <p> * Returns the maximum number of neurons of this layer * </p> * @return int Maximum number of neurons */ public int getMaxnofneurons() { return maxnofneurons; } /** * <p> * Sets the maximum number of neurons of this layer * </p> * @param maxnofneurons Number of neurons */ public void setMaxnofneurons(int maxnofneurons) { this.maxnofneurons = maxnofneurons; } /** * <p> * Add a neuron to the layer * </p> * @param neuron New neuron to add to the layer */ public void addNeuron(LinkedNeuron neuron) { //Control the number of neurons if (neurons.size() == maxnofneurons) return; //Add the neuron neurons.add(neuron); } /** * <p> * Removes a neuron of the layer * </p> * @param neuron Neuron to remove * @return true if the neuron has been removes */ public boolean removeNeuron(LinkedNeuron neuron) { //Control the number of neurons if (neurons.size() == minnofneurons) return false; return neurons.remove(neuron); } /** * <p> * Removes a neuron of the layer using its index * </p> * @param index Index of the neuron to remove * @return LinkedNeuron Neuron removed */ public LinkedNeuron removeNeuron(int index) { return neurons.remove(index); } /** * <p> * Returns a neuron of the layer using its index * </p> * @param index Index of the neuron to remove * @return LinkedNeuron Neuron removed */ public LinkedNeuron getNeuron(int index) { return neurons.get(index); } /** * <p> * Returns the number of neurons of this layer * </p> * @return int Number of neurons */ public int getNofneurons() { return neurons.size(); } /** * <p> * Checks if this layer is equal to another * </p> * @param other Other layer to compare * @return true if both layers are equal */ public boolean equals(ILayer<LinkedNeuron> other) { if (this.hashCode() != other.hashCode()) return false; else return true; } /** * <p> * Returns an integer number that identifies the layer * </p> * @return int Hashcode */ public int hashCode() { HashCodeBuilder hcb = new HashCodeBuilder(41, 43); for (INeuron neuron : neurons) hcb.append(neuron); return hcb.toHashCode(); } ///////////////////////////////////////////////////////////////// // ----------------------------------------------- Public methods ///////////////////////////////////////////////////////////////// /** * <p> * Checks if this layer is full of neurons * </p> * @return true if the layer is full of neurons */ public boolean neuronsFull() { if (neurons.size() >= maxnofneurons) return true; else return false; } /** * <p> * Checks if this layer is empty of neurons * </p> * @return true if the layer is empty of neurons */ public boolean neuronsEmpty() { if (neurons.size() == 0) return true; else return false; } /** * <p> * Checks if this layer is full of links * </p> * @return true if the layer is full of links */ public boolean linksFull(ILayer<? extends INeuron> previous) { if (!biased) { for (LinkedNeuron neuron : neurons) if (neuron.getNoflinks() < previous.getNofneurons()) return false; } else { for (LinkedNeuron neuron : neurons) if (neuron.getNoflinks() - 1 < previous.getNofneurons()) return false; } return true; } /** * <p> * Checks if this layer is empty of links * </p> * @return true if the layer is empty of links */ public boolean linksEmpty() { for (LinkedNeuron neuron : neurons) { if ((neuron.isBiased() && neuron.getNoflinks() > 1) || (!neuron.isBiased() && neuron.getNoflinks() > 0)) return false; } return true; } /** * <p> * Returns the number of effective links of the layer * </p> * @return int Number of effective links */ public int getNoflinks() { int noflinks = 0; for (LinkedNeuron neuron : neurons) noflinks += neuron.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 (LinkedNeuron neuron : neurons) neuron.keepRelevantLinks(significativeWeight); } /** * <p> * Returns a copy of this linked layer * </p> * @param previousLayer Previous layer to which copied neurons * are going to be linked * @return LinkedLayer Copy of this linked layer */ public LinkedLayer copy(ILayer<? extends INeuron> previousLayer) { LinkedLayer result = null; try { // Generate new layer result = this.getClass().newInstance(); // Copy properties of the layer result.setMinnofneurons(this.minnofneurons); result.setInitialmaxnofneurons(this.initialmaxnofneurons); result.setMaxnofneurons(this.maxnofneurons); result.setType(this.type); result.setBiased(this.biased); // Copy each neuron for (LinkedNeuron neuron : this.neurons) result.addNeuron(neuron.copy(previousLayer)); } 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; } ///////////////////////////////////////////////////////////////// // --------------------------------------------- Abstract methods ///////////////////////////////////////////////////////////////// /** * <p> * New neuron for the layer * </p> * @return LinkedNeuron New neuron for the layer */ public abstract LinkedNeuron obtainNewNeuron(); }