예제 #1
0
        public override void VTrain(VMatrix features, VMatrix labels)
        {
            if (m_hidden.Length < 1)
            {
                m_hidden = new int[1] {
                    features.Cols() * 2
                };
            }

            // add the input nodes
            List <Node> iNodes = new List <Node>();

            for (var i = 0; i < features.Cols(); i++)
            {
                iNodes.Add(new InputNode(i, i, m_rand));
            }

            m_layers.Add(iNodes);
            int prevNodes = iNodes.Count + 1;

            // add the hidden nodes
            for (var layer = 0; layer < m_hidden.Length; layer++)
            {
                List <Node> hNodes = new List <Node>();

                for (var n = 0; n < m_hidden[layer]; n++)
                {
                    var node = new HiddenNode(n, prevNodes, m_rand);
                    if (m_activation == "relu")
                    {
                        if (m_actRandom)
                        {
                            node.alpha     = m_actAlpha * m_rand.NextDouble();
                            node.threshold = m_actThreshold * m_rand.NextDouble();
                            node.beta      = ((m_actBeta - 1.0) * m_rand.NextDouble()) + 1.0;
                        }
                        else
                        {
                            node.alpha     = m_actAlpha;
                            node.threshold = m_actThreshold;
                            node.beta      = m_actBeta;
                        }
                    }
                    hNodes.Add(node);
                }

                m_layers.Add(hNodes);
                prevNodes = hNodes.Count + 1;
            }

            // add the output nodes
            List <Node> oNodes = new List <Node>();

            for (var col = 0; col < labels.Cols(); col++)
            {
                var labelValueCount = labels.ValueCount(col);

                if (labelValueCount < 2)
                {
                    // continuous
                    var node = new OutputNode(oNodes.Count, prevNodes, true, col, -1, m_rand);
                    if (m_activation == "relu")
                    {
                        if (m_actRandom)
                        {
                            node.alpha     = m_actAlpha * m_rand.NextDouble();
                            node.threshold = m_actThreshold * m_rand.NextDouble();
                            node.beta      = ((m_actBeta - 1.0) * m_rand.NextDouble()) + 1.0;
                        }
                        else
                        {
                            node.alpha     = m_actAlpha;
                            node.threshold = m_actThreshold;
                            node.beta      = m_actBeta;
                        }
                    }
                    oNodes.Add(node);
                }
                else
                {
                    for (var n = 0; n < labelValueCount; n++)
                    {
                        var node = new OutputNode(oNodes.Count, prevNodes, false, col, n, m_rand);
                        if (m_activation == "relu")
                        {
                            if (m_actRandom)
                            {
                                node.alpha     = m_actAlpha * m_rand.NextDouble();
                                node.threshold = m_actThreshold * m_rand.NextDouble();
                                node.beta      = ((m_actBeta - 1.0) * m_rand.NextDouble()) + 1.0;
                            }
                            else
                            {
                                node.alpha     = m_actAlpha;
                                node.threshold = m_actThreshold;
                                node.beta      = m_actBeta;
                            }
                        }
                        oNodes.Add(node);
                    }
                }
            }

            m_layers.Add(oNodes);

            int     trainSize          = (int)(0.75 * features.Rows());
            VMatrix trainFeatures      = new VMatrix(features, 0, 0, trainSize, features.Cols());
            VMatrix trainLabels        = new VMatrix(labels, 0, 0, trainSize, labels.Cols());
            VMatrix validationFeatures = new VMatrix(features, trainSize, 0, features.Rows() - trainSize, features.Cols());
            VMatrix validationLabels   = new VMatrix(labels, trainSize, 0, labels.Rows() - trainSize, labels.Cols());

            Console.Write("Layers: ");
            Console.Write(iNodes.Count);
            Console.Write('x');
            for (var l = 0; l < m_hidden.Length; l++)
            {
                Console.Write(m_hidden[l]);
                Console.Write('x');
            }
            Console.WriteLine(oNodes.Count);

            Console.WriteLine("AF: " + m_activation);
            Console.WriteLine(string.Format("AParam: {0},{1},{2},{3}", m_actAlpha, m_actThreshold, m_actBeta, m_actRandom));
            Console.WriteLine("Boost: " + m_boost);

            Console.WriteLine("Epoch\tMSE (validation)");
            if (m_outputFile != null)
            {
                m_outputFile.Write("Layers: ");
                m_outputFile.Write(iNodes.Count);
                m_outputFile.Write('x');
                for (var l = 0; l < m_hidden.Length; l++)
                {
                    m_outputFile.Write(m_hidden[l]);
                    m_outputFile.Write('x');
                }
                m_outputFile.WriteLine(oNodes.Count);

                m_outputFile.WriteLine("Momentum: " + m_momentum);
                m_outputFile.WriteLine("AF: " + m_activation);
                m_outputFile.WriteLine(string.Format("AParam: {0},{1},{2},{3}", m_actAlpha, m_actThreshold, m_actBeta, m_actRandom));
                m_outputFile.WriteLine("Boost: " + m_boost);
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
                m_outputFile.WriteLine("Epoch\tMSE (validation)");
            }

            for (int round = 1; round < m_layers.Count; round++)
            {
                int    epoch      = 0;                                  // current epoch number
                int    bestEpoch  = 0;                                  // epoch number of best MSE
                int    eCount     = 0;                                  // number of epochs since the best MSE
                bool   checkDone  = false;                              // if true, check to see if we're done
                double initialMSE = double.MaxValue;                    // MSE for first epoch
                double bestMSE    = double.MaxValue;                    // best validation MSE so far

                for (; ;)
                {
                    // shuffle the training set
                    trainFeatures.Shuffle(m_rand, trainLabels);

                    TrainEpoch(++epoch, trainFeatures, trainLabels, round);

                    // check the MSE after this epoch
                    double mse = VGetMSE(validationFeatures, validationLabels);

                    Console.WriteLine(string.Format("{0}:{1}-{2}\t{3}", round, epoch, eCount, mse));
                    if (m_outputFile != null)
                    {
                        m_outputFile.WriteLine(string.Format("{0}:{1}-{2}\t{3}", round, epoch, eCount, mse));
                        m_outputFile.Flush();
                    }

                    if ((mse == 0.0) || (epoch > 5000))
                    {
                        break;
                    }
                    else if ((epoch == 1) || (mse < bestMSE))
                    {
                        if (epoch == 1)
                        {
                            // save the initial MSE
                            initialMSE = mse;
                        }
                        else if (!checkDone && (mse < initialMSE * 0.9))
                        {
                            checkDone = true;
                        }
                        eCount = 0;

                        // save the best for later
                        bestMSE   = mse;
                        bestEpoch = epoch;
                        for (var layer = 1; layer < m_layers.Count; layer++)
                        {
                            foreach (var node in m_layers[layer])
                            {
                                node.SaveBestWeights();
                            }
                        }
                    }
                    else if (checkDone)
                    {
                        // check to see if we're done
                        eCount++;
                        if (eCount >= 20)
                        {
                            break;
                        }
                    }

                    if ((bestEpoch > 0) && (bestEpoch != epoch))
                    {
                        for (var layer = round; layer < m_layers.Count; layer++)
                        {
                            foreach (var node in m_layers[layer])
                            {
                                node.RestoreBestWeights();
                                node.InitDeltas();
                            }
                        }
                        if (m_outputFile != null)
                        {
                            m_outputFile.WriteLine();
                            m_outputFile.WriteLine(string.Format("Best Weights (from Epoch {0}, valMSE={1})", bestEpoch, bestMSE));
                            PrintWeights();
                        }
                    }
                }
            }

            if (m_outputFile != null)
            {
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
                m_outputFile.Close();
            }
        }
예제 #2
0
        public override void VTrain(VMatrix features, VMatrix labels)
        {
            if (m_hidden.Length < 1)
            {
                m_hidden = new int[1] {
                    features.Cols() * 2
                };
            }

            int wIdx = 0;                                                               // index into the weights array

            // add the input nodes
            List <Node> iNodes = new List <Node>();

            for (var i = 0; i < features.Cols(); i++)
            {
                iNodes.Add(new InputNode(i, 0, m_rand));
            }

            m_layers.Add(iNodes);

            int     trainSize          = (int)(0.75 * features.Rows());
            VMatrix trainFeatures      = new VMatrix(features, 0, 0, trainSize, features.Cols());
            VMatrix trainLabels        = new VMatrix(labels, 0, 0, trainSize, labels.Cols());
            VMatrix validationFeatures = new VMatrix(features, trainSize, 0, features.Rows() - trainSize, features.Cols());
            VMatrix validationLabels   = new VMatrix(labels, trainSize, 0, labels.Rows() - trainSize, labels.Cols());

            Console.WriteLine("R-E-C\tMSE (training)\t\tMSE (validation)\taccuracy (validation)");
            if (m_outputFile != null)
            {
                m_outputFile.WriteLine("Momentum: " + m_momentum);
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
                m_outputFile.WriteLine("R-E-C\tMSE (training)\t\tMSE (validation)\taccuracy (validation)");
            }

            if (m_weights != null)
            {
                // not training
                double trainMSE = VGetMSE(trainFeatures, trainLabels);
                double mse      = VGetMSE(validationFeatures, validationLabels);
                double accuracy = VMeasureAccuracy(validationFeatures, validationLabels, null);
                Console.WriteLine($"1\t{trainMSE}\t{mse}\t{accuracy}");
                if (m_outputFile != null)
                {
                    m_outputFile.WriteLine($"1\t{trainMSE}\t{mse}\t{accuracy}");
                }
            }
            else
            {
                for (int round = 1; round <= m_hidden.Length + 1; round++)
                {
                    if (round <= m_hidden.Length)
                    {
                        // add hidden nodes
                        int         prevNodes = m_layers[m_layers.Count - 1].Count + 1;
                        List <Node> hNodes    = new List <Node>();

                        for (var n = 0; n < m_hidden[m_layers.Count - 1]; n++)
                        {
                            if (m_weights != null)
                            {
                                hNodes.Add(new HiddenNode(prevNodes, m_rand, m_weights[wIdx++]));
                            }
                            else
                            {
                                hNodes.Add(new HiddenNode(prevNodes, m_rand, null));
                            }
                        }

                        m_layers.Add(hNodes);

                        prevNodes = hNodes.Count + 1;

                        // add output nodes
                        List <Node> oNodes = new List <Node>();

                        if (round < m_hidden.Length)
                        {
                            // dae layer - add output nodes to match inputs
                            for (var col = 0; col < m_layers[m_layers.Count - 2].Count; col++)
                            {
                                oNodes.Add(new OutputNode(prevNodes, true, col, -1, m_rand, null));
                            }
                        }
                        else
                        {
                            // final layer - figure out how many outputs we need
                            for (var col = 0; col < labels.Cols(); col++)
                            {
                                var labelValueCount = labels.ValueCount(col);

                                if (labelValueCount < 2)
                                {
                                    // continuous
                                    if (m_weights != null)
                                    {
                                        oNodes.Add(new OutputNode(prevNodes, true, col, -1, m_rand, m_weights[wIdx++]));
                                    }
                                    else
                                    {
                                        oNodes.Add(new OutputNode(prevNodes, true, col, -1, m_rand, null));
                                    }
                                }
                                else
                                {
                                    for (var n = 0; n < labelValueCount; n++)
                                    {
                                        if (m_weights != null)
                                        {
                                            oNodes.Add(new OutputNode(prevNodes, false, col, n, m_rand, m_weights[wIdx++]));
                                        }
                                        else
                                        {
                                            oNodes.Add(new OutputNode(prevNodes, false, col, n, m_rand, null));
                                        }
                                    }
                                }
                            }
                        }

                        m_layers.Add(oNodes);

                        InitNodes();
                    }

                    int    epoch        = 0;                                    // current epoch number
                    int    bestEpoch    = 0;                                    // epoch number of best MSE
                    int    eCount       = 0;                                    // number of epochs since the best MSE
                    bool   checkDone    = false;                                // if true, check to see if we're done
                    double mse          = 0;                                    // validation MSE
                    double bestTrainMSE = double.MaxValue;                      // best training MSE so far
                    double bestMSE      = double.MaxValue;                      // best validation MSE so far
                    double accuracy     = 0;                                    // validation accuracy
                    double bestAccuracy = double.MaxValue;                      // best validationa accuracy so far

                    for (; ;)
                    {
                        // shuffle the training set
                        trainFeatures.Shuffle(m_rand, trainLabels);
                        double trainMSE = TrainEpoch(++epoch, trainFeatures, trainLabels, round <m_hidden.Length, round> m_hidden.Length);

                        // check the MSE after this epoch
                        if (round < m_hidden.Length)
                        {
                            mse      = IGetMSE(validationFeatures);
                            accuracy = 0;
                        }
                        else
                        {
                            mse = VGetMSE(validationFeatures, validationLabels);

                            // check the validation accuracy
                            accuracy = VMeasureAccuracy(validationFeatures, validationLabels, null);
                        }

                        Console.WriteLine($"{round}-{epoch}-{eCount}\t{trainMSE}\t{mse}\t{accuracy}");
                        if (m_outputFile != null)
                        {
                            m_outputFile.WriteLine($"{round}-{epoch}-{eCount}\t{trainMSE}\t{mse}\t{accuracy}");
                            m_outputFile.Flush();
                        }

                        if ((mse == 0.0) || (epoch > 10000))
                        {
                            break;
                        }
                        else if ((epoch == 1) || (mse < bestMSE))
                        {
                            if (epoch == 1)
                            {
                                // save the initial MSE
                                bestMSE = mse;
                            }
                            else if ((mse / bestMSE) > 0.99)
                            {
                                if (!checkDone)
                                {
                                    checkDone = true;
                                    eCount    = 0;
                                }
                            }
                            else
                            {
                                checkDone = false;
                                eCount    = 0;
                            }

                            // save the best for later
                            bestTrainMSE = trainMSE;
                            bestMSE      = mse;
                            bestAccuracy = accuracy;
                            bestEpoch    = epoch;
                            for (var layer = 0; layer < m_layers.Count - 1; layer++)
                            {
                                foreach (var node in m_layers[layer])
                                {
                                    node.SaveBestWeights();
                                }
                            }
                        }
                        else if (!checkDone)
                        {
                            checkDone = true;
                            eCount    = 0;
                        }

                        if (checkDone)
                        {
                            // check to see if we're done
                            eCount++;
                            if (eCount >= 20)
                            {
                                break;
                            }
                        }
                    }

                    if (round < m_hidden.Length)
                    {
                        // delete the output layer
                        m_layers.RemoveAt(m_layers.Count - 1);
                    }

                    if ((bestEpoch > 0) && (bestEpoch != epoch))
                    {
                        for (var layer = 0; layer < m_layers.Count - 1; layer++)
                        {
                            foreach (var node in m_layers[layer])
                            {
                                node.RestoreBestWeights();
                            }
                        }

                        Console.WriteLine($"Best Weights (from Epoch {bestEpoch}, trainMSE={bestTrainMSE}, valMSE={bestMSE})");
                        if (m_outputFile != null)
                        {
                            m_outputFile.WriteLine();
                            m_outputFile.WriteLine($"Best Weights (from Epoch {bestEpoch}, trainMSE={bestTrainMSE}, valMSE={bestMSE})");
                            m_outputFile.Flush();
                        }
                    }
                }
            }

            if (m_outputFile != null)
            {
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
            }

            if (m_outputFile != null)
            {
                m_outputFile.Close();
            }
        }
예제 #3
0
        public override void VTrain(VMatrix features, VMatrix labels)
        {
            if (Layers.Count < 1)
            {
                // create the layers
                if (Parameters.Hidden.Length < 1)
                {
                    Parameters.Hidden = new[] { features.Cols() * 2 };
                }

                // add the input nodes
                var iNodes = new List <Node>();
                for (var i = 0; i < features.Cols(); i++)
                {
                    iNodes.Add(new InputNode(i, i, _rand));
                }

                var iLayer = new Layer()
                {
                    Type     = LayerType.Input,
                    Nodes    = iNodes,
                    Previous = null,
                    Next     = null
                };
                Layers.Add(iLayer);

                var prevLayer = iLayer;

                // add the hidden nodes
                foreach (var t in Parameters.Hidden)
                {
                    var hNodes = new List <Node>();

                    for (var n = 0; n < t; n++)
                    {
                        var node = new HiddenNode(n, prevLayer.Nodes.Count + 1, t, _rand);
                        hNodes.Add(node);
                    }

                    var hLayer = new Layer()
                    {
                        Type     = LayerType.Hidden,
                        Nodes    = hNodes,
                        Previous = prevLayer,
                        Next     = null
                    };
                    Layers.Add(hLayer);

                    prevLayer.Next = hLayer;
                    prevLayer      = hLayer;
                }

                // add the output nodes
                var oNodes = new List <Node>();
                var oCount = 0;
                for (var col = 0; col < labels.Cols(); col++)
                {
                    var labelValueCount = labels.ValueCount(col);

                    if (labelValueCount < 2)
                    {
                        // continuous
                        oCount++;
                    }
                    else
                    {
                        oCount += labelValueCount;
                    }
                }

                for (var col = 0; col < labels.Cols(); col++)
                {
                    var labelValueCount = labels.ValueCount(col);

                    if (labelValueCount < 2)
                    {
                        // continuous
                        var node = new OutputNode(oNodes.Count, true, col, -1, prevLayer.Nodes.Count + 1, oCount, _rand);
                        oNodes.Add(node);
                    }
                    else
                    {
                        for (var n = 0; n < labelValueCount; n++)
                        {
                            var node = new OutputNode(oNodes.Count, false, col, n, prevLayer.Nodes.Count + 1, oCount, _rand);
                            oNodes.Add(node);
                        }
                    }
                }

                var oLayer = new Layer()
                {
                    Type     = LayerType.Output,
                    Nodes    = oNodes,
                    Previous = prevLayer
                };
                Layers.Add(oLayer);

                prevLayer.Next = oLayer;
            }

            var trainSize          = (int)(0.75 * features.Rows());
            var trainFeatures      = new VMatrix(features, 0, 0, trainSize, features.Cols());
            var trainLabels        = new VMatrix(labels, 0, 0, trainSize, labels.Cols());
            var validationFeatures = new VMatrix(features, trainSize, 0, features.Rows() - trainSize, features.Cols());
            var validationLabels   = new VMatrix(labels, trainSize, 0, labels.Rows() - trainSize, labels.Cols());

            Console.Write("Layers: ");
            foreach (var layer in Layers)
            {
                Console.Write(layer.Nodes.Count);
                if (layer.Type == LayerType.Output)
                {
                    Console.WriteLine();
                }
                else
                {
                    Console.Write('x');
                }
            }

            Console.WriteLine("AF: " + Parameters.Activation);

            Console.WriteLine("Epoch\tMSE (validation)");

            int    epoch;                                 // current epoch number
            var    bestEpoch     = 0;                     // epoch number of best MSE
            var    eCount        = 0;                     // number of epochs since the best MSE
            var    checkDone     = false;                 // if true, check to see if we're done
            var    initialMse    = Parameters.InitialMse; // MSE for first epoch
            var    bestMse       = Parameters.StartMse;   // best validation MSE so far
            double bestAccuracy  = 0;
            var    batchCount    = (trainFeatures.Rows() + Parameters.BatchSize - 1) / Parameters.BatchSize;
            int    countInterval = batchCount / 10;

            if (countInterval < 1)
            {
                countInterval = 1;
            }
            var startEpoch = Parameters.StartEpoch + 1;

            for (epoch = startEpoch;; epoch++)
            {
                // shuffle the training set
                trainFeatures.Shuffle(_rand, trainLabels);
                var cl = Console.CursorLeft;

                for (var batch = 0; batch < batchCount; batch++)
                {
                    var startIdx = batch * Parameters.BatchSize;
                    var count    = Parameters.BatchSize;
                    if ((startIdx + count) > trainFeatures.Rows())
                    {
                        count = trainFeatures.Rows() - startIdx;
                    }
                    TrainBatch(trainFeatures, trainLabels, startIdx, count);

                    if ((((batch + 1) % countInterval) == 0) || (batch == (batchCount - 1)))
                    {
                        Console.SetCursorPosition(cl, Console.CursorTop);
                        Console.Write(batch + 1);
                    }
                }

                Console.WriteLine();

                // check the MSE
                var mse = VGetMSE(validationFeatures, validationLabels);
                if ((epoch == startEpoch) && (initialMse == 0))
                {
                    // save the initial MSE
                    initialMse = mse;
                }
                var accuracy = VMeasureAccuracy(validationFeatures, validationLabels, null);

                if ((epoch % Parameters.SnapshotInterval) == 0)
                {
                    SaveSnapshot(epoch, mse, initialMse, accuracy);
                }

                Console.WriteLine($"{epoch}-{eCount}\t{mse}");

                if ((mse == 0) || (epoch > 5000))
                {
                    break;
                }

                if ((epoch == startEpoch) || (mse < bestMse))
                {
                    if ((epoch != startEpoch) && !checkDone && (mse < initialMse * 0.9))
                    {
                        checkDone = true;
                    }
                    eCount = 0;

                    // save the best for later
                    bestMse      = mse;
                    bestEpoch    = epoch;
                    bestAccuracy = accuracy;
                    foreach (var layer in Layers)
                    {
                        foreach (var node in layer.Nodes)
                        {
                            node.SaveBestWeights();
                        }
                    }
                }
                else if (checkDone)
                {
                    // check to see if we're done
                    eCount++;
                    if (eCount >= 20)
                    {
                        break;
                    }
                }
            }

            if ((bestEpoch > 0) && (bestEpoch != epoch))
            {
                foreach (var layer in Layers)
                {
                    foreach (var node in layer.Nodes)
                    {
                        node.RestoreBestWeights();
                    }
                }
            }

            SaveSnapshot(bestEpoch, bestMse, initialMse, bestAccuracy, true);
        }
예제 #4
0
        public override void VTrain(VMatrix features, VMatrix labels)
        {
            if (m_hidden.Length < 1)
            {
                m_hidden = new int[1] {
                    features.Cols() * 2
                };
            }

            // create output nodes
            List <Node> oNodes = new List <Node>();

            // figure out how many outputs we need
            for (var col = 0; col < labels.Cols(); col++)
            {
                var labelValueCount = labels.ValueCount(col);

                if (labelValueCount < 2)
                {
                    // continuous
                    oNodes.Add(new OutputNode(m_hidden[m_hidden.Length - 1] + 1, true, col, -1, m_rand));
                }
                else
                {
                    for (var n = 0; n < labelValueCount; n++)
                    {
                        oNodes.Add(new OutputNode(m_hidden[m_hidden.Length - 1] + 1, false, col, n, m_rand));
                    }
                }
            }

            int oCount = oNodes.Count;

            for (var plane = 0; plane < oCount; plane++)
            {
                m_layers.Add(new List <List <Node> >());

                // add the input nodes
                List <Node> iNodes = new List <Node>();
                for (var i = 0; i < features.Cols(); i++)
                {
                    iNodes.Add(new InputNode(i, 0, m_rand));
                }

                m_layers[plane].Add(iNodes);

                int prevNodes = iNodes.Count + 1;

                for (var layer = 0; layer <= m_hidden.Length; layer++)
                {
                    if (layer < m_hidden.Length)
                    {
                        // add hidden nodes
                        List <Node> hNodes = new List <Node>();

                        for (var n = 0; n < m_hidden[layer]; n++)
                        {
                            hNodes.Add(new HiddenNode(prevNodes, m_rand));
                        }

                        m_layers[plane].Add(hNodes);

                        prevNodes = hNodes.Count + 1;
                    }
                    else
                    {
                        // add output node
                        m_layers[plane].Add(new List <Node>()
                        {
                            oNodes[plane]
                        });
                    }
                }
            }

            InitNodes();

            int     trainSize          = (int)(0.75 * features.Rows());
            VMatrix trainFeatures      = new VMatrix(features, 0, 0, trainSize, features.Cols());
            VMatrix trainLabels        = new VMatrix(labels, 0, 0, trainSize, labels.Cols());
            VMatrix validationFeatures = new VMatrix(features, trainSize, 0, features.Rows() - trainSize, features.Cols());
            VMatrix validationLabels   = new VMatrix(labels, trainSize, 0, labels.Rows() - trainSize, labels.Cols());

            Console.WriteLine(string.Format("Planes: {0}", oCount));
            Console.Write(string.Format("Layers: {0}x", features.Cols()));
            for (var l = 0; l < m_hidden.Length; l++)
            {
                Console.Write(m_hidden[l]);
                Console.Write('x');
            }
            Console.WriteLine("1");
            Console.WriteLine("Momentum: " + m_momentum);
            Console.WriteLine("AF: " + m_activation);
            Console.WriteLine(string.Format("AParam: {0},{1},{2},{3}", m_actLeak, m_actThreshold, m_actSlope, m_actRandom));
            Console.WriteLine("P-R-C\tMSE (validation)");
            if (m_outputFile != null)
            {
                m_outputFile.WriteLine(string.Format("Planes: {0}", oCount));
                m_outputFile.Write(string.Format("Layers: {0}x", features.Cols()));
                for (var l = 0; l < m_hidden.Length; l++)
                {
                    m_outputFile.Write(m_hidden[l]);
                    m_outputFile.Write('x');
                }
                m_outputFile.WriteLine("1");
                m_outputFile.WriteLine("Momentum: " + m_momentum);
                m_outputFile.WriteLine("AF: " + m_activation);
                m_outputFile.WriteLine(string.Format("AParam: {0},{1},{2},{3}", m_actLeak, m_actThreshold, m_actSlope, m_actRandom));
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("P-R-C\tMSE (validation)");
            }

            // train the net, one plane at a time
            for (var plane = 0; plane < oCount; plane++)
            {
                int    epoch      = 0;                                  // current epoch number
                int    bestEpoch  = 0;                                  // epoch number of best MSE
                int    eCount     = 0;                                  // number of epochs since the best MSE
                bool   checkDone  = false;                              // if true, check to see if we're done
                double initialMSE = double.MaxValue;                    // MSE for first epoch
                double bestMSE    = double.MaxValue;                    // best validation MSE so far

                for (; ;)
                {
                    // shuffle the training set
                    trainFeatures.Shuffle(m_rand, trainLabels);
                    TrainEpoch(plane, ++epoch, trainFeatures, trainLabels);

                    // check the MSE after this epoch
                    double mse = PGetMSE(plane, validationFeatures, validationLabels);

                    Console.WriteLine(string.Format("{0}-{1}-{2}\t{3}", plane, epoch, eCount, mse));
                    if (m_outputFile != null)
                    {
                        m_outputFile.WriteLine(string.Format("{0}-{1}-{3}\t{3}", plane, epoch, eCount, mse));
                        m_outputFile.Flush();
                    }

                    if ((mse == 0.0) || (epoch > 10000))
                    {
                        break;
                    }
                    else if ((epoch == 1) || (mse < bestMSE))
                    {
                        if (epoch == 1)
                        {
                            // save the initial MSE
                            initialMSE = mse;
                        }
                        else if (!checkDone && (mse < initialMSE * 0.9))
                        {
                            checkDone = true;
                        }
                        eCount = 0;

                        // save the best for later
                        bestMSE   = mse;
                        bestEpoch = epoch;
                        for (var layer = 0; layer < m_layers[plane].Count - 1; layer++)
                        {
                            foreach (var node in m_layers[plane][layer])
                            {
                                node.SaveBestWeights();
                            }
                        }
                    }
                    else if (checkDone)
                    {
                        // check to see if we're done
                        eCount++;
                        if (eCount >= 20)
                        {
                            break;
                        }
                    }
                    else if ((epoch > 100) && /*(mse < initialMSE) &&*/ (mse > ((bestMSE + initialMSE) / 2)))
                    {
                        checkDone = true;
                    }
                }

                if ((bestEpoch > 0) && (bestEpoch != epoch))
                {
                    for (var layer = 0; layer < m_layers[plane].Count - 1; layer++)
                    {
                        foreach (var node in m_layers[plane][layer])
                        {
                            node.RestoreBestWeights();
                        }
                    }

                    Console.WriteLine(string.Format("Best Weights (from Epoch {0}, valMSE={1})", bestEpoch, bestMSE));
                    if (m_outputFile != null)
                    {
                        m_outputFile.WriteLine();
                        m_outputFile.WriteLine(string.Format("Best Weights (from Epoch {0}, valMSE={1})", bestEpoch, bestMSE));
                        m_outputFile.Flush();
                    }
                }
            }

            if (m_outputFile != null)
            {
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
            }

            if (m_outputFile != null)
            {
                m_outputFile.Close();
            }
        }
예제 #5
0
        public override void VTrain(VMatrix features, VMatrix labels)
        {
            if (m_hidden.Length < 1)
            {
                m_hidden = new int[1] {
                    features.Cols() * 2
                };
            }

            int prevNodes = features.Cols() + 1;
            int wIdx      = 0;                                                          // index into the weights array

            for (var layer = 0; layer <= m_hidden.Length; layer++)
            {
                // add the nodes for this layer
                List <Node> nodes = new List <Node>();

                if (layer < m_hidden.Length)
                {
                    // hidden layer
                    for (var n = 0; n < m_hidden[layer]; n++)
                    {
                        if (m_weights != null)
                        {
                            nodes.Add(new Node(prevNodes, false, 0, 0, m_rand, m_weights[wIdx++]));
                        }
                        else
                        {
                            nodes.Add(new Node(prevNodes, false, 0, 0, m_rand, null));
                        }
                    }
                }
                else
                {
                    // output layer - figure out how many outputs we need
                    for (var col = 0; col < labels.Cols(); col++)
                    {
                        var labelValueCount = labels.ValueCount(col);

                        if (labelValueCount < 2)
                        {
                            // continuous
                            if (m_weights != null)
                            {
                                nodes.Add(new Node(prevNodes, true, col, -1, m_rand, m_weights[wIdx++]));
                            }
                            else
                            {
                                nodes.Add(new Node(prevNodes, true, col, -1, m_rand, null));
                            }
                        }
                        else
                        {
                            for (var n = 0; n < labelValueCount; n++)
                            {
                                if (m_weights != null)
                                {
                                    nodes.Add(new Node(prevNodes, false, col, n, m_rand, m_weights[wIdx++]));
                                }
                                else
                                {
                                    nodes.Add(new Node(prevNodes, false, col, n, m_rand, null));
                                }
                            }
                        }
                    }
                }

                prevNodes = nodes.Count + 1;

                m_layers.Add(nodes);
            }

            InitNodes();

            int     trainSize          = (int)(0.75 * features.Rows());
            VMatrix trainFeatures      = new VMatrix(features, 0, 0, trainSize, features.Cols());
            VMatrix trainLabels        = new VMatrix(labels, 0, 0, trainSize, labels.Cols());
            VMatrix validationFeatures = new VMatrix(features, trainSize, 0, features.Rows() - trainSize, features.Cols());
            VMatrix validationLabels   = new VMatrix(labels, trainSize, 0, labels.Rows() - trainSize, labels.Cols());

            int    epoch        = 0;                            // current epoch number
            double bestTrainMSE = double.MaxValue;              // best training MSE so far
            double bestMSE      = double.MaxValue;              // best validation MSE so far
            double bestAccuracy = double.MaxValue;              // best validationa accuracy so far
            double initialMSE   = double.MaxValue;              // MSE for first epoch
            int    eCount       = 0;                            // number of epochs since the best MSE
            int    bestEpoch    = 0;                            // epoch number of best MSE
            bool   done         = false;
            bool   checkDone    = false;                        // if true, check to see if we're done

            Console.WriteLine("Epoch\tMSE (training)\t\tMSE (validation)\taccuracy (validation)");
            if (m_outputFile != null)
            {
                m_outputFile.WriteLine(string.Format("{0} layers, {1} output nodes", m_layers.Count, m_layers[m_layers.Count - 1].Count));
                m_outputFile.WriteLine("Momentum: " + m_momentum);
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
                m_outputFile.WriteLine("Epoch\tMSE (training)\t\tMSE (validation)\taccuracy (validation)");
            }

            do
            {
                // shuffle the training set
                trainFeatures.Shuffle(m_rand, trainLabels);

                double trainMSE;

                if (m_weights != null)
                {
                    // not training
                    trainMSE = VGetMSE(trainFeatures, trainLabels);
                    epoch++;
                }
                else
                {
                    trainMSE = TrainEpoch(++epoch, trainFeatures, trainLabels);
                }

                // check the MSE after this epoch
                double mse = VGetMSE(validationFeatures, validationLabels);

                // check the validation accuracy after this epoch
                double accuracy = VMeasureAccuracy(validationFeatures, validationLabels, null);

                Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", epoch, trainMSE, mse, accuracy));
                if (m_outputFile != null)
                {
                    m_outputFile.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", epoch, trainMSE, mse, accuracy));
                }

                if (m_weights != null)
                {
                    // not really training
                    done = true;
                }
                else if (mse == 0.0)
                {
                    // can't get better than this
                    done = true;
                }
                else if ((epoch == 1) || (mse <= bestMSE))
                {
                    if (epoch == 1)
                    {
                        // save the initial MSE
                        initialMSE = mse;
                    }
                    else if (!checkDone && (mse < initialMSE * 0.9))
                    {
                        checkDone = true;
                    }

                    // save the best for later
                    bestTrainMSE = trainMSE;
                    bestMSE      = mse;
                    bestAccuracy = accuracy;
                    bestEpoch    = epoch;
                    eCount       = 0;
                    for (var layer = 0; layer < m_layers.Count - 1; layer++)
                    {
                        foreach (var node in m_layers[layer])
                        {
                            node.SaveBestWeights();
                        }
                    }
                }
                else if (checkDone)
                {
                    // check to see if we're done
                    eCount++;
                    if (eCount >= 20)
                    {
                        done = true;
                    }
                }
                else if (mse > initialMSE * 1.1)
                {
                    // are we getting really worse?
                    checkDone = true;
                }
                else if (epoch >= 10000)
                {
                    // time to stop
                    done = true;
                }
            } while (!done);

            if (m_outputFile != null)
            {
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
            }

            if ((bestEpoch > 0) && (bestEpoch != epoch))
            {
                for (var layer = 0; layer < m_layers.Count - 1; layer++)
                {
                    foreach (var node in m_layers[layer])
                    {
                        node.RestoreBestWeights();
                    }
                }
                if (m_outputFile != null)
                {
                    m_outputFile.WriteLine();
                    m_outputFile.WriteLine(string.Format("Best Weights (from Epoch {0}, trainMSE={1}, valMSE={2}, valAcc={3})", bestEpoch, bestTrainMSE, bestMSE, bestAccuracy));
                    PrintWeights();
                }
            }

            if (m_outputFile != null)
            {
                m_outputFile.Close();
            }
        }
예제 #6
0
        public override void VTrain(VMatrix features, VMatrix labels)
        {
            if (m_hidden.Length < 1)
            {
                m_hidden = new int[1] {
                    features.Cols() * 2
                };
            }

            // add the input nodes
            var iNodes = new List <Node>();

            for (var i = 0; i < features.Cols(); i++)
            {
                iNodes.Add(new InputNode(i, 0, m_rand));
            }

            m_layers.Add(iNodes);

            // figure out how many outputs we need
            var oCount = 0;

            for (var col = 0; col < labels.Cols(); col++)
            {
                var labelValueCount = labels.ValueCount(col);

                if (labelValueCount < 2)
                {
                    // continuous
                    oCount++;
                }
                else
                {
                    oCount += labelValueCount;
                }
            }

            var trainSize          = (int)(0.75 * features.Rows());
            var trainFeatures      = new VMatrix(features, 0, 0, trainSize, features.Cols());
            var trainLabels        = new VMatrix(labels, 0, 0, trainSize, labels.Cols());
            var validationFeatures = new VMatrix(features, trainSize, 0, features.Rows() - trainSize, features.Cols());
            var validationLabels   = new VMatrix(labels, trainSize, 0, labels.Rows() - trainSize, labels.Cols());

            Console.Write("Layers: ");
            Console.Write(features.Cols());
            Console.Write('x');
            for (var l = 0; l < m_hidden.Length; l++)
            {
                Console.Write(m_hidden[l]);
                Console.Write('x');
            }
            Console.WriteLine(oCount);
            Console.WriteLine("Momentum: " + m_momentum);
            Console.WriteLine("C: " + m_corruptLevel);
            Console.WriteLine("AF: " + m_activation);
            Console.WriteLine($"AParam: {m_actLeak},{m_actThreshold},{m_actSlope},{m_actRandom}");
            Console.WriteLine("TrainAll: " + m_trainAll);
            Console.WriteLine("R-E-C\tMSE (validation)");
            if (m_outputFile != null)
            {
                m_outputFile.Write("Layers: ");
                m_outputFile.Write(features.Cols());
                m_outputFile.Write('x');
                for (var l = 0; l < m_hidden.Length; l++)
                {
                    m_outputFile.Write(m_hidden[l]);
                    m_outputFile.Write('x');
                }
                m_outputFile.WriteLine(oCount);
                m_outputFile.WriteLine("Momentum: " + m_momentum);
                m_outputFile.WriteLine("C: " + m_corruptLevel);
                m_outputFile.WriteLine("AF: " + m_activation);
                m_outputFile.WriteLine($"AParam: {m_actLeak},{m_actThreshold},{m_actSlope},{m_actRandom}");
                m_outputFile.WriteLine("TrainAll: " + m_trainAll);
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("R-E-C\tMSE (validation)");
            }

            var maxRounds = (m_trainAll ? m_hidden.Length : m_hidden.Length + 1);

            for (var round = 1; round <= maxRounds; round++)
            {
                if (round <= m_hidden.Length)
                {
                    // add hidden nodes
                    var prevNodes = m_layers[m_layers.Count - 1].Count + 1;
                    var hNodes    = new List <Node>();

                    for (var n = 0; n < m_hidden[m_layers.Count - 1]; n++)
                    {
                        hNodes.Add(new HiddenNode(prevNodes, m_rand));
                    }

                    m_layers.Add(hNodes);

                    prevNodes = hNodes.Count + 1;

                    // add output nodes
                    var oNodes = new List <Node>();

                    // figure out how many outputs we need
                    for (var col = 0; col < labels.Cols(); col++)
                    {
                        var labelValueCount = labels.ValueCount(col);

                        if (labelValueCount < 2)
                        {
                            // continuous
                            oNodes.Add(new OutputNode(prevNodes, true, col, -1, m_rand));
                        }
                        else
                        {
                            for (var n = 0; n < labelValueCount; n++)
                            {
                                oNodes.Add(new OutputNode(prevNodes, false, col, n, m_rand));
                            }
                        }
                    }

                    m_layers.Add(oNodes);

                    InitNodes();
                }

                var epoch      = 0;                                     // current epoch number
                var bestEpoch  = 0;                                     // epoch number of best MSE
                var eCount     = 0;                                     // number of epochs since the best MSE
                var checkDone  = false;                                 // if true, check to see if we're done
                var initialMSE = double.MaxValue;                       // MSE for first epoch
                var bestMSE    = double.MaxValue;                       // best validation MSE so far

                for (; ;)
                {
                    // shuffle the training set
                    trainFeatures.Shuffle(m_rand, trainLabels);
                    TrainEpoch(++epoch, trainFeatures, trainLabels, round < m_hidden.Length, m_trainAll || (round > m_hidden.Length));

                    // check the MSE after this epoch
                    var mse = VGetMSE(validationFeatures, validationLabels);

                    Console.WriteLine($"{round}-{epoch}-{eCount}\t{mse}");
                    if (m_outputFile != null)
                    {
                        m_outputFile.WriteLine($"{round}-{epoch}-{eCount}\t{mse}");
                        m_outputFile.Flush();
                    }

                    if ((mse == 0.0) || (epoch > 10000))
                    {
                        break;
                    }
                    else if ((epoch == 1) || (mse < bestMSE))
                    {
                        if (epoch == 1)
                        {
                            // save the initial MSE
                            initialMSE = mse;
                        }
                        else if (!checkDone && (mse < initialMSE * 0.9))
                        {
                            checkDone = true;
                        }
                        eCount = 0;

                        // save the best for later
                        bestMSE   = mse;
                        bestEpoch = epoch;
                        for (var layer = 0; layer < m_layers.Count - 1; layer++)
                        {
                            foreach (var node in m_layers[layer])
                            {
                                node.SaveBestWeights();
                            }
                        }
                    }
                    else if (checkDone)
                    {
                        // check to see if we're done
                        eCount++;
                        if (eCount >= 20)
                        {
                            break;
                        }
                    }
                    else if ((epoch > 100) && /*(mse < initialMSE) &&*/ (mse > ((bestMSE + initialMSE) / 2)))
                    {
                        checkDone = true;
                    }
                }

                if (round < m_hidden.Length)
                {
                    // delete the output layer
                    m_layers.RemoveAt(m_layers.Count - 1);
                }

                if ((bestEpoch > 0) && (bestEpoch != epoch))
                {
                    for (var layer = 0; layer < m_layers.Count - 1; layer++)
                    {
                        foreach (var node in m_layers[layer])
                        {
                            node.RestoreBestWeights();
                        }
                    }

                    Console.WriteLine($"Best Weights (from Epoch {bestEpoch}, valMSE={bestMSE})");
                    if (m_outputFile != null)
                    {
                        m_outputFile.WriteLine();
                        m_outputFile.WriteLine($"Best Weights (from Epoch {bestEpoch}, valMSE={bestMSE})");
                        m_outputFile.Flush();
                    }
                }
            }

            if (m_outputFile != null)
            {
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
            }

            if (m_outputFile != null)
            {
                m_outputFile.Close();
            }
        }
예제 #7
0
        public override void VTrain(VMatrix features, VMatrix labels)
        {
            if (m_hidden.Length < 1)
            {
                m_hidden = new int[1] {
                    features.Cols() * 2
                };
            }

            // add the input nodes
            List <Node> iNodes = new List <Node>();

            for (var i = 0; i < features.Cols(); i++)
            {
                iNodes.Add(new InputNode(i, 0, m_rand));
            }

            m_layers.Add(iNodes);

            int prevNodes = iNodes.Count + 1;
            int wIdx      = 0;                                                          // index into the weights array

            // add the hidden nodes
            for (var layer = 0; layer < m_hidden.Length; layer++)
            {
                // add the nodes for this layer
                List <Node> hNodes = new List <Node>();

                // if not the last 2 hidden layers, add c bias weight
                if (layer < m_hidden.Length - 2)
                {
                    prevNodes++;
                }

                for (var n = 0; n < m_hidden[layer]; n++)
                {
                    if (m_weights != null)
                    {
                        hNodes.Add(new HiddenNode(prevNodes, m_rand, m_weights[wIdx++]));
                    }
                    else
                    {
                        hNodes.Add(new HiddenNode(prevNodes, m_rand, null));
                    }
                }

                prevNodes = hNodes.Count + 1;
                m_layers.Add(hNodes);
            }

            // add the output nodes - figure out how many outputs we need
            List <Node> oNodes = new List <Node>();

            for (var col = 0; col < labels.Cols(); col++)
            {
                var labelValueCount = labels.ValueCount(col);

                if (labelValueCount < 2)
                {
                    // continuous
                    if (m_weights != null)
                    {
                        oNodes.Add(new OutputNode(prevNodes, true, col, -1, m_rand, m_weights[wIdx++]));
                    }
                    else
                    {
                        oNodes.Add(new OutputNode(prevNodes, true, col, -1, m_rand, null));
                    }
                }
                else
                {
                    for (var n = 0; n < labelValueCount; n++)
                    {
                        if (m_weights != null)
                        {
                            oNodes.Add(new OutputNode(prevNodes, false, col, n, m_rand, m_weights[wIdx++]));
                        }
                        else
                        {
                            oNodes.Add(new OutputNode(prevNodes, false, col, n, m_rand, null));
                        }
                    }
                }
            }

            m_layers.Add(oNodes);

            InitNodes();

            int     trainSize          = (int)(0.75 * features.Rows());
            VMatrix trainFeatures      = new VMatrix(features, 0, 0, trainSize, features.Cols());
            VMatrix trainLabels        = new VMatrix(labels, 0, 0, trainSize, labels.Cols());
            VMatrix validationFeatures = new VMatrix(features, trainSize, 0, features.Rows() - trainSize, features.Cols());
            VMatrix validationLabels   = new VMatrix(labels, trainSize, 0, labels.Rows() - trainSize, labels.Cols());

            int    epoch     = 0;                               // current epoch number
            int    bestEpoch = 0;                               // epoch number of best MSE
            int    eCount;                                      // number of epochs since the best MSE
            bool   checkDone;                                   // if true, check to see if we're done
            double bestTrainMSE = double.MaxValue;              // best training MSE so far
            double bestMSE      = double.MaxValue;              // best validation MSE so far
            double bestAccuracy = double.MaxValue;              // best validationa accuracy so far

            Console.WriteLine("Epoch\tMSE (training)\t\tMSE (validation)\taccuracy (validation)");
            if (m_outputFile != null)
            {
                m_outputFile.WriteLine(string.Format("{0} layers, {1} output nodes", m_layers.Count, m_layers[m_layers.Count - 1].Count));
                m_outputFile.WriteLine("Momentum: " + m_momentum);
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
                m_outputFile.WriteLine("Epoch\tMSE (training)\t\tMSE (validation)\taccuracy (validation)");
            }

            if (m_weights != null)
            {
                // not training
                double trainMSE = VGetMSE(trainFeatures, trainLabels);
                epoch = 1;
                double mse      = VGetMSE(validationFeatures, validationLabels);
                double accuracy = VMeasureAccuracy(validationFeatures, validationLabels, null);
                Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", epoch, trainMSE, mse, accuracy));
                if (m_outputFile != null)
                {
                    m_outputFile.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", epoch, trainMSE, mse, accuracy));
                }
            }
            else
            {
                for (int hLayer = 1; hLayer <= m_hidden.Length; hLayer++)
                {
                    if (hLayer < m_hidden.Length)
                    {
                        // dbn layer
                        epoch     = 0;
                        eCount    = 0;
                        checkDone = false;
                        double wDelta    = 0;
                        double lastDelta = 0;
                        double bestDelta = double.MaxValue;
                        int    maxEpochs = 500000 / trainFeatures.Rows();
                        if (maxEpochs < 10)
                        {
                            maxEpochs = 10;
                        }

                        for (; ;)
                        {
                            // shuffle the training set
                            trainFeatures.Shuffle(m_rand, trainLabels);
                            wDelta = TrainDBN(hLayer, ++epoch, trainFeatures, trainLabels);

                            Console.WriteLine(string.Format("{0}\t{1}", epoch, wDelta));
                            if (m_outputFile != null)
                            {
                                m_outputFile.WriteLine(string.Format("{0}\t{1}", epoch, wDelta));
                            }

                            if (epoch > maxEpochs)
                            {
                                break;
                            }
                            else if (epoch == 1)
                            {
                                bestDelta = wDelta;
                            }
                            else if ((wDelta / lastDelta) >= 0.99)
                            {
                                if (!checkDone)
                                {
                                    checkDone = true;
                                    eCount    = 0;
                                }
                            }
                            else if (wDelta < bestDelta)
                            {
                                checkDone = false;
                            }
                            else if (!checkDone)
                            {
                                checkDone = true;
                                eCount    = 0;
                            }

                            if (checkDone)
                            {
                                // check to see if we're done
                                eCount++;
                                if (eCount >= 5)
                                {
                                    break;
                                }
                            }

                            if (wDelta < bestDelta)
                            {
                                bestDelta = wDelta;
                            }
                            lastDelta = wDelta;
                        }
                    }
                    else
                    {
                        // final hidden layer
                        epoch     = 0;
                        eCount    = 0;
                        checkDone = false;

                        double initialMSE = double.MaxValue;                            // MSE for first epoch

                        for (; ;)
                        {
                            // shuffle the training set
                            trainFeatures.Shuffle(m_rand, trainLabels);
                            double trainMSE = TrainEpoch(++epoch, trainFeatures, trainLabels);

                            // check the MSE after this epoch
                            double mse = VGetMSE(validationFeatures, validationLabels);

                            // check the validation accuracy after this epoch
                            double accuracy = VMeasureAccuracy(validationFeatures, validationLabels, null);

                            Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", epoch, trainMSE, mse, accuracy));
                            if (m_outputFile != null)
                            {
                                m_outputFile.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", epoch, trainMSE, mse, accuracy));
                            }

                            if (mse == 0.0)
                            {
                                // can't get better than this
                                break;
                            }
                            else if ((epoch == 1) || (mse <= bestMSE))
                            {
                                if (epoch == 1)
                                {
                                    // save the initial MSE
                                    initialMSE = mse;
                                }
                                else if (!checkDone && (mse < initialMSE * 0.9))
                                {
                                    checkDone = true;
                                }

                                // save the best for later
                                bestTrainMSE = trainMSE;
                                bestMSE      = mse;
                                bestAccuracy = accuracy;
                                bestEpoch    = epoch;
                                eCount       = 0;
                                for (var layer = 0; layer < m_layers.Count - 1; layer++)
                                {
                                    foreach (var node in m_layers[layer])
                                    {
                                        node.SaveBestWeights();
                                    }
                                }
                            }
                            else if (checkDone)
                            {
                                // check to see if we're done
                                eCount++;
                                if (eCount >= 20)
                                {
                                    break;
                                }
                            }
                            else if (mse > initialMSE * 1.1)
                            {
                                // are we getting really worse?
                                checkDone = true;
                            }
                            else if (epoch >= 10000)
                            {
                                // time to stop
                                break;
                            }
                        }
                    }
                }
            }

            if (m_outputFile != null)
            {
                m_outputFile.WriteLine();
                m_outputFile.WriteLine("Weights");
                PrintWeights();
            }

            if ((bestEpoch > 0) && (bestEpoch != epoch))
            {
                for (var layer = 0; layer < m_layers.Count - 1; layer++)
                {
                    foreach (var node in m_layers[layer])
                    {
                        node.RestoreBestWeights();
                    }
                }
                if (m_outputFile != null)
                {
                    m_outputFile.WriteLine();
                    m_outputFile.WriteLine(string.Format("Best Weights (from Epoch {0}, trainMSE={1}, valMSE={2}, valAcc={3})", bestEpoch, bestTrainMSE, bestMSE, bestAccuracy));
                    PrintWeights();
                }
            }

            if (m_outputFile != null)
            {
                m_outputFile.Close();
            }
        }
예제 #8
0
        public override void VTrain(VMatrix features, VMatrix labels)
        {
            if (labels.ValueCount(0) > 2)
            {
                m_count = labels.ValueCount(0);
            }

            // create one set of weights for each output
            m_weights = new List <double[]>();
            for (var p = 0; p < m_count; p++)
            {
                var weights = new double[features.Cols() + 1];
                for (var i = 0; i < weights.Length; i++)
                {
                    weights[i] = 1.0 - (m_rand.NextDouble() * 2.0);
                }
                m_weights.Add(weights);
            }

            // iterate through each of the instances
            for (var instance = 0; instance < m_count; instance++)
            {
                double error;                                          // error rate for the current epoch
                var    bestError    = 1.0;                             // best (smallest) error rate so far
                var    eCount       = 0;                               // number of epochs since the best error
                var    epoch        = 0;                               // current epoch number
                var    done         = false;
                double bestAccuracy = 0;                               // best accuracy so far
                var    bestEpoch    = 0;                               // epoch number of best accuracy
                var    bestWeights  = new double[features.Cols() + 1]; // best weights

                if (m_outputFile != null)
                {
                    m_outputFile.WriteLine("Instance " + instance);
                    m_outputFile.WriteLine("Epoch\tError Rate");
                }

                do
                {
                    // shuffle the training set
                    features.Shuffle(m_rand, labels);

                    error = TrainEpoch(instance, ++epoch, features, labels);

                    // check the accuracy after this epoch
                    var accuracy = GetAccuracy(instance, features, labels);
                    if (accuracy > bestAccuracy)
                    {
                        // save the best for later
                        bestAccuracy = accuracy;
                        bestEpoch    = epoch;
                        for (var i = 0; i < bestWeights.Length; i++)
                        {
                            bestWeights[i] = m_weights[instance][i];
                        }
                    }

                    if (error == 0.0)
                    {
                        // can't get better than this
                        done = true;
                    }
                    else if ((epoch == 1) || (error <= bestError))
                    {
                        // save the best error so far
                        bestError = error;
                        eCount    = 0;
                    }
                    else
                    {
                        // check to see if we're done
                        eCount++;
                        if (eCount >= 10)
                        {
                            done = true;
                        }
                    }
                } while (!done);

                if (m_outputFile != null)
                {
                    m_outputFile.WriteLine();
                    m_outputFile.WriteLine("Weights");
                    for (var i = 0; i < m_weights[instance].Length - 1; i++)
                    {
                        m_outputFile.Write(string.Format("{0}\t", m_weights[instance][i]));
                    }
                    m_outputFile.WriteLine(string.Format("{0}\t", m_weights[instance][m_weights[instance].Length - 1]));
                    m_outputFile.WriteLine();
                }

                if (bestEpoch != epoch)
                {
                    for (var i = 0; i < bestWeights.Length; i++)
                    {
                        m_weights[instance][i] = bestWeights[i];
                    }
                    if (m_outputFile != null)
                    {
                        m_outputFile.WriteLine();
                        m_outputFile.WriteLine(string.Format("Best Weights (from Epoch {0}, accuracy={1})", bestEpoch, bestAccuracy));
                        for (var i = 0; i < m_weights[instance].Length - 1; i++)
                        {
                            m_outputFile.Write(string.Format("{0}\t", m_weights[instance][i]));
                        }
                        m_outputFile.WriteLine(string.Format("{0}\t", m_weights[instance][m_weights[instance].Length - 1]));
                        m_outputFile.WriteLine();
                    }
                }
            }

            if (m_outputFile != null)
            {
                m_outputFile.Close();
            }
        }