keel.Algorithms.Neural_Networks.NNEP_Common.NeuralNetIndividualSpecies.java Source code

Java tutorial

Introduction

Here is the source code for keel.Algorithms.Neural_Networks.NNEP_Common.NeuralNetIndividualSpecies.java

Source

/***********************************************************************
    
   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;

import keel.Algorithms.Neural_Networks.NNEP_Common.neuralnet.INeuralNet;
import keel.Algorithms.Neural_Networks.NNEP_Common.neuralnet.InputLayer;
import keel.Algorithms.Neural_Networks.NNEP_Common.neuralnet.LinkedLayer;
import net.sf.jclec.IConfigure;
import net.sf.jclec.util.range.Interval;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationRuntimeException;
import org.apache.commons.lang.builder.EqualsBuilder;

/**
 * <p>
 * @author Written by Pedro Antonio Gutierrez Penia (University of Cordoba) 16/7/2007
 * @author Written by Aaron Ruiz Mora (University of Cordoba) 16/7/2007
 * @version 0.1
 * @since JDK1.5
 * </p>
 */

public class NeuralNetIndividualSpecies extends AbstractNeuralNetSpecies<NeuralNetIndividual>
        implements IConfigure {
    /**
     * <p>
     * Individuals that use a INeuralNet as genotype
     * </p>
     */

    /////////////////////////////////////////////////////////////////
    // --------------------------------------- Serialization constant
    /////////////////////////////////////////////////////////////////

    /** Generated by Eclipse */
    private static final long serialVersionUID = 2813451004932981929L;

    /////////////////////////////////////////////////////////////////
    // ------------------------------------------------- Constructors
    /////////////////////////////////////////////////////////////////

    /**
     * <p>
     * Empty constructor
     * </p>
     */

    public NeuralNetIndividualSpecies() {
        super();
    }

    /////////////////////////////////////////////////////////////////
    // ------------------------------------------- Setting properties
    /////////////////////////////////////////////////////////////////

    /**
     * <p>
     * Sets number of hidden layers of the neural nets
     * 
     * @param nOfHiddenLayers Number of hidden layers
     * </p>
     */

    public void setNOfHiddenLayers(int nOfHiddenLayers) {
        this.nOfHiddenLayers = nOfHiddenLayers;
    }

    /**
     * <p>
     * Sets number of inputs of the neural nets
     * 
     * @param nOfInputs Number of hidden layers
     * </p>
     */

    public void setNOfInputs(int nOfInputs) {
        this.nOfInputs = nOfInputs;
    }

    /**
     * <p>
     * Sets number of outputs of the neural nets
     * 
     * @param nOfInputs Number of hidden layers
     * </p>
     */

    public void setNOfOutputs(int nOfOutputs) {
        this.nOfOutputs = nOfOutputs;
    }

    /**
     * <p>
     * Sets weight range of a hidden layer
     * 
     * @param index Index of the desired hidden layer
     * @param indexRange Index of the desired range into the layer (useful for hibrid layer) 
     * @param hiddenLayerWeightRange New weight range
     * </p>
     */

    public void setHiddenLayerWeightRange(int index, int indexRange, Interval hiddenLayerWeightRange) {
        this.weightRanges[index][indexRange] = hiddenLayerWeightRange;
    }

    /**
     * <p>
     * Sets weight range of the output layer
     * 
     * @param indexRange Index of the desired range into the layer (useful for hibrid layer) 
     * @param outputLayerWeightRange New weight range
     * </p>
     */

    public void setOutputLayerWeightRange(int indexRange, Interval outputLayerWeightRange) {
        this.weightRanges[weightRanges.length - 1][indexRange] = outputLayerWeightRange;
    }

    /**
     * <p>
     * Sets maximum number of neurons of a hidden layer
     * 
     * @param index Index of the desired hidden layer
     * @param hiddenLayerMaxNofneurons Maximum number of neurons
     * </p>
     */

    public void setHiddenLayerMaxNofneurons(int index, int hiddenLayerMaxNofneurons) {
        this.maxNofneurons[index] = hiddenLayerMaxNofneurons;
    }

    /**
     * <p>
     * Sets minimum number of neurons of a hidden layer
     * 
     * @param index Index of the desired hidden layer
     * @param hiddenLayerMaxNofneurons Minimum number of neurons
     * </p>
     */

    public void setHiddenLayerMinNofneurons(int index, int hiddenLayerMinNofneurons) {
        this.minNofneurons[index] = hiddenLayerMinNofneurons;
    }

    /**
     * <p>
     * Sets initial maximum number of neurons of a hidden layer
     * 
     * @param index Index of the desired hidden layer
     * @param hiddenLayerInitialNofneurons Initial maximum number of neurons
     * </p>
     */

    public void setHiddenLayerInitialNofneurons(int index, int hiddenLayerInitialMaxNofneurons) {
        this.initialMaxNofneurons[index] = hiddenLayerInitialMaxNofneurons;
    }

    /**
     * <p>
     * Sets type of neurons of a hidden layer
     * 
     * @param index Index of the desired hidden layer
     * @param hiddenLayerType Type of neurons
     * </p>
     */

    public void setHiddenLayerType(int index, String hiddenLayerType) {
        this.type[index] = hiddenLayerType;
    }

    /**
     * <p>
     * Sets type of neurons of the output layer
     * 
     * @param outputLayerType Type of neurons
     * </p>
     */

    public void setOutputLayerType(String outputLayerType) {
        this.type[type.length - 1] = outputLayerType;
    }

    /**
     * <p>
     * Sets initiator of neurons of a hidden layer
     * 
     * @param index Index of the desired hidden layer
     * @param hiddenLayerInitiator Initiator of neurons
     * </p>
     */

    public void setHiddenLayerInitiator(int index, String hiddenLayerInitiator) {
        this.initiator[index] = hiddenLayerInitiator;
    }

    /**
     * <p>
     * Sets initiator of neurons of the output layer
     * 
     * @param outputLayerInitiator Initiator of neurons
     * </p>
     */

    public void setOutputLayerInitiator(String outputLayerInitiator) {
        this.initiator[initiator.length - 1] = outputLayerInitiator;
    }

    /**
     * <p>
     * Sets a boolean indicating if a hidden layer is biased
     * 
     * @param index Index of the desired hidden layer
     * @param hiddenLayerBiased Is hidden layer biased?
     * </p>
     */

    public void setHiddenLayerBiased(int index, boolean hiddenLayerBiased) {
        this.biased[index] = hiddenLayerBiased;
    }

    /**
     * <p>
     * Sets a boolean indicating if the output layer is biased
     * 
     * @param outputLayerBiased Is output layer biased?
     * </p>
     */

    public void setOutputLayerBiased(boolean outputLayerBiased) {
        this.biased[biased.length - 1] = outputLayerBiased;
    }

    /**
     * <p>
     * Sets an array of neuron types of a concrete layer
     * (this is an hibrid layer)
     * 
     * @param index Index of the desired hidden layer
     * @param neuronTypes Array of neurons types
     * </p>
     */

    public void setNeuronTypes(int index, String[] neuronTypes) {
        this.neuronTypes[index] = neuronTypes;
    }

    /**
     * <p>
     * Sets an array of percentages of a concrete layer
     * (this is an hibrid layer)
     * 
     * @param index Index of the desired hidden layer
     * @param percentages Array of percentages
     * </p>
     */

    public void setPercentages(int index, double[] percentages) {
        this.percentages[index] = percentages;
    }

    /**
     * <p>
     * Sets an array of initiators of neurons of hibrid layers
     * 
     * @param index Index of the desired hidden layer
     * @param initiatorNeuronTypes Array of initiators of neurons
     * </p>
     */

    public void setInitiatorNeuronTypes(int index, String[] initiatorNeuronTypes) {
        this.initiatorNeuronTypes[index] = initiatorNeuronTypes;
    }

    /////////////////////////////////////////////////////////////////
    // --------------------- Implementing INeuralNetSpecies interface
    /////////////////////////////////////////////////////////////////

    /**
     * <p>
     * Creates a new individual
     * @return A NeuraNetIndividual
     * </p>
     */

    public NeuralNetIndividual createIndividual() {
        return new NeuralNetIndividual();
    }

    /**
     * <p>
     * Creates a new individual
     * @param genotype Genotype of the individual
     * @return A NeuraNetIndividual
     * </p>
     */
    public NeuralNetIndividual createIndividual(INeuralNet genotype) {
        return new NeuralNetIndividual(genotype);
    }

    /**
     * <p>
     * Creates the genotype of the individual
     * @return The Genotype
     * <(p>
     */

    @SuppressWarnings("unchecked")
    public INeuralNet createGenotype() {
        INeuralNet result = null;

        // New neural net
        try {
            Class<INeuralNet> neuralNetClass = (Class<INeuralNet>) Class.forName(neuralNetType);

            // Range instance
            result = neuralNetClass.newInstance();

            //Generate topology
            generateTopology(result);

            //Set input layer number of neurons
            result.getInputLayer().setMaxnofneurons(nOfInputs);
        } catch (ClassNotFoundException e) {
            throw new ConfigurationRuntimeException("Illegal neural net classname");
        } catch (InstantiationException e) {
            throw new ConfigurationRuntimeException("Problems creating an instance of " + type, e);
        } catch (IllegalAccessException e) {
            throw new ConfigurationRuntimeException("Problems creating an instance of " + type, e);
        }

        return result;
    }

    /////////////////////////////////////////////////////////////////
    // ---------------------------------------------- Private methods
    /////////////////////////////////////////////////////////////////

    /**
     * <p>
     * Generate topology of a INeuralNet
     * 
     * @param neuralNet New neural net genotype
     * </p>
     */

    private void generateTopology(INeuralNet neuralNet) {
        //Input Layer
        InputLayer inputLayer = new InputLayer();
        neuralNet.setInputLayer(inputLayer);

        try {
            //Each hidden Layer
            for (int i = 0; i < nOfHiddenLayers; i++) {
                LinkedLayer hiddenLayer = (LinkedLayer) Class.forName(getHiddenLayerType(i)).newInstance();
                hiddenLayer.setType(LinkedLayer.HIDDEN_LAYER);
                neuralNet.addHlayer(hiddenLayer);
            }

            //Output Layer
            LinkedLayer outputLayer = (LinkedLayer) Class.forName(getOutputLayerType()).newInstance();
            outputLayer.setType(LinkedLayer.OUTPUT_LAYER);
            neuralNet.setOutputLayer(outputLayer);

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /////////////////////////////////////////////////////////////////
    // ----------------------------------- Overwriting Object methods
    /////////////////////////////////////////////////////////////////

    /**
     * <p>
     * Compare two individuals
     * @return True if the two individuals are equals
     * </p>
     */

    public boolean equals(Object other) {
        if (other instanceof NeuralNetIndividualSpecies) {
            EqualsBuilder eb = new EqualsBuilder();
            NeuralNetIndividualSpecies nnoth = (NeuralNetIndividualSpecies) other;
            eb.append(this.neuralNetType, nnoth.neuralNetType);
            eb.append(this.nOfInputs, nnoth.nOfInputs);
            eb.append(this.nOfHiddenLayers, nnoth.nOfHiddenLayers);
            eb.append(this.nOfOutputs, nnoth.nOfOutputs);
            eb.append(this.weightRanges, nnoth.weightRanges);
            eb.append(this.maxNofneurons, nnoth.maxNofneurons);
            eb.append(this.minNofneurons, nnoth.minNofneurons);
            eb.append(this.initialMaxNofneurons, nnoth.initialMaxNofneurons);
            eb.append(this.type, nnoth.type);
            eb.append(this.initiator, nnoth.initiator);
            eb.append(this.biased, nnoth.biased);
            eb.append(this.neuronTypes, nnoth.neuronTypes);
            eb.append(this.percentages, nnoth.percentages);
            eb.append(this.initiatorNeuronTypes, nnoth.initiatorNeuronTypes);
            return eb.isEquals();
        } else {
            return false;
        }
    }

    /////////////////////////////////////////////////////////////////
    // ---------------------------- Implementing IConfigure interface
    /////////////////////////////////////////////////////////////////

    /**
     * <p>
     * Configuration parameters for this species are:
     * 
     * 
     * input-layer.number-of-inputs (int)
     *  Number of inputs. Number of inputs of this species neural nets.
     *
     * output-layer.number-of-outputs (int)
     *  Number of inputs. Number of outputs of this species neural nets.
     * 
     * hidden-layer(i).weight-range (complex)
     *  Weigth range of the hidden layer number "i".
     * 
     * output-layer.weight-range (complex)
     *  Weigth range of the outputlayer.
     *  
     * hidden-layer(i).maximum-number-of-neurons (int)
     *  Maximum number of neurons of hidden layer number "i".
     * 
     * hidden-layer(i).initial-number-of-neurons (int)
     *  Initial number of neurons of hidden layer number "i".
     * 
     * hidden-layer(i)[@type] (string)
     *  Layer type of the hidden layer number "i".
     *  
     * output-layer[@type] (string)
     *  Layer type of the output layer.
     * 
     * hidden-layer(i)[@biased] (string)
     *  Boolean indicating if hidden layer number "i" is biased.
     * 
     * output-layer[@type] (string)
     *  Boolean indicating if the output layer is biased.
     *  
     *  @param configutation Configuration if the Individual
     * </p>
     */

    @SuppressWarnings("unchecked")
    public void configure(Configuration configuration) {
        // -------------------------------------- Setup neuralNetType
        neuralNetType = configuration.getString("neural-net-type");

        // -------------------------------------- Setup nOfHiddenLayers 
        nOfHiddenLayers = configuration.getList("hidden-layer[@type]").size();

        // -------------------------------------- Setup nOfInputs 
        //nOfInputs = configuration.getInt("input-layer.number-of-inputs");

        // -------------------------------------- Setup nOfOutputs
        //nOfOutputs = configuration.getInt("output-layer.number-of-outputs");

        // Initialize arrays
        maxNofneurons = new int[nOfHiddenLayers];
        minNofneurons = new int[nOfHiddenLayers];
        initialMaxNofneurons = new int[nOfHiddenLayers];
        type = new String[nOfHiddenLayers + 1];
        initiator = new String[nOfHiddenLayers + 1];
        biased = new boolean[nOfHiddenLayers + 1];

        weightRanges = new Interval[nOfHiddenLayers + 1][];
        neuronTypes = new String[nOfHiddenLayers + 1][];
        percentages = new double[nOfHiddenLayers + 1][];
        initiatorNeuronTypes = new String[nOfHiddenLayers + 1][];
        for (int i = 0; i < nOfHiddenLayers + 1; i++) {
            String header;

            if (i != nOfHiddenLayers) {
                header = "hidden-layer(" + i + ")";
                // ---------------------------------- Setup maxNofneurons array
                maxNofneurons[i] = configuration.getInt(header + ".maximum-number-of-neurons");
                // ---------------------------------- Setup minNofneurons array
                minNofneurons[i] = configuration.getInt(header + ".minimum-number-of-neurons");
                // ---------------------------------- Setup initialMaxNofneurons array
                initialMaxNofneurons[i] = configuration.getInt(header + ".initial-maximum-number-of-neurons");
                // ---------------------------------- Setup initiator array
                initiator[i] = configuration.getString(header + ".initiator-of-links");
            } else {
                header = "output-layer";
                // ---------------------------------- Setup initiator array
                initiator[i] = configuration.getString(header + ".initiator-of-links");
            }

            //  ----------------------------------------- Setup type array
            type[i] = configuration.getString(header + "[@type]");

            //  ----------------------------------------- Setup biased array
            biased[i] = configuration.getBoolean(header + "[@biased]");

            // -------------------------------------- Setup weight ranges array
            weightRanges[i] = new Interval[1];
            try {
                // Range name
                String rangeName = header + ".weight-range";
                // Range classname
                String rangeClassname = configuration.getString(rangeName + "[@type]");
                // Range class
                Class<Interval> rangeClass = (Class<Interval>) Class.forName(rangeClassname);
                // Range instance
                Interval range = rangeClass.newInstance();
                // Configura range
                range.configure(configuration.subset(rangeName));
                // Set range
                if (i != nOfHiddenLayers)
                    setHiddenLayerWeightRange(i, 0, range);
                else
                    setOutputLayerWeightRange(0, range);
            } catch (ClassNotFoundException e) {
                throw new ConfigurationRuntimeException("Illegal range classname");
            } catch (InstantiationException e) {
                throw new ConfigurationRuntimeException("Problems creating an instance of range", e);
            } catch (IllegalAccessException e) {
                throw new ConfigurationRuntimeException("Problems creating an instance of range", e);
            }
        }
    }
}