проблема с NeuronDotNet в C # - PullRequest
0 голосов
/ 05 июля 2011

Я хочу использовать NeuronDotNet в моем приложении. пожалуйста, рассмотрите этот класс:

using NeuronDotNet.Core;

public class CostomNeuralNetwork
        {
            public static double[] SampleInput = new double[] {4, 2, 8, 6, 15, 49, 22};
            public static double[] SampleOutput = new double[] {4, 2};

            private BackpropagationNetwork network;

            public CostomNeuralNetwork()
            {
                var inputLayer = new LinearLayer(7);
                var hiddenLayer = new SigmoidLayer(20);
                var outputLayer = new SigmoidLayer(2);

                new BackpropagationConnector(inputLayer, hiddenLayer).Initializer = new RandomFunction(0d, 0.3d);
                new BackpropagationConnector(hiddenLayer, outputLayer).Initializer = new RandomFunction(0d, 0.3d);

                network = new BackpropagationNetwork(inputLayer, outputLayer);
                network.SetLearningRate(0.3);
            }

            public void Train(double[] input,double []output)
            {
                var set = new TrainingSet(7, 2);
                set.Add(new TrainingSample(input, output));
                network.Learn(set, 10000);
            }

            public double[] Estimate(double[] input)
            {
                var res = network.Run(input);
                return res;
            }
        }

когда я пытаюсь использовать этот класс с этим кодом:

var costomNetwork = new CostomNeuralNetwork();
            costomNetwork.Train(CostomNeuralNetwork.SampleInput, CostomNeuralNetwork.SampleOutput);
            costomNetwork.Estimate(CostomNeuralNetwork.SampleInput);

всегда ответ, возвращаемый методом Estimate, представляет собой двойной массив, содержащий члены thow, значения которых равны 1.0 или что-то вроде 0.9999923. независимо от того, какие данные я передаю в метод оценивания, он всегда возвращает то же самое, что и ответ. я делаю что-то не так, чтобы при любом входе возвращался такой же выход? у кого-нибудь есть такая же проблема с этим кодом?

Ответы [ 3 ]

1 голос
/ 20 сентября 2011

Проблема здесь связана с самой NeuronDotNet, а не с вашей реализацией. В основном выходные данные обучения для нейрондотнета должны быть меньше 1 для сети BackPrpogation, код ниже работает нормально

public class LinearNeural
{
    public static double[] SampleInput = new double[] { 1d,2d,3d,4d,5d,6d,7d };
    public static double[] SampleOutput = new double[] { 0.01d, 0.02d, 0.06d, 0.08d, 0.10d, 0.12d, 0.14d };
    private double learningRate = 0.3d;
    private int neuronCount = 10;
    private int cycles = 100;
    private BackpropagationNetwork network;


    public LinearNeural()
    {

    }


    public List<double> DoWork()
    {

        LinearLayer inputLayer = new LinearLayer(1);
        LinearLayer hiddenLayer = new LinearLayer(neuronCount);
        LinearLayer outputLayer = new LinearLayer(1);
        new BackpropagationConnector(inputLayer, hiddenLayer).Initializer = new RandomFunction(0d, 0.3d);
        new BackpropagationConnector(hiddenLayer, outputLayer).Initializer = new RandomFunction(0d, 0.3d);
        network = new BackpropagationNetwork(inputLayer, outputLayer);
        network.SetLearningRate(learningRate);


        TrainingSet trainingSet = new TrainingSet(1, 1);

        for (int i = 0; i < SampleInput.Count(); i++)
        {
            double xVal = SampleInput[i];
            for (double input = SampleInput[i] - 0.05; input < SampleInput[i] + 0.06; input += 0.01)
            {
                trainingSet.Add(new TrainingSample(new double[] { input }, new double[] { SampleOutput[i] }));
            }
        }

        network.Learn(trainingSet, cycles);
        return StopLearning();

    }


    public List<double> StopLearning()
    {
        var retList = new List<double>();
        if (network != null)
        {
            network.StopLearning();
            for (double xVal = 0; xVal < 10; xVal += 0.05d)
            {
               retList.Add(network.Run(new double[] {xVal})[0]);
            }
        }
        return retList;
    }
0 голосов
/ 11 июля 2011

Прежде всего извините за поздний ответ.Теперь взгляните на функцию активации, которую вы используете для выходного слоя.Функция сигмоида (подробнее см. wikipedia ) может использоваться только для двоичных выходов (обычно от 0 до 1 для нормального сигмоида).Поэтому, если вы тренируете сеть таким образом, вы всегда будете получать 1 как результат, потому что это самое близкое значение к вашим желаемым выходам (4,2 или что-то еще).Попробуйте дать выходным модулям линейную функцию активации, которая должна работать намного лучше.Как сказал Фил, вы можете использовать некоторые другие параметры.Вот конфигурация, которая работала для меня:

  • hiddenLayer: sigmoid
  • outputLayer: linear
  • learningRate: 0.1 (0,3 слишком высоко)
  • эпох: 100 (больше, чем достаточно, но 10000 также в порядке, потому что это обратное распространение и очень простой пример, поэтому ничего не пошло бы не так).

    Как вы можете видеть на следующем рисунке,ошибка достигает 0 очень быстро (5% или около того, что означает 5 эпох):

development of error

А вот ссылка на программу, которую я использовал: Скачать NNSpace .Эта программа (NNSpace) также основана на платформе .NET и C #, но использует графический интерфейс пользователя вместо того, чтобы вручную кодировать каждый шаг.Если у вас есть какие-либо вопросы, не стесняйтесь связаться со мной по электронной почте .

РЕДАКТИРОВАТЬ: Извините, я забыл упомянуть, что я, конечно, создал несколько единиц смещения(никто не будет запускать backprop без них), не знаете, сделает ли NeuronDotNet это автоматически?

0 голосов
/ 05 июля 2011

Я вижу, что вы жестко запрограммировали несколько вещей (количество нейронов, количество слоев, скорость обучения, сигмовидную функцию и т. Д.). Когда я некоторое время назад работал с ANN, используя другую библиотеку, я обнаружил, что было бы очень полезно много экспериментировать с этими значениями. Библиотека, которую я использовал, обеспечивала пользовательский интерфейс, который позволял мне очень легко настраивать и экспериментировать с различными значениями, пока сеть не стала полезной.

Обучение сети стало намного проще с интерактивным графическим интерфейсом. После обучения в GUI я сохранил его на диск, а затем загрузил сеть в моем программном обеспечении. Если вы можете разработать такой рабочий процесс, вы можете избавить себя от головной боли.

Моим первым предложением было бы попробовать гораздо меньшую ценность для тренировочных эпох. 10000 кажется мне много. Вы не хотите, чтобы сеть переучивалась. Кроме того, если у вас есть способ увидеть весовые коэффициенты для каждого соединения нейрона, это может помочь привести вас к другим выводам.

EDIT: Вы также определенно захотите попробовать тренироваться с различными примерами входов и выходов, а не только с одним примером, который вы дали здесь. Сеть должна учиться на различных данных. Не пытайтесь преподавать это слишком тщательно на одном образце.

...