Нейронная сеть на C++
уже которую неделю пытаюсь научиться написанию нейронных сетей, но что бы я ни пробовал, сеть не хочет обучаться ни в какую. Перед этим изучал теорию, всё вроде бы просто и понятно, но когда дело доходит до практики - ничего не работает. Сейчас я остановился на данном (всё ещё не рабочем) варианте:
#include <iostream>
#include <math.h>
#include <clocale>
#include <string.h>
using namespace std;
double sig(double x);
double grad(double x);
int CIN();
double ABS(double x);
const int lays = 3;
const int ne = 3;
double t[ne]; //Æåëàåìîå
double N[ne][lays]; //Íåéðîíû
double W[ne][ne][lays - 1]; //Âåñà
double e[ne][ne][lays - 1];
double E[ne][lays]; // îøèáêè
const double a = 0.1;
bool lever1 = false;
//string boofer;
int main(int argc, char** argv) {
short count = 0;
setlocale(0, "");
for (short ck1 = 0; ck1 < ne; ck1++)
for (short ck2 = 0; ck2 < ne; ck2++)
for (short ck3 = 0; ck3 < lays - 1; ck3++)
W[ck1][ck2][ck3] = (rand() % 998 + 1) / 1000.0;
while (true) {
cout << "______________ñêîëüêî ðàç îáó÷àòü:_____________\n";
cin >> count;
if (count != 0) {
//bool bf1;
//bool bf2;
cout << "______________Âõîä:_____________\n";
cin >> N[0][0];
cin >> N[1][0];
N[2][0] = 0.1;
cout << "______________Âûõîä:_____________\n";
cin >> t[0];
t[1] = 0.1;
t[2] = 0.1;
for (short i = 0; i < count; i++) {
//bf1 = rand() % 2;
//bf2 = rand() % 2;
//N[0][0] = 0.1 + 0.8 * bf1;
//N[1][0] = 0.1 + 0.8 * bf2;
//t[0] = 0.5 + 0.1 * (bf1 || bf2) && (bf1 != bf2);
//t[1] = 0.5;
for (short ck1 = 1; ck1 < lays; ck1++)
for (short ck3 = 0 ; ck3 < ne; ck3++)
N[ck3][ck1] = 0;
for (short ck1 = 0; ck1 < lays - 1; ck1++)
for (short ck2 = 0; ck2 < ne; ck2++)
for (short ck3 = 0 ; ck3 < ne; ck3++)
N[ck3][ck1 + 1] += N[ck2][ck1] * W[ck2][ck3][ck1];
for (short ck1 = 1; ck1 < lays; ck1++)
for (short ck3 = 0 ; ck3 < ne; ck3++)
N[ck3][ck1] = sig(N[ck3][ck1]);
for (short ck3 = 0 ; ck3 < ne; ck3++)
N[ck3][0] = sig(N[ck3][0]);
for (short ck = 0; ck < ne; ck++)
E[ck][lays - 1] = (t[ck] - N[ck][lays - 1]) * (t[ck] - N[ck][lays - 1]);
for (short ck1 = lays - 1; ck1 > 0; ck1--) {
for (short ck2 = 0; ck2 < ne; ck2++)
for (short ck3 = 0 ; ck3 < ne; ck3++)
e[ck2][ck3][ck1 - 1] = E[ck3][ck1] * W[ck2][ck3][ck1 - 1] / (W[0][ck3][ck1 - 1] + W[1][ck3][ck1 - 1] + W[2][ck3][ck1 - 1]);
for (short ck2 = 0; ck2 < ne; ck2++)
E[ck2][ck1 - 1] = e[ck2][0][ck1 - 1] + e[ck2][1][ck1 - 1] + e[ck2][2][ck1 - 1];
}
for (short ck1 = 0; ck1 < lays - 1; ck1++)
for (short ck2 = 0; ck2 < ne; ck2++)
for (short ck3 = 0; ck3 < ne; ck3++) //Функция обновления весов:
//W[ck2][ck3][ck1] += a * e[ck2][ck3][ck1] * (1 - N[ck2][ck1 - 1] * N[ck2][ck1 - 1]) * W[ck2][ck3][ck1];
W[ck2][ck3][ck1] += a * e[ck2][ck3][ck1] * (1 - N[ck2][ck1 - 1]) * N[ck2][ck1 - 1] * W[ck2][ck3][ck1];
for (short ck1 = 0; ck1 < lays; ck1++) {
for (short ck2 = 0; ck2 < ne; ck2++)
cout << "_______íåéðîí ¹" << ck2 << " è ñëîÿ " << ck1 << " --> " << N[ck2][ck1] << "______\n";
cout << "\n";
}
cout << "_____________________________________________________________________________\n";
/*
for (short ck3 = 0; ck3 < lays - 1; ck3++) {
for (short ck1 = 0; ck1 < ne; ck1++)
for (short ck2 = 0; ck2 < ne; ck2++)
cout << "_____âåñ ñ " << ck1 << " ïî " << ck2 << " ñëîÿ " << ck3 << " --> " << a * e[ck2][ck3][ck1] * (1 - N[ck2][ck1 - 1] * N[ck2][ck1 - 1]) * W[ck2][ck3][ck1] << "____\n";
cout << "\n";
}
cout << "\n";
/*
for (short ck1 = 0; ck1 < lays - 1; ck1++) {
for (short ck2 = 0; ck2 < ne; ck2++)
for (short ck3 = 0; ck3 < ne; ck3++)
cout << "_____ãðàäèåíò ñ " << ck2 << " ïî " << ck3 << " ñëîÿ " << ck1 << " --> " << a * e[ck2][ck3][ck1] * (1 - N[ck2][ck1 - 1] * N[ck2][ck1 - 1]) * W[ck2][ck3][ck1] << "____\n";
cout << "\n";
}
cout << "\n";
*/
}
} else {
for (short ck = 0; ck < ne; ck++) {
cout << "____________ " << ck << " íåéðîí_____________\n";
cin >> N[ck][0];
}
for (short i = 0; i < 1; i++) {
for (short ck1 = 1; ck1 < lays; ck1++)
for (short ck3 = 0 ; ck3 < ne; ck3++)
N[ck3][ck1] = 0;
for (short ck1 = 0; ck1 < lays - 1; ck1++)
for (short ck2 = 0; ck2 < ne; ck2++)
for (short ck3 = 0 ; ck3 < ne; ck3++)
N[ck3][ck1 + 1] += N[ck2][ck1] * W[ck2][ck3][ck1];
for (short ck1 = 1; ck1 < lays; ck1++)
for (short ck3 = 0 ; ck3 < ne; ck3++)
N[ck3][ck1] = sig(N[ck3][ck1]);
for (short ck1 = 0; ck1 < lays; ck1++) {
for (short ck2 = 0; ck2 < ne; ck2++)
cout << "_______íåéðîí ¹" << ck2 << " è ñëîÿ " << ck1 << " --> " << N[ck2][ck1] << "______\n";
cout << "\n";
}
cout << "_____________________________________________________________________________\n";
for (short ck3 = 0; ck3 < lays - 1; ck3++) {
for (short ck1 = 0; ck1 < ne; ck1++)
for (short ck2 = 0; ck2 < ne; ck2++)
cout << "_____âåñ ñ " << ck1 << " ïî " << ck2 << " ñëîÿ " << ck3 << " --> " << W[ck1][ck2][ck3] << "____\n";
cout << "\n";
}
cout << "\n";
for (short ck1 = 0; ck1 < lays - 1; ck1++) {
for (short ck2 = 0; ck2 < ne; ck2++)
for (short ck3 = 0; ck3 < ne; ck3++)
cout << "_____ãðàäèåíò ñ " << ck2 << " ïî " << ck3 << " ñëîÿ " << ck1 << " --> ïóñòà " << ck2 << "____\n";
cout << "\n";
}
cout << "\n";
}
}
}
}
double sig(double x) {
return 1/(1.0 + exp(-x));
}
Кто-нибудь может подсказать простейший пример обратного распространения ошибки. На сколько я разобрался, проблема именно в этом.