.NET 4.x Непонятное поведение ИНС - C#
Формулировка задачи:
Здравствуйте дорогие мои друзья!
Решил я создать нейронную сеть.
В итоге вышло вот это :
Проблема в том, при обучении, которое используется в коде, приведенном выше, средняя ошибка не опускается ниже 25%
С нейронными сетями работаю впервые, по этому и не стал создавать целые библиотеки классов для этого.
буду ОООчень благодарен за объяснение, почему не тренируется данная сеть!
P.S: В результате наблюдения выяснилось, что данная нейронная сеть хорошо обучается только некоторым и случайным "вариациям" операции XOR
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();Решение задачи: «.NET 4.x Непонятное поведение ИНС»
textual
Листинг программы
int InputNeurons = 2; int HiddenNeurons = 50; int OutputNeurons = 1;