상속: BasicMLDataSet, IMLDataSet, INeuralDataSet
예제 #1
0
        public override void CalculateResult()
        {
            Console.WriteLine(@"SVM Results:");

            var testSet = new BasicNeuralDataSet(TestSet, IdealTestOutput);
            var values = new List<double[]>();
            var result = new List<double[]>();

            foreach (var input in testSet)
            {
                var output = Svm.Compute(input.Input);

                Console.WriteLine(input.Input[0] + @", actual=" + output[0] + @", ideal=" + input.Ideal[0]);

                var tmp = new double[input.Input.Count];
                input.Input.CopyTo(tmp,0,input.Input.Count);
                values.Add(tmp);

                var tmp2 = new double[output.Count];
                output.CopyTo(tmp2, 0, output.Count);
                result.Add(tmp2);
            }

            ResultTestSet = new BasicNeuralDataSet(values.ToArray(), result.ToArray());

            Console.WriteLine("Done");
        }
        /// <summary>
        ///   Measure the performance of the network
        /// </summary>
        /// <param name = "network">Network to analyze</param>
        /// <param name = "dataset">Dataset with input and ideal data</param>
        /// <returns>Error % of correct bits, returned by the network.</returns>
        public static double MeasurePerformance(BasicNetwork network, BasicNeuralDataSet dataset)
        {
            int correctBits = 0;
            float threshold = 0.0f;
            IActivationFunction activationFunction = network.GetActivation(network.LayerCount - 1); //get the activation function of the output layer
            if (activationFunction is ActivationSigmoid)
            {
                threshold = 0.5f; /* > 0.5, range of sigmoid [0..1]*/
            }
            else if (activationFunction is ActivationTANH)
            {
                threshold = 0.0f; /*> 0, range of bipolar sigmoid is [-1..1]*/
            }
            else
                throw new ArgumentException("Bad activation function");
            int n = (int) dataset.Count;

            Parallel.For(0, n, (i) =>
                               {
                                   IMLData actualOutputs = network.Compute(dataset.Data[i].Input);
                                   lock (LockObject)
                                   {
                                       for (int j = 0, k = actualOutputs.Count; j < k; j++)
                                           if ((actualOutputs[j] > threshold && dataset.Data[i].Ideal[j] > threshold)
                                               || (actualOutputs[j] < threshold && dataset.Data[i].Ideal[j] < threshold))
                                               correctBits++;
                                   }
                               });

            long totalOutputBitsCount = dataset.Count*dataset.Data[0].Ideal.Count;

            return (double) correctBits/totalOutputBitsCount;
        }
        /// <summary>
        /// Generate a random training set. 
        /// </summary>
        /// <param name="seed">The seed value to use, the same seed value will always produce
        /// the same results.</param>
        /// <param name="count">How many training items to generate.</param>
        /// <param name="inputCount">How many input numbers.</param>
        /// <param name="idealCount">How many ideal numbers.</param>
        /// <param name="min">The minimum random number.</param>
        /// <param name="max">The maximum random number.</param>
        /// <returns>The random training set.</returns>
        public static BasicNeuralDataSet Generate(long seed,
                int count, int inputCount,
                int idealCount, double min, double max)
        {

            LinearCongruentialGenerator rand =
                new LinearCongruentialGenerator(seed);

            BasicNeuralDataSet result = new BasicNeuralDataSet();
            for (int i = 0; i < count; i++)
            {
                INeuralData inputData = new BasicNeuralData(inputCount);

                for (int j = 0; j < inputCount; j++)
                {
                    inputData.Data[j] = rand.Range(min, max);
                }

                INeuralData idealData = new BasicNeuralData(idealCount);

                for (int j = 0; j < idealCount; j++)
                {
                    idealData[j] = rand.Range(min, max);
                }

                BasicNeuralDataPair pair = new BasicNeuralDataPair(inputData,
                        idealData);
                result.Add(pair);

            }
            return result;
        }
        /// <summary>
        /// Clone this object.
        /// </summary>
        /// <returns>A clone of this object.</returns>
        public override object Clone()
        {
            BasicNeuralDataSet result = new BasicNeuralDataSet();

            foreach (INeuralDataPair pair in this.Data)
            {
                result.Add((INeuralDataPair)pair.Clone());
            }
            return(result);
        }
예제 #5
0
        public void LoadTrainingData(ref BasicNeuralDataSet trainingSet, ref BasicNeuralDataSet validationSet)
        {
            ParseTrainingModel(TrainingModel);

            var trainSetCount = (int)(Input.Count() * ((100.0 - ValidationSetSize) / 100));

            Input.Shuffle();
            Output.Shuffle();
            MyExtensions.ResetStableShuffle();

            trainingSet = new BasicNeuralDataSet(Input.Take(trainSetCount).ToArray(), Output.Take(trainSetCount).ToArray());
            validationSet = new BasicNeuralDataSet(Input.Skip(trainSetCount).ToArray(), Output.Skip(trainSetCount).ToArray());
        }
        public void Execute(IExampleInterface app)
        {
            //Specify the number of dimensions and the number of neurons per dimension
            int dimensions = 2;
            int numNeuronsPerDimension = 7;

            //Set the standard RBF neuron width. 
            //Literature seems to suggest this is a good default value.
            double volumeNeuronWidth = 2.0 / numNeuronsPerDimension;

            //RBF can struggle when it comes to flats at the edge of the sample space.
            //We have added the ability to include wider neurons on the sample space boundary which greatly
            //improves fitting to flats
            bool includeEdgeRBFs = true;

            #region Setup
            //General setup is the same as before
            RadialBasisPattern pattern = new RadialBasisPattern();
            pattern.InputNeurons = dimensions;
            pattern.OutputNeurons = 1;

            //Total number of neurons required.
            //Total number of Edges is calculated possibly for future use but not used any further here
            int numNeurons = (int)Math.Pow(numNeuronsPerDimension, dimensions);
            int numEdges = (int)(dimensions * Math.Pow(2, dimensions - 1));

            pattern.AddHiddenLayer(numNeurons);

            BasicNetwork network = pattern.Generate();
            RadialBasisFunctionLayer rbfLayer = (RadialBasisFunctionLayer)network.GetLayer(RadialBasisPattern.RBF_LAYER);
            network.Reset();

            //Position the multidimensional RBF neurons, with equal spacing, within the provided sample space from 0 to 1.
            rbfLayer.SetRBFCentersAndWidthsEqualSpacing(0, 1, RBFEnum.Gaussian, dimensions, volumeNeuronWidth, includeEdgeRBFs);            
            
            #endregion

            //Create some training data that can not easily be represented by gaussians
            //There are other training examples for both 1D and 2D
            //Degenerate training data only provides outputs as 1 or 0 (averaging over all outputs for a given set of inputs would produce something approaching the smooth training data).
            //Smooth training data provides true values for the provided input dimensions.
            Create2DSmoothTainingDataGit();

            //Create the training set and train.
            INeuralDataSet trainingSet = new BasicNeuralDataSet(INPUT, IDEAL);
            ITrain train = new SVDTraining(network, trainingSet);

            //SVD is a single step solve
            int epoch = 1;
            do
            {
                train.Iteration();
                Console.WriteLine("Epoch #" + epoch + " Error:" + train.Error);
                epoch++;
            } while ((epoch < 1) && (train.Error > 0.001));

            // test the neural network
            Console.WriteLine("Neural Network Results:");

            //Create a testing array which may be to a higher resoltion than the original training data
            Set2DTestingArrays(100);
            trainingSet = new BasicNeuralDataSet(INPUT, IDEAL);

            //Write out the results data
            using (var sw = new System.IO.StreamWriter("results.csv", false))
            {
                foreach (INeuralDataPair pair in trainingSet)
                {
                    INeuralData output = network.Compute(pair.Input);
                    //1D//sw.WriteLine(InverseScale(pair.Input[0]) + ", " + Chop(InverseScale(output[0])));// + ", " + pair.Ideal[0]);
                    sw.WriteLine(InverseScale(pair.Input[0]) + ", " + InverseScale(pair.Input[1]) + ", " + Chop(InverseScale(output[0])));// + ", " + pair.Ideal[0]);// + ",ideal=" + pair.Ideal[0]);
                    //3D//sw.WriteLine(InverseScale(pair.Input[0]) + ", " + InverseScale(pair.Input[1]) + ", " + InverseScale(pair.Input[2]) + ", " + Chop(InverseScale(output[0])));// + ", " + pair.Ideal[0]);// + ",ideal=" + pair.Ideal[0]);
                    //Console.WriteLine(pair.Input[0] + ", actual=" + output[0] + ",ideal=" + pair.Ideal[0]);
                }
            }

            Console.WriteLine("\nFit output saved to results.csv");
            Console.WriteLine("\nComplete - Please press the 'any' key to close.");
            Console.ReadKey();
        }
예제 #7
0
        public virtual void CalculateResult()
        {
            var values = new List<double[]>();
            var result = new List<double[]>();

            foreach (var input in TestSet)
            {
                var output = new double[Network.OutputSize];
                Network.Model.Compute(input, output);

                values.Add(input);
                result.Add(output);
            }

            ResultTestSet = new BasicNeuralDataSet(values.ToArray(), result.ToArray());
        }
        /// <summary>
        /// Mencari solusi model neural network
        /// </summary>
        private void searchSolution()
        {
            // Normalize Data
            switch (this.selectedActivationFunction)
            {
                case ActivationFunctionEnumeration.SemiLinearFunction:
                    this.activationFunction = new SemiLinearFunction();
                    this.normalizeData(0.1, 0.9);
                    break;
                case ActivationFunctionEnumeration.SigmoidFunction:
                    this.activationFunction = new SigmoidFunction();
                    this.normalizeData(0.1, 0.9);
                    break;
                case ActivationFunctionEnumeration.BipolarSigmoidFunction:
                    this.activationFunction = new BipolarSigmoidFunction();
                    this.normalizeData(-0.9, 0.9);
                    break;
                case ActivationFunctionEnumeration.HyperbolicTangentFunction:
                    this.activationFunction = new HyperbolicTangentFunction();
                    this.normalizeData(-0.9, 0.9);
                    break;
                default:
                    this.activationFunction = new BipolarSigmoidFunction();
                    this.normalizeData(-0.9, 0.9);
                    break;
            }

            //create network
            this.network = new BasicNetwork();
            this.network.AddLayer(new FeedforwardLayer(this.activationFunction, this.inputLayerNeurons));
            this.network.AddLayer(new FeedforwardLayer(this.activationFunction, this.hiddenLayerNeurons));
            this.network.AddLayer(new FeedforwardLayer(this.activationFunction, this.outputLayerNeurons));
            this.network.Reset();

            //variable for looping
            //needToStop = false;
            double mse = 0.0, error = 0.0, mae=0.0;
            int iteration = 1;

            // parameters
            double msle = 0.0, mspe = 0.0, generalizationLoss = 0.0, pq = 0.0;
            double[] trainingErrors = new double[this.strip];
            for (int i = 0; i < this.strip; i++) trainingErrors[i] = double.MaxValue / strip;

            double lastMSE = double.MaxValue;

            // advanced early stopping
            int n = this.data.Length - this.network.InputLayer.NeuronCount;
            int validationSet = (int)Math.Round(this.validationSetRatio * n);
            int trainingSet = n - validationSet;
            double[][] networkTrainingInput = new double[trainingSet][];
            double[][] networkTrainingOutput = new double[trainingSet][];
            for (int i = 0; i < trainingSet; i++)
            {
                networkTrainingInput[i] = new double[this.network.InputLayer.NeuronCount];
                networkTrainingOutput[i] = new double[1];
            }
            for (int i = 0; i < trainingSet; i++)
            {
                for (int j = 0; j < this.network.InputLayer.NeuronCount; j++)
                {
                    networkTrainingInput[i][j] = this.networkInput[i][j];
                }
                networkTrainingOutput[i][0] = this.networkOutput[i][0];
            }

            // validation set
            double[] solutionValidation = new double[validationSet];
            double[] inputForValidation = new double[this.network.InputLayer.NeuronCount];
            double[] inputForValidationNetwork = new double[this.network.InputLayer.NeuronCount];

            // array for saving neural weights and parameters
            this.bestValidationError = double.MaxValue;
            this.bestWeightMatrix = new double[this.network.Layers.Count -1][,];
            this.bestSolution = new double[n];

            for (int i = 0; i < this.network.Layers.Count - 1; i++)
            {
                this.bestWeightMatrix[i] = new double[this.network.Layers[i].WeightMatrix.Rows, this.network.Layers[i].WeightMatrix.Cols];
            }

            //best network criterion
            double bestNetworkError = double.MaxValue, bestNetworkMSE = double.MaxValue, bestNetworkMAE = double.MaxValue;

            // build array for graph
            this.solutionData = new double[n];
            this.predictedPoint = new cPoint[n];
            this.validationPoint = new cPoint[validationSet];

            //initialize point for graph
            predictedDS.Samples = predictedPoint;
            validationDS.Samples = validationPoint;
            this.predictedDS.Active = true;

            // prepare training data
            INeuralDataSet dataset;
            if (this.useAdvanceEarlyStopping)
                dataset = new BasicNeuralDataSet(networkTrainingInput, networkTrainingOutput);
            else
                dataset = new BasicNeuralDataSet(this.networkInput, this.networkOutput);

            // initialize trainer
            this.learning = new Backpropagation(this.network, dataset, this.learningRate, this.momentum);

            //training
            while (!needToStop)
            {
                double sse = 0.0;
                double sae = 0.0;
                double ssle = 0.0;
                double sspe = 0.0;

                this.learning.Iteration();
                error = learning.Error;

                if (this.useAdvanceEarlyStopping)
                {
                    this.validationDS.Active = true;
                }
                else
                {
                    this.validationDS.Active = false;
                }

                for (int i = 0; i < n; i++)
                {
                    INeuralData neuraldata = new BasicNeuralData(this.networkInput[i]);

                    this.solutionData[i] = (this.network.Compute(neuraldata)[0]
                        - this.minNormalizedData) / this.factor + this.minData;

                    this.predictedPoint[i].x = i + this.network.InputLayer.NeuronCount;
                    this.predictedPoint[i].y = (float)this.solutionData[i];

                    sse += Math.Pow(this.solutionData[i] - this.data[i + this.network.InputLayer.NeuronCount], 2);
                    sae += Math.Abs(this.solutionData[i] - this.data[i + this.network.InputLayer.NeuronCount]);

                    //calculate advance early stopping
                    if (this.useAdvanceEarlyStopping)
                    {
                        if (i < n - validationSet)
                        {
                            ssle += Math.Pow(this.solutionData[i] - this.data[i + this.network.InputLayer.NeuronCount], 2);
                        }
                        else
                        {

                            // initialize the first validation set input
                            if (i == n - validationSet)
                            {
                                for (int j = 0; j < this.network.InputLayer.NeuronCount; j++)
                                {
                                    inputForValidation[this.network.InputLayer.NeuronCount - 1 - j] = this.data[this.data.Length - (n - i) - 1 - j];
                                }
                            }

                            for (int j = 0; j < this.network.InputLayer.NeuronCount; j++)
                            {
                                inputForValidationNetwork[j] = (inputForValidation[j] - this.minData) * this.factor + this.minNormalizedData;
                            }

                            INeuralData neuraldataval = new BasicNeuralData(inputForValidationNetwork);
                            solutionValidation[i - n + validationSet] = (this.network.Compute(neuraldataval)[0] - this.minNormalizedData) / this.factor + this.minData;

                            this.validationPoint[i - n + validationSet].x = i + this.network.InputLayer.NeuronCount;
                            this.validationPoint[i - n + validationSet].y = (float)solutionValidation[i - n + validationSet];

                            sspe += Math.Pow(this.data[i + this.network.InputLayer.NeuronCount] - solutionValidation[i - n + validationSet], 2);

                            // initialize the next validation set input from the current validation set input
                            for (int j = 0; j < this.network.InputLayer.NeuronCount - 1; j++)
                            {
                                inputForValidation[j] = inputForValidation[j + 1];
                            }

                            inputForValidation[this.network.InputLayer.NeuronCount - 1] = solutionValidation[i - n + validationSet];

                        }
                    }

                }

                mse = sse / this.solutionData.Length;
                mae = sae / this.solutionData.Length;

                //Console.WriteLine(error.ToString());

                //Display it
                this.iterationBox.Text = iteration.ToString();
                this.maeBox.Text = mae.ToString("F5");
                this.mseBox.Text = mse.ToString("F5");
                this.errorBox.Text = error.ToString("F5");

                seriesGraph.Refresh();

                if (this.useAdvanceEarlyStopping)
                {
                    //calculate advance early stopping 2
                    mspe = sspe / validationSet;
                    msle = ssle / (this.solutionData.Length - validationSet);

                    //save best weight
                    if (this.bestValidationError > mspe)
                    {
                        this.bestValidationError = mspe;
                        this.bestSolution = this.solutionData;

                        // weight matrix
                        for (int i = 0; i < this.network.Layers.Count - 1; i++)
                            for (int j = 0; j < this.network.Layers[i].WeightMatrix.Rows; j++)
                                for (int k = 0; k < this.network.Layers[i].WeightMatrix.Cols; k++)
                                    this.bestWeightMatrix[i][j,k] = this.network.Layers[i].WeightMatrix[j, k];

                        bestNetworkError = error;
                        bestNetworkMAE = mae;
                        bestNetworkMSE = mse;

                    }
                    //calculate generalization loss &pq
                    generalizationLoss = 100 * (mspe / this.bestValidationError - 1);

                    trainingErrors[(iteration - 1) % this.strip] = msle;
                    double minStripTrainingError = double.MaxValue, sumStripTrainingError = 0.0;
                    for (int i = 0; i < this.strip; i++)
                    {
                        sumStripTrainingError += trainingErrors[i];
                        if (trainingErrors[i] < minStripTrainingError) minStripTrainingError = trainingErrors[i];
                    }
                    double trainingProgress = 1000 * ((sumStripTrainingError / (this.strip * minStripTrainingError)) - 1);
                    pq = generalizationLoss / trainingProgress;

                    //display advance early stopping
                    this.learningErrorBox.Text = msle.ToString("F5");
                    this.validationErrorBox.Text = mspe.ToString("F5");
                    this.generalizationLossBox.Text = generalizationLoss.ToString("F5");
                    this.pqBox.Text = pq.ToString("F5");
                    this.seriesGraph.Refresh();

                    //stopping
                    switch (this.advanceStoppingMethod)
                    {
                        case AdvanceStoppingMethodEnumeration.GeneralizationLoss:
                            if (generalizationLoss > this.generalizationLossTreshold) needToStop = true;
                            break;
                        case AdvanceStoppingMethodEnumeration.ProgressQuotient:
                            if (pq > this.pqTreshold) needToStop = true;
                            break;
                    }

                }

                if (this.withCheckingCycle && iteration % this.checkingCycle == 0)
                {
                    switch (this.checkingMethod)
                    {
                        case CheckingMethodEnumeration.byMSEValue:
                            if (mse <= this.byMSEValueStopping) needToStop = true;
                            break;
                        case CheckingMethodEnumeration.byMSEChange:
                            if (lastMSE - mse <= this.byMSEChangeStopping) needToStop = true;
                            break;
                    }
                    lastMSE = mse;
                }
                if (iteration >= this.maxIteration)
                {
                    needToStop = true;
                }

                iteration++;
            }

            //restore weight
            if (this.useAdvanceEarlyStopping)
            {
                this.solutionData = this.bestSolution;

                // weight matrix

                for (int i = 0; i < this.network.Layers.Count - 1; i++)
                    for (int j = 0; j < this.network.Layers[i].WeightMatrix.Rows; j++)
                        for (int k = 0; k < this.network.Layers[i].WeightMatrix.Cols; k++)
                            this.network.Layers[i].WeightMatrix[j, k] = this.bestWeightMatrix[i][j, k];

                //best network criterion
                this.error = bestNetworkError;
                this.mse = bestNetworkMSE;
                this.mae = bestNetworkMAE;
            }
            else
            {
                this.error = error;
                this.mse = mse;
                this.mae = mae;
            }

            this.enableControls(true);
        }
예제 #9
0
        /// <summary>
        /// This is based off of this article:
        /// http://www.codeproject.com/Articles/54575/An-Introduction-to-Encog-Neural-Networks-for-C
        /// </summary>
        /// <remarks>
        /// Go here for documentation of encog:
        /// http://www.heatonresearch.com/wiki
        /// 
        /// Download link:
        /// https://github.com/encog/encog-dotnet-core/releases
        /// </remarks>
        private void btnXOR_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _trainingData = null;
                _results = null;

                BasicNetwork network = new BasicNetwork();

                #region Create nodes

                // Create the network's nodes

                //NOTE: Using ActivationSigmoid, because there are no negative values.  If there were negative, use ActivationTANH
                //http://www.heatonresearch.com/wiki/Activation_Function

                //NOTE: ActivationSigmoid (0 to 1) and ActivationTANH (-1 to 1) are pure but slower.  A cruder but faster function is ActivationElliott (0 to 1) and ActivationElliottSymmetric (-1 to 1)
                //http://www.heatonresearch.com/wiki/Elliott_Activation_Function

                network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 2));     // input layer
                network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 6));     // hidden layer
                network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 1));     // output layer
                network.Structure.FinalizeStructure();

                // Randomize the links
                network.Reset();

                #endregion

                #region Training data

                // Neural networks must be trained before they are of any use. To train this neural network, we must provide training
                // data. The training data is the truth table for the XOR operator. The XOR has the following inputs:
                double[][] xor_input = new[]
                {
                    new[] { 0d, 0d },
                    new[] { 1d, 0d },
                    new[] { 0d, 1d },
                    new[] { 1d, 1d },
                };

                // And the expected outputs
                double[][] xor_ideal_output = new[]
                {
                    new[] { 0d },
                    new[] { 1d },
                    new[] { 1d },
                    new[] { 0d },
                };

                _trainingData = GetDrawDataFromTrainingData(xor_input, xor_ideal_output);

                #endregion
                #region Train network

                INeuralDataSet trainingSet = new BasicNeuralDataSet(xor_input, xor_ideal_output);

                // This is a good general purpose training algorithm
                //http://www.heatonresearch.com/wiki/Training
                ITrain train = new ResilientPropagation(network, trainingSet);

                List<double> log = new List<double>();

                int trainingIteration = 1;
                do
                {
                    train.Iteration();

                    log.Add(train.Error);

                    trainingIteration++;
                } while ((trainingIteration < 2000) && (train.Error > 0.001));

                // Paste this into excel and chart it to see the error trend
                string logExcel = string.Join("\r\n", log);

                #endregion

                #region Test

                //NOTE: I initially ran a bunch of tests, but the network always returns exactly the same result when given the same inputs
                //var test = Enumerable.Range(0, 1000).
                //    Select(o => new { In1 = _rand.Next(2), In2 = _rand.Next(2) }).

                var test = xor_input.
                    Select(o => new { In1 = Convert.ToInt32(o[0]), In2 = Convert.ToInt32(o[1]) }).
                    Select(o => new
                    {
                        o.In1,
                        o.In2,
                        Expected = XOR(o.In1, o.In2),
                        NN = CallNN(network, o.In1, o.In2),
                    }).
                    Select(o => new { o.In1, o.In2, o.Expected, o.NN, Error = Math.Abs(o.Expected - o.NN) }).
                    OrderByDescending(o => o.Error).
                    ToArray();

                #endregion
                #region Test intermediate values

                // It was only trained with inputs of 0 and 1.  Let's see what it does with values in between

                var intermediates = Enumerable.Range(0, 1000).
                    Select(o => new { In1 = _rand.NextDouble(), In2 = _rand.NextDouble() }).
                    Select(o => new
                    {
                        o.In1,
                        o.In2,
                        NN = CallNN(network, o.In1, o.In2),
                    }).
                    OrderBy(o => o.In1).
                    ThenBy(o => o.In2).
                    //OrderBy(o => o.NN).
                    ToArray();

                #endregion

                #region Serialize/Deserialize

                // Serialize it
                string weightDump = network.DumpWeights();
                double[] dumpArray = weightDump.Split(',').
                    Select(o => double.Parse(o)).
                    ToArray();

                //TODO: Shoot through the layers, and store in some custom structure that can be serialized, then walked through to rebuild on deserialize
                //string[] layerDump = network.Structure.Layers.
                //    Select(o => o.ToString()).
                //    ToArray();

                // Create a clone
                BasicNetwork clone = new BasicNetwork();

                clone.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 2));
                clone.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 6));
                clone.AddLayer(new BasicLayer(new ActivationSigmoid(), true, 1));
                clone.Structure.FinalizeStructure();

                clone.DecodeFromArray(dumpArray);

                // Test the clone
                string cloneDump = clone.DumpWeights();

                bool isSame = weightDump == cloneDump;

                var cloneTests = xor_input.
                    Select(o => new
                    {
                        Input = o,
                        NN = CallNN(clone, o[0], o[1]),
                    }).ToArray();

                #endregion

                #region Store results

                double[] matchValues = new[] { 0d, 1d };
                double matchRange = .03;        //+- 5% of target value would be considered a match

                _results = intermediates.
                    Select(o => Tuple.Create(new Point(o.In1, o.In2), o.NN, IsMatch(o.NN, matchValues, matchRange))).
                    ToArray();

                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally
            {
                RedrawResults();
            }
        }
예제 #10
0
        protected void ReorderOutput(Network network, BasicNeuralDataSet dataset, Dictionary<int, List<BasicMLData>> trackIdFingerprints, double[][] binaryCodes)
        {
            int outputNeurons = network.GetLayerNeuronCount(network.LayerCount - 1);
            int trackCount = trackIdFingerprints.Count;

            // For each song, compute Am
            double[][] am = new double[trackCount][];
            int counter = 0;
            foreach (KeyValuePair<int, List<BasicMLData>> pair in trackIdFingerprints)
            {
                List<BasicMLData> sxSnippet = pair.Value;
                if (sxSnippet.Count < trainingSongSnippets)
                {
                    throw new NetTrainerException("Not enough snippets for a song");
                }

                am[counter] = new double[outputNeurons];
                foreach (BasicMLData snippet in sxSnippet)
                {
                    IMLData actualOutput = network.Compute(snippet);
                    for (int k = 0; k < outputNeurons; k++)
                    {
                        actualOutput[k] /= outputNeurons;
                        am[counter][k] += actualOutput[k];
                    }
                }

                counter++;
            }

            // Get a collection of tracks (shallow copy)
            int[] unassignedTracks = new int[trackCount];
            int countTrack = 0;
            foreach (KeyValuePair<int, List<BasicMLData>> item in trackIdFingerprints)
            {
                unassignedTracks[countTrack++] = item.Key;
            }

            int currItteration = 0;

            // Find binary code - track pair that has min l2 norm across all binary codes
            List<Tuple<int, int>> binCodeTrackPair = BinaryOutputUtil.FindMinL2Norm(binaryCodes, am);
            foreach (Tuple<int, int> pair in binCodeTrackPair)
            {
                // Set the input-output for all fingerprints of that song
                List<BasicMLData> songFingerprints = trackIdFingerprints[unassignedTracks[pair.Item2]];
                foreach (BasicMLData songFingerprint in songFingerprints)
                {
                    for (int i = 0, n = songFingerprint.Count; i < n; i++)
                    {
                        dataset.Data[currItteration].Input[i] = songFingerprint[i];
                    }

                    for (int i = 0, n = binaryCodes[pair.Item1].Length; i < n; i++)
                    {
                        dataset.Data[currItteration].Ideal[i] = binaryCodes[pair.Item1][i];
                    }

                    currItteration++;
                }
            }
        }
예제 #11
0
        public void Train(Network network, TrainingCallback callback)
        {
            IActivationFunction activationFunctionInput = network.GetActivation(0);
            int outputNeurons = network.GetLayerNeuronCount(network.LayerCount - 1);
            double error = 0;
            callback.Invoke(TrainingStatus.FillingStandardInputs, 0, 0, 0); /*First operation is filling standard input/outputs*/
            Dictionary<int, List<BasicMLData>> trackIdFingerprints = GetNormalizedTrackFingerprints(activationFunctionInput, trainingSongSnippets, outputNeurons);
            workingThread = Thread.CurrentThread;
            IActivationFunction activationFunctionOutput = network.GetActivation(network.LayerCount - 1);
            double[][] normalizedBinaryCodes = GetNormalizedBinaryCodes(activationFunctionOutput, outputNeurons);
            Tuple<double[][], double[][]> tuple = FillStandardInputsOutputs(trackIdFingerprints, normalizedBinaryCodes); /*Fill standard input output*/
            double[][] inputs = tuple.Item1;
            double[][] outputs = tuple.Item2;

            if (inputs == null || outputs == null)
            {
                callback.Invoke(TrainingStatus.Exception, 0, 0, 0);
                return;
            }

            int currentIterration = 0;
            double correctOutputs = 0.0;
            BasicNeuralDataSet dataset = new BasicNeuralDataSet(inputs, outputs);
            ITrain learner = new ResilientPropagation(network, dataset);
            try
            {
                // Dynamic output reordering cycle
                /*Idyn = 50*/
                for (int i = 0; i < Idyn; i++)
                {
                    if (paused)
                    {
                        pauseSem.WaitOne();
                    }

                    correctOutputs = NetworkPerformanceMeter.MeasurePerformance(network, dataset);
                    callback.Invoke(TrainingStatus.OutputReordering, correctOutputs, error, currentIterration);
                    ReorderOutput(network, dataset, trackIdFingerprints, normalizedBinaryCodes);
                    /*Edyn = 10*/
                    for (int j = 0; j < Edyn; j++)
                    {
                        if (paused)
                        {
                            pauseSem.WaitOne();
                        }

                        correctOutputs = NetworkPerformanceMeter.MeasurePerformance(network, dataset);
                        callback.Invoke(TrainingStatus.RunningDynamicEpoch, correctOutputs, error, currentIterration);
                        learner.Iteration();
                        error = learner.Error;
                        currentIterration++;
                    }
                }

                for (int i = 0; i < Efixed; i++)
                {
                    if (paused)
                    {
                        pauseSem.WaitOne();
                    }

                    correctOutputs = NetworkPerformanceMeter.MeasurePerformance(network, dataset);
                    callback.Invoke(TrainingStatus.FixedTraining, correctOutputs, error, currentIterration);
                    learner.Iteration();
                    error = learner.Error;
                    currentIterration++;
                }

                network.ComputeMedianResponses(inputs, trainingSongSnippets);
                callback.Invoke(TrainingStatus.Finished, correctOutputs, error, currentIterration);
            }
            catch (ThreadAbortException)
            {
                callback.Invoke(TrainingStatus.Aborted, correctOutputs, error, currentIterration);
                paused = false;
            }
        }
        /// <summary>
        /// Load the specified Encog object from an XML reader.
        /// </summary>
        /// <param name="xmlIn">The XML reader to use.</param>
        /// <returns>The loaded object.</returns>
        public IEncogPersistedObject Load(ReadXML xmlIn)
        {

            String name = xmlIn.LastTag.Attributes[
                   EncogPersistedCollection.ATTRIBUTE_NAME];
            String description = xmlIn.LastTag.GetAttributeValue(
                   EncogPersistedCollection.ATTRIBUTE_DESCRIPTION);

            this.currentDataSet = new BasicNeuralDataSet();
            this.currentDataSet.Name = name;
            this.currentDataSet.Description = description;

            while (xmlIn.ReadToTag())
            {
                if (xmlIn.IsIt(BasicNeuralDataSetPersistor.TAG_ITEM, true))
                {
                    HandleItem(xmlIn);
                }
                else if (xmlIn.IsIt(EncogPersistedCollection.TYPE_TRAINING, false))
                {
                    break;
                }

            }

            return this.currentDataSet;
        }
        /// <summary>
        /// Load the binary dataset to memory.  Memory access is faster. 
        /// </summary>
        /// <returns>A memory dataset.</returns>
        public INeuralDataSet LoadToMemory()
        {
            BasicNeuralDataSet result = new BasicNeuralDataSet();

            foreach (INeuralDataPair pair in this)
            {
                result.Add(pair);
            }

            return result;
        }
예제 #14
0
 /// <summary>
 /// Construct an enumerator.
 /// </summary>
 /// <param name="owner">The owner of the enumerator.</param>
 public BasicNeuralEnumerator(BasicNeuralDataSet owner)
 {
     this.current = -1;
     this.owner   = owner;
 }
예제 #15
0
        public void PerLineClassification(object sender, DoWorkEventArgs e)
        {
            worker = sender as BackgroundWorker;
            //inputtemplate = new double[DataContainer.model.timetable.rosterings.Count];
            //idealtemplate = new double[DataContainer.model.timetable.rosterings.Count * 4];
            inputtemplate = new double[23];
            idealtemplate = new double[23 * 4];
            Dictionary<string, int> inputmap = new Dictionary<string, int>()
            {
                {"Belfast - Connolly", 0},
                {"DART",1},
                {"IWT",2},
                {"DFDS",3},
                {"Timber",4},
                {"Tara Mines",5},
                {"Northern Commuter",6},
                {"Cork - Heuston",7},
                {"Heuston Commuter",8},
                {"Tralee",9 },
                {"Limerick - Heuston",10},
                {"Limerick Junction - Limerick",11},
                {"Ballybrophy - Limerick",12},
                {"Waterford - Heuston",13},
                {"Waterford - Limerick Junction",14},
                {"Rosslare - Waterford",15},
                {"Rosslare - Connolly",16},
                {"Galway - Heuston",17},
                {"Westport - Heuston",18},
                {"Sligo - Connolly",19},
                {"Maynooth Commuter",20}
            };
            inputtemplate = new double[inputmap.Count];
            idealtemplate = new double[inputmap.Count * 4];

            List<double[]> inputlist = new List<double[]>();
            List<double[]> outputlist = new List<double[]>();
            foreach(List<DelayCombination> day in DataContainer.NeuralNetwork.DelayCombinations.dict.Values.Where(x => x != null))
            {

                foreach(DelayCombination delaycombination in day)
                {
                    worker.ReportProgress(0, "Preprocessing Data... Date : " + delaycombination.primarydelays[0].date.ToString("dd/MM/yyyy"));

                    double[] inputline = new double[inputtemplate.Length];
                    double[] outputline = new double[idealtemplate.Length];

                    double[] secondarydelaysize = new double[inputtemplate.Length];
                    foreach (Delay d in delaycombination.primarydelays)
                    {
                        //string line = DataContainer.model.timetable.trains.Single(x => x.id == d.traincode).description;
                        if (GetLine(d) == "None") { goto skip; }
                        inputline[inputmap[GetLine(d)]] += d.destinationdelay;
                    }
                    foreach (Delay d in delaycombination.secondarydelays)
                    {
                        //string line = DataContainer.model.timetable.trains.Single(x => x.id == d.traincode).description;
                        if (GetLine(d) == "None") { goto skip; }
                        secondarydelaysize[inputmap[GetLine(d)]] += d.destinationdelay;
                    }

                    for (int i = 0; i < secondarydelaysize.Length; i++)
                    {
                        if (secondarydelaysize[i] == 0)
                        {
                            outputline[i * 4] = 1;
                        }
                        else if (secondarydelaysize[i] < 300)
                        {
                            outputline[i * 4 + 1] = 1;
                        }
                        else if (secondarydelaysize[i] < 600)
                        {
                            outputline[i * 4 + 2] = 1;
                        }
                        else
                        {
                            outputline[i * 4 + 3] = 1;
                        }
                    }

                    inputlist.Add(inputline);
                    outputlist.Add(outputline);
                skip:
                    continue;

                }
            }

            double[][] input = inputlist.ToArray();
            double[][] output = outputlist.ToArray();
            INeuralDataSet dataset = new BasicNeuralDataSet(input, output);
            DataContainer.NeuralNetwork.Data = dataset;
        }
예제 #16
0
        private static EncogTrainingResponse TrainNetwork2(BasicNetwork network, TrainingData training, double maxError, CancellationToken cancelToken, double? maxSeconds = null)
        {

            //TODO: When the final layer is softmax, the error seems to be higher.  Probably because the training outputs need to be run through softmax

            const int MAXITERATIONS = 5000;

            INeuralDataSet trainingSet = new BasicNeuralDataSet(training.Input, training.Output);
            ITrain train = new ResilientPropagation(network, trainingSet);

            DateTime startTime = DateTime.UtcNow;
            TimeSpan? maxTime = maxSeconds != null ? TimeSpan.FromSeconds(maxSeconds.Value) : (TimeSpan?)null;

            bool success = false;

            //List<double> log = new List<double>();
            int iteration = 1;
            double error = double.MaxValue;
            while (true)
            {
                if (cancelToken.IsCancellationRequested)
                {
                    break;
                }

                train.Iteration();

                error = train.Error;
                //log.Add(error);

                iteration++;

                if (double.IsNaN(error))
                {
                    break;
                }
                else if (error < maxError)
                {
                    success = true;
                    break;
                }
                else if (iteration >= MAXITERATIONS)
                {
                    break;
                }
                else if (maxTime != null && DateTime.UtcNow - startTime > maxTime)
                {
                    break;
                }
            }

            //string logExcel = string.Join("\r\n", log);       // paste this into excel and chart it to see the error trend

            train.FinishTraining();

            return new EncogTrainingResponse(network, success, error, iteration, (DateTime.UtcNow - startTime).TotalSeconds);
        }