Exemple #1
0
        static void Train(
            Net net,
            Loss lossFn,
            Dataset dataset,
            int epochs            = Config.NUM_EPOCHS,
            int logEvery          = Config.LOG_EVERY,
            float validationRatio = 0.2f
            )
        {
            Console.WriteLine(STARLINE);
            Console.WriteLine("TRAINING");
            Console.WriteLine(UNDERLINE);

            // Reserve some elements for validation
            var validationSize    = (int)MathF.Round(dataset.Length * validationRatio);
            var numberOfExamples  = dataset.Length - validationSize;
            var validationIndices = Enumerable.Range(0, validationSize).ToArray();

            string epochFormat = 'D' + epochs.ToString().Length.ToString();

            var learningRate = Config.LEARNING_RATE;

            for (int epoch = 0; epoch < epochs; ++epoch)
            {
                var epochLosses     = new float[numberOfExamples];
                var epochIndicators = new float[numberOfExamples];
                net.SetLearningRate(learningRate);
                for (int i = validationSize; i < numberOfExamples; ++i)
                {
                    var dataAndAnswer   = dataset.GetItem(i);
                    var output          = net.ForwardPass(dataAndAnswer.Item1);
                    var outputAndAnswer = new Tuple <float[], float[]>(output, dataAndAnswer.Item2);
                    var gradient        = lossFn.Derivative(outputAndAnswer);

                    epochLosses[i]     = lossFn.Calculate(outputAndAnswer).Average();
                    epochIndicators[i] = Convert.ToSingle(
                        (MathF.Round(output[0]) == dataAndAnswer.Item2[0]) &&
                        (MathF.Round(output[1]) == dataAndAnswer.Item2[1])
                        );
                    net.BackwardPass(gradient);
                }

                Console.WriteLine($"epoch: [{(epoch + 1).ToString(epochFormat)}/{epochs}]\tmean loss: {epochLosses.Average():F5}\taccuracy: {epochIndicators.Average()}");

                // Log validation results if needed
                if ((epoch + 1) % logEvery == 0)
                {
                    Console.WriteLine(SEPARATOR);
                    Evaluate(
                        net: net,
                        lossFn: lossFn,
                        dataset: dataset,
                        indices: validationIndices
                        );
                    Console.WriteLine(SEPARATOR);
                }
                if ((epoch + 1) % (epochs / 3) == 0)
                {
                    var newLearningRate = learningRate * 0.1f;
                    Console.WriteLine(SEPARATOR);
                    Console.WriteLine($"Learning rate decayed from: {learningRate} to {newLearningRate}");
                    learningRate = newLearningRate;
                    Console.WriteLine(SEPARATOR);
                }
            }
            Console.WriteLine("\nFINISHED");
            Console.WriteLine(STARLINE);
        }