/* * Encog(tm) Core v2.5 - Java Version * http://www.heatonresearch.com/encog/ * http://code.google.com/p/encog-java/ * Copyright 2008-2010 Heaton Research, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * For more information on Heaton Research copyrights, licenses * and trademarks visit: * http://www.heatonresearch.com/copyright */ package org.encog.neural.networks.training.genetic; import org.encog.mathutil.randomize.Randomizer; import org.encog.neural.networks.BasicNetwork; import org.encog.neural.networks.training.BasicTraining; import org.encog.neural.networks.training.CalculateScore; import org.encog.solve.genetic.GeneticAlgorithm; import org.encog.solve.genetic.crossover.Splice; import org.encog.solve.genetic.genome.Genome; import org.encog.solve.genetic.mutate.MutatePerturb; import org.encog.solve.genetic.population.BasicPopulation; import org.encog.solve.genetic.population.Population; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Implements a genetic algorithm that allows a feedforward or simple recurrent * neural network to be trained using a genetic algorithm. * * There are essentially two ways you can make use of this class. * * Either way, you will need a score object. The score object tells the genetic * algorithm how well suited a neural network is. * * If you would like to use genetic algorithms with a training set you should * make use TrainingSetScore class. This score object uses a training set to * score your neural network. * * If you would like to be more abstract, and not use a training set, you can * create your own implementation of the CalculateScore method. This class can * then score the networks any way that you like. */ public class NeuralGeneticAlgorithm extends BasicTraining { /** * Very simple class that implements a genetic algorithm. * * @author jheaton */ public class NeuralGeneticAlgorithmHelper extends GeneticAlgorithm { /** * @return The error from the last iteration. */ public double getError() { final Genome genome = getPopulation().getBest(); return genome.getScore(); } /** * Get the current best neural network. * * @return The current best neural network. */ public BasicNetwork getNetwork() { final Genome genome = getPopulation().getBest(); return (BasicNetwork) genome.getOrganism(); } } /** * The logging object. */ private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * Simple helper class that implements the required methods to implement a * genetic algorithm. */ private NeuralGeneticAlgorithmHelper genetic; /** * Construct a neural genetic algorithm. * * @param network * The network to base this on. * @param randomizer * The randomizer used to create this initial population. * @param calculateScore * The score calculation object. * @param populationSize * The population size. * @param mutationPercent * The percent of offspring to mutate. * @param percentToMate * The percent of the population allowed to mate. */ public NeuralGeneticAlgorithm(final BasicNetwork network, final Randomizer randomizer, final CalculateScore calculateScore, final int populationSize, final double mutationPercent, final double percentToMate) { this.genetic = new NeuralGeneticAlgorithmHelper(); this.genetic.setCalculateScore(new GeneticScoreAdapter(calculateScore)); final Population population = new BasicPopulation(populationSize); getGenetic().setMutationPercent(mutationPercent); getGenetic().setMatingPopulation(percentToMate * 2); getGenetic().setPercentToMate(percentToMate); getGenetic().setCrossover( new Splice(network.getStructure().calculateSize() / 3)); getGenetic().setMutate(new MutatePerturb(4.0)); getGenetic().setPopulation(population); for (int i = 0; i < population.getPopulationSize(); i++) { final BasicNetwork chromosomeNetwork = (BasicNetwork) network .clone(); randomizer.randomize(chromosomeNetwork); final NeuralGenome genome = new NeuralGenome(this, chromosomeNetwork); getGenetic().calculateScore(genome); getGenetic().getPopulation().add(genome); } population.sort(); } /** * @return The genetic algorithm implementation. */ public NeuralGeneticAlgorithmHelper getGenetic() { return this.genetic; } /** * @return The network that is being trained. */ public BasicNetwork getNetwork() { return getGenetic().getNetwork(); } /** * Perform one training iteration. */ public void iteration() { if (this.logger.isInfoEnabled()) { this.logger.info("Performing Genetic iteration."); } preIteration(); getGenetic().iteration(); setError(getGenetic().getError()); postIteration(); } /** * Set the genetic helper class. * * @param genetic * The genetic helper class. */ public void setGenetic(final NeuralGeneticAlgorithmHelper genetic) { this.genetic = genetic; } }