/** * @author Steven L. Moxley * @version 1.2 */ package org.futurist.neuralnet; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.math3.distribution.AbstractRealDistribution; import org.apache.commons.math3.distribution.BetaDistribution; import org.apache.commons.math3.distribution.CauchyDistribution; import org.apache.commons.math3.distribution.ChiSquaredDistribution; import org.apache.commons.math3.distribution.ExponentialDistribution; import org.apache.commons.math3.distribution.FDistribution; import org.apache.commons.math3.distribution.NormalDistribution; import org.apache.commons.math3.distribution.TDistribution; import org.apache.commons.math3.distribution.UniformRealDistribution; import org.apache.commons.math3.distribution.WeibullDistribution; import org.futurist.neuralnet.Network; public class Playground { public static void main(String[] args) { final int tests = 5; // test results ConcurrentHashMap<String, Double> defaultTest = new ConcurrentHashMap<String, Double>(); ConcurrentHashMap<String, Double> distTest = new ConcurrentHashMap<String, Double>(); ConcurrentHashMap<Integer, Double> numLevelsTest = new ConcurrentHashMap<Integer, Double>(); ConcurrentHashMap<Integer, Double> numLayerNodesTest = new ConcurrentHashMap<Integer, Double>(); ConcurrentHashMap<Integer, Double> numEdgesTest = new ConcurrentHashMap<Integer, Double>(); ConcurrentHashMap<Double, Double> learnRateTest = new ConcurrentHashMap<Double, Double>(); ConcurrentHashMap<Double, Double> learnScaleTest = new ConcurrentHashMap<Double, Double>(); ConcurrentHashMap<Integer, Double> numRoundsTest = new ConcurrentHashMap<Integer, Double>(); String outputFile = "C:\\Users\\smoxley\\Downloads\\network-stats.txt"; // default values to use prior to testing Integer numLevels = 3; // 1 hidden layer usually sufficient Integer inNodes = 10; // number of input nodes Integer outNodes = 13; // number of output nodes Integer lNodes = (inNodes * outNodes) / 2; // number of nodes per hidden layer Integer numEdges = 2 * inNodes; AbstractRealDistribution dist = new ChiSquaredDistribution(inNodes*outNodes); // NormalDistribution() also good Double learnRate = 0.025; // 1.7 and 1.11 also good Double learnScale = 1.25; // linear dampening; 0.5 and 1.0 also good for(int t = 0; t < tests; t++) { System.out.println("Running test " + t + "..."); // random ideal values for training/learning Double[] idealVals = new Double[outNodes]; Random idealSeeder = new Random(); for(int i = 0; i < idealVals.length; i++) { idealVals[i] = idealSeeder.nextDouble(); } // default network Network defaultNet = new Network(0, dist, inNodes, lNodes, outNodes, numEdges, numLevels, learnRate, learnScale, idealVals, 100, 100, 100); //System.out.println("Ideal Values: " + defaultNet.getIdealValues().length + "\tOutput Nodes: " + defaultNet.getOutputNodes().size()); defaultNet.run(); if(defaultTest.contains(dist.toString())) { defaultTest.replace("Default Network", defaultNet.getAverageError() + defaultTest.get(dist.toString())); } else { defaultTest.put("Default Network", defaultNet.getAverageError()); } //defaultNet.printNodes(); //defaultNet.printEdges(); File output = new File(outputFile); try { FileWriter writer = new FileWriter(output); writer.write(defaultNet.getStats()); writer.close(); } catch (IOException e) { e.printStackTrace(); } // test initial weighting by distribution ArrayList<AbstractRealDistribution> dists = new ArrayList<AbstractRealDistribution>(); dists.add(new BetaDistribution(inNodes*outNodes, numEdges)); dists.add(new CauchyDistribution()); dists.add(new ChiSquaredDistribution(inNodes*outNodes)); dists.add(new ExponentialDistribution(inNodes*outNodes)); dists.add(new FDistribution(inNodes*outNodes, numEdges)); dists.add(new NormalDistribution()); dists.add(new TDistribution(inNodes*outNodes)); dists.add(new UniformRealDistribution()); dists.add(new WeibullDistribution(inNodes*outNodes, numEdges)); for(AbstractRealDistribution d : dists) { //System.out.println("Varying DISTRIBUTION, currently testing " + d.toString() + " with defaults of numLayers=" + numLevels + ", inputNeurons=" + inNodes + ", layerNodes=" + lNodes + ", outputNeurons=" + outNodes + ", numSynapses=" + numEdges + ", learningRate=" + learnRate + ", and learningScale=" + learnScale + "."); Network nn = new Network(1, d, inNodes, lNodes, outNodes, numEdges, numLevels, learnRate, learnScale, idealVals, 100, 100, 100); //System.out.println("Ideal Values: " + nn.getTargetValues().length + "\tOutput Nodes: " + nn.getOutputNodes().size()); nn.run(); String distName = d.toString().split("@")[0]; if(distTest.contains(distName)) { distTest.replace(distName, nn.getAverageError() + distTest.get(distName)); } else { distTest.put(distName, nn.getAverageError()); } //nn.printStats(); } // test optimal number of functional units/hidden layers among 0, 1, 2, [inputs+outputs]/2, [inputs+outputs] ArrayList<Integer> numLayers = new ArrayList<Integer>(); numLayers.add(3); numLayers.add(4); numLayers.add(5); numLayers.add(inNodes); numLayers.add(outNodes); numLayers.add((inNodes+outNodes) / 2); for(Integer i : numLayers) { //System.out.println("Varying HIDDEN LAYERS, currently testing " + i + " with defaults of " + dist.toString() + ", numNeurons=" + ", inputNeurons=" + inNodes + ", layerNodes=" + lNodes + ", outputNeurons=" + outNodes + ", numSynapses=" + numEdges + ", learningRate=" + learnRate + ", and learningScale=" + learnScale + "."); Network nn = new Network(2, dist, inNodes, lNodes, outNodes, numEdges, i, learnRate, learnScale, idealVals, 100, 100, 100); nn.run(); if(numLevelsTest.contains(i)) { numLevelsTest.replace(i, nn.getAverageError() + numLevelsTest.get(i)); } else { numLevelsTest.put(i, nn.getAverageError()); } //nn.printStats(); } // test optimal number of neurons per functional unit/hidden layer among [inputs+outputs]/2, [inputs+outputs] ArrayList<Integer> numNeurons = new ArrayList<Integer>(); numNeurons.add(inNodes); numNeurons.add(outNodes); numNeurons.add(inNodes + outNodes); numNeurons.add((inNodes*outNodes) / 2); numNeurons.add(inNodes * numEdges); numNeurons.add(outNodes * numEdges); for(Integer i : numNeurons) { //System.out.println("Varying NUMBER OF NEURONS, currently testing " + i + " with defaults of " + dist.toString() + ", numLayers=" + numLevels + ", numSynapses=" + numEdges + ", learningRate=" + learnRate + ", and learningScale=" + learnScale + "."); Network nn = new Network(3, dist, inNodes, i, outNodes, numEdges, numLevels, learnRate, learnScale, idealVals, 100, 100, 100); nn.run(); if(numLayerNodesTest.contains(i)) { numLayerNodesTest.replace(i, nn.getAverageError() + numLayerNodesTest.get(i)); } else { numLayerNodesTest.put(i, nn.getAverageError()); } //nn.printStats(); } // test optional number of synapses in the network among 2*numNodes, numNodes*numLevels, numNodes^2, ArrayList<Integer> numSynapses = new ArrayList<Integer>(); numSynapses.add(2 * inNodes); numSynapses.add(2 * outNodes); numSynapses.add(inNodes * numLevels); numSynapses.add(outNodes * numLevels); numSynapses.add(inNodes * outNodes); numSynapses.add(inNodes * outNodes * numLevels); numSynapses.add(new Double(Math.pow(inNodes, 2)).intValue()); numSynapses.add(new Double(Math.pow(outNodes, 2)).intValue()); for(Integer i : numSynapses) { //System.out.println("Varying NUMBER OF SYNAPSES, currently testing " + i + " with defaults of " + dist.toString() + ", numLayers=" + numLevels + ", inputNeurons=" + inNodes + ", layerNodes=" + lNodes + ", outputNeurons=" + outNodes + ", learningRate=" + learnRate + ", and learningScale=" + learnScale + "."); Network nn = new Network(4, dist, inNodes, lNodes, outNodes, i, numLevels, learnRate, learnScale, idealVals, 100, 100, 100); nn.run(); if(numEdgesTest.contains(i)) { numEdgesTest.replace(i, nn.getAverageError() + numEdgesTest.get(i)); } else { numEdgesTest.put(i, nn.getAverageError()); } //nn.printStats(); } // test optimal learning rate from 0.01 to 2.00 stepping by 0.1 for(Double i = 0.01; i < 2.00; i += 0.1) { //System.out.println("Varying LEARNING RATE, currently testing " + i + " with defaults of " + dist.toString() + ", numLayers=" + numLevels + ", inputNeurons=" + inNodes + ", layerNodes=" + lNodes + ", outputNeurons=" + outNodes + ", numSynapses=" + numEdges + ", and learningScale=" + learnScale + "."); Network nn = new Network(5, dist, inNodes, lNodes, outNodes, numEdges, numLevels, i, learnScale, idealVals, 100, 100, 100); nn.run(); if(learnRateTest.contains(i)) { learnRateTest.replace(i, nn.getAverageError() + learnRateTest.get(i)); } else { learnRateTest.put(i, nn.getAverageError()); } //nn.printStats(); } // test optimal learning scale, varying according to 0.25n to 2.0n stepping by 0.25 for(Double i = 0.25; i < 2.00; i += 0.25) { //System.out.println("Varying LEARNING SCALE, currently testing " + i + " with defaults of " + dist.toString() + ", numLayers=" + numLevels + ", inputNeurons=" + inNodes + ", layerNodes=" + lNodes + ", outputNeurons=" + outNodes + ", numSynapses=" + numEdges + ", and learningRate=" + learnRate + "."); Network nn = new Network(5, dist, inNodes, lNodes, outNodes, numEdges, numLevels, learnRate, i, idealVals, 100, 100, 100); nn.run(); if(learnScaleTest.contains(i)) { learnScaleTest.replace(i, nn.getAverageError() + learnScaleTest.get(i)); } else { learnScaleTest.put(i, nn.getAverageError()); } //nn.printStats(); } // test optimal number of rounds from 2, 5, 10, 25, 100 ArrayList<Integer> rounds = new ArrayList<Integer>(); rounds.add(2); rounds.add(5); rounds.add(10); rounds.add(25); rounds.add(100); for(Integer i : rounds) { //System.out.println("Varying NUMBER OF ROUNDS, currently testing " + i + " with defaults of " + dist.toString() + ", numLayers=" + numLevels + ", inputNeurons=" + inNodes + ", layerNodes=" + lNodes + ", outputNeurons=" + outNodes + ", numSynapses=" + numEdges + ", learningRate=" + learnRate + ", and learningScale=" + learnScale + "."); Network nn = new Network(6, dist, inNodes, lNodes, outNodes, numEdges, numLevels, learnRate, learnScale, idealVals, 100, 100, 100); nn.setSimulationSettings(i, true); nn.run(); if(numRoundsTest.contains(i)) { numRoundsTest.replace(i, nn.getAverageError() + numRoundsTest.get(i)); } else { numRoundsTest.put(i, nn.getAverageError()); } //nn.printStats(); } System.out.println(); } System.out.print("DEFAULT NETWORK'S average error:\t"); for(String p : defaultTest.keySet()) { System.out.println(defaultTest.get(p) / tests); } System.out.println(); System.out.println("Varying DISTRIBUTION parameter average error:"); for(String p : distTest.keySet()) { System.out.println("\t" + p + ":\t" + distTest.get(p) / tests); } System.out.println(); System.out.println("Varying HIDDEN LAYERS parameter average error:"); for(Integer p : numLevelsTest.keySet()) { System.out.println("\t" + p + ":\t" + numLevelsTest.get(p) / tests); } System.out.println(); System.out.println("Varying NUMBER OF NEURONS parameter average error:"); for(Integer p : numLayerNodesTest.keySet()) { System.out.println("\t" + p + ":\t" + numLayerNodesTest.get(p) / tests); } System.out.println(); System.out.println("Varying NUMBER OF SYNAPSES parameter average error:"); for(Integer p : numEdgesTest.keySet()) { System.out.println("\t" + p + ":\t" + numEdgesTest.get(p) / tests); } System.out.println(); System.out.println("Varying LEARNING RATE parameter average error:"); for(Double p : learnRateTest.keySet()) { System.out.println("\t" + p + ":\t" + learnRateTest.get(p) / tests); } System.out.println(); System.out.println("Varying LEARNING SCALE parameter average error:"); for(Double p : learnScaleTest.keySet()) { System.out.println("\t" + p + ":\t" + learnScaleTest.get(p) / tests); } System.out.println(); System.out.println("Varying NUMBER OF ROUNDS parameter average error:"); for(Integer p : numRoundsTest.keySet()) { System.out.println("\t" + p + ":\t" + numRoundsTest.get(p) / tests); } System.out.println(); } }