.NET 4.x Непонятное поведение ИНС - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте дорогие мои друзья! Решил я создать нейронную сеть. В итоге вышло вот это :
Random Rnd = new Random();
 
Console.Clear();
 
int InputNeurons = 2;
int HiddenNeurons = 50;
int OutputNeurons = 1;
 
double[] Input = new double[InputNeurons];
double[,] Hidden = new double[2, HiddenNeurons];
double[,] Output = new double[2, OutputNeurons];
 
double[][] WInput = new double[InputNeurons][];
double[][] WHidden = new double[HiddenNeurons][];
 
Randomize();
 
double Err = 0;
do
{
    Err = 0;
 
    Input[0] = 0;
    Input[1] = 0;
    Count();
    Err += (0 - Output[1, 0]) * (0 - Output[1, 0]);
    Learn(new double[] { 0.0 }, 1);
 
    Input[0] = 0;
    Input[1] = 1;
    Count();
    Err += (1 - Output[1, 0]) * (1 - Output[1, 0]);
    Learn(new double[] { 1.0 }, 1);
 
    Input[0] = 1;
    Input[1] = 0;
    Count();
    Err += (1 - Output[1, 0]) * (1 - Output[1, 0]);
    Learn(new double[] { 1.0 }, 1);
 
    Input[0] = 1;
    Input[1] = 1;
    Count();
    Err += (0 - Output[1, 0]) * (0 - Output[1, 0]);
    Learn(new double[] { 0.0 }, 1);
    Err /= 4;
    Console.WriteLine(Err);
} while (Err > 0.01);
 
while (true)
{
    Console.Clear();
 
    double f = Convert.ToDouble(Console.ReadLine());
    double s = Convert.ToDouble(Console.ReadLine());
 
    Input[0] = f;
    Input[1] = s;
 
    Count();
 
    Console.WriteLine(Output[1, 0]);
    Console.ReadKey();
}
 
void Randomize()
                {
                    for (int i = 0; i < InputNeurons; i++)
                    {
                        WInput[i] = new double[HiddenNeurons];
                        for (int k = 0; k < WInput[i].Length; k++)
                        {
                            WInput[i][k] = Convert.ToDouble(Rnd.Next(-5, 6)) / 10;
                        }
                    }
 
                    for (int i = 0; i < HiddenNeurons; i++)
                    {
                        WHidden[i] = new double[OutputNeurons];
                        for (int k = 0; k < WHidden[i].Length; k++)
                        {
                            WHidden[i][k] = Convert.ToDouble(Rnd.Next(-5, 6)) / 10;
                        }
                    }
                }
void Count()
                {
                    for (int Y = 0; Y < HiddenNeurons; Y++)
                    {
                        double Sum = 0;
                        for (int X = 0; X < InputNeurons; X++)
                        {
                            Sum += Input[X] * WInput[X][Y];
                        }
                        Hidden[0, Y] = Sum;
                        Hidden[1, Y] = Convert.ToDouble(1) / (1 + Math.Pow(Math.E, Convert.ToDouble(-1) * Convert.ToDouble(Sum)));
                    }
 
                    for (int Y = 0; Y < OutputNeurons; Y++)
                    {
                        double Sum = 0;
                        for (int X = 0; X < HiddenNeurons; X++)
                        {
                            Sum += Hidden[1, X] * WHidden[X][Y];
                        }
                        Output[0, Y] = Sum;
                        Output[1, Y] = Convert.ToDouble(1) / (1 + Math.Pow(Math.E, Convert.ToDouble(-1) * Convert.ToDouble(Sum)));
                    }
                }
void Learn(double[] Pending, double LearningSpeed)
{
    double[][] ChHidden = new double[HiddenNeurons][];
    double[][] ChInput = new double[InputNeurons][];
 
    double[] ErrorOutput = new double[OutputNeurons];
    double[] ErrorHidden = new double[HiddenNeurons];
 
    for (int i = 0; i < ChHidden.Length; i++)
    {
        ChHidden[i] = new double[OutputNeurons];
    }
    for (int i = 0; i < ChInput.Length; i++)
    {
        ChInput[i] = new double[HiddenNeurons];
    }
 
    for (int i = 0; i < OutputNeurons; i++)
    {
        ErrorOutput[i] = (Pending[i] - Output[1, i]) * Output[1, i] * (1 - Output[1, i]);
 
        for (int j = 0; j < HiddenNeurons; j++)
        {
            ChHidden[j][i] = (ErrorOutput[i] * WHidden[j][i]) * Hidden[1, j] * (Convert.ToDouble(1) - Hidden[1, j]) * LearningSpeed * Hidden[1, j];
        }
    }
 
    for (int Y = 0; Y < HiddenNeurons; Y++)
    {
        double Sum = 0;
        for (int X = 0; X < OutputNeurons; X++)
        {
            Sum += ErrorOutput[X] * WHidden[Y][X];
        }
        ErrorHidden[Y] = Sum;
    }
 
    for (int i = 0; i < HiddenNeurons; i++)
    {
        for (int j = 0; j < InputNeurons; j++)
        {
            ChInput[j][i] = ErrorHidden[i] * Hidden[1, j] * (Convert.ToDouble(1) - Hidden[1, j]) * LearningSpeed * Hidden[1, j];
        }
    }

    for (int i = 0; i < HiddenNeurons; i++)
    {
        for (int j = 0; j < OutputNeurons; j++)
        {
            WHidden[i][j] += ChHidden[i][j]; 
        }
    }
    for (int i = 0; i < InputNeurons; i++)
    {
        for (int j = 0; j < HiddenNeurons; j++)
        {
            WInput[i][j] += ChInput[i][j];
        }
    }
}
 
Console.ReadKey();
Проблема в том, при обучении, которое используется в коде, приведенном выше, средняя ошибка не опускается ниже 25% С нейронными сетями работаю впервые, по этому и не стал создавать целые библиотеки классов для этого. буду ОООчень благодарен за объяснение, почему не тренируется данная сеть! P.S: В результате наблюдения выяснилось, что данная нейронная сеть хорошо обучается только некоторым и случайным "вариациям" операции XOR

Решение задачи: «.NET 4.x Непонятное поведение ИНС»

textual
Листинг программы
int InputNeurons = 2;
int HiddenNeurons = 50;
int OutputNeurons = 1;

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.364 из 5
Похожие ответы