Ниже помещаю последнию версию кода, в надежде, что кто нибудь его когда нибудь посмотрит, и на этом Демо примере (который крайне необходим разработчику, а по чему то о нем ни кто не заботится, считая что он должен читать лирику о производных) покажет мне, где я восзможно ошибся или как можно добится более быстрой сходимости, на этом примере я получаю сходимость на 21261 итерации - кто быстре ?
public class BackProp
{
int ACount = 10;
int StimulCount = 5;
double[,] w1;
double[] w2;
double[,] PrevUpdate1;
double[] PrevUpdate2;
double[] y1;
//RCount=1
double y2 = 0;
//InputCount=3
double[,] y0 = { { 7, 4, 5 }, { 6, 4, 5 }, { 7, 5, 6 }, { 6, 3, 5 }, { 8, 5, 6 } };
double[] d = { 10, 20, 40, 50, 60 };
private bool checkAll = false;
private int checkCnt = 0;
double[] s1;
double s2 = 0;
double delta_m2 = 0;
double[] delta_m1;
double delta2 = 0;
double delta1 = 0;
private bool[] checkX = new bool[5];
public double F(double x)
{
return (1.0 / (1.0 + Math.Exp(-x)));
}
public double FF(double Fx)
{
return Fx * (1.0 - Fx);
}
public void ClearCheck()
{
checkCnt = 0;
for (int i = 0; i < StimulCount; i++)
{
checkX[i] = false;
}
}
public void Run()
{
w1 = new double[3, ACount];
w2 = new double[ACount];
PrevUpdate1 = new double[3, ACount];
PrevUpdate2 = new double[ACount];
y1 = new double[ACount];
s1 = new double[ACount];
delta_m1 = new double[ACount];
Random rnd=new Random(1);
for (int j = 0; j < ACount; j++)
{
w1[0, j] = rnd.NextDouble();
w1[1, j] = rnd.NextDouble();
w1[2, j] = rnd.NextDouble();
w2[j] = rnd.NextDouble();
}
double EachRate = 0.1;
double Momentum = 0.9;
int Iteration = 0;
while (!checkAll)
{
ClearCheck();
Iteration++;
for (int i = 0; i < StimulCount; i++)
{
// Прямой проход
s2 = 0;
for (int j = 0; j < ACount; j++)
{
s1[j] = w1[0, j] * y0[i, 0] + w1[1, j] * y0[i, 1] + w1[2, j] * y0[i, 2];
y1[j] = F(s1[j]);
s2 += w2[j] * y1[j];
}
y2 = F(s2);
// Проверка есть ли ошибка
Console.WriteLine("{0} = {1}", y2, (d[i] / 100));
if (Math.Abs(y2 - (d[i] / 100)) < 0.001)
{
checkX[i] = true;
}
delta_m2 = (y2 - (d[i] / 100)) * FF(y2);
for (int j = 0; j < ACount; j++)
{
delta_m1[j] = delta_m2 * w2[j] * FF(y1[j]);
}
// 10*3 связей первого слоя
for (int j = 0; j < ACount; j++)
{
for (int k = 0; k < 3; k++)
{
delta1 = -EachRate * delta_m1[j] * y0[i, k] + Momentum * PrevUpdate1[k, j];
w1[k, j] += delta1;
PrevUpdate1[k, j] = delta1;
}
}
// 10 связей второго слоя
for (int j = 0; j < ACount; j++)
{
delta2 = -EachRate * delta_m2 * y1[j] + Momentum * PrevUpdate2[j];
w2[j] += delta2;
PrevUpdate2[j] = delta2;
}
}
//Console.ReadLine();
for (int i = 0; i < StimulCount; i++)
{
if (checkX[i]) checkCnt++;
}
if (checkCnt == StimulCount)
{
checkAll = true;
}
Console.WriteLine("Iteration={0} - {1}", Iteration, checkCnt);
}
}
}