Я пытаюсь заставить простую искусственную нейронную сеть работать с алгоритмом обратного распространения. Я создал ANN и считаю, что правильно реализовал алгоритм BP, но, конечно, могу ошибаться.
Прямо сейчас я пытаюсь обучить сеть, задав ей два случайных числа (a, b) между 0 и 0.5 и добавив их. Затем, конечно, каждый раз, когда выходной сигнал сети сравнивается с теоретическим ответом a + b (который всегда будет достигнут функцией сигмоида).
Странно, но вывод всегда сходится к числу от 0 до 1 (как и должно быть из-за сигмоидальной функции), но вводимые мной случайные числа, похоже, не влияют на него.
Редактировать: Извините, похоже, он не сходится. Вот изображение вывода:
Веса случайным образом распределены между -1 и 1, но я также пробовал между 0 и 1.
Я также попытался дать ему два постоянных числа (0,35,0,9) и попытаться обучить его выплевывать 0,5. Это работает и сходится очень быстро до 0,5. Я также научил его выплевывать 0,5, если я даю ему любые два случайных числа от 0 до 1, и это тоже работает.
Если вместо этого моя цель:
vector<double> target;
target.push_back(.5);
Тогда он очень быстро сходится, даже при случайных входах:
Я пробовал пару разных сетей, так как я очень легко добавил слои в свою сеть. Стандартный, который я использую, - один с двумя входами, один слой из 2 нейронов и второй слой только с одним нейроном (выходной нейрон). Однако я также попытался добавить несколько слоев и добавить к ним нейроны. Кажется, это ничего не меняет. Моя скорость обучения равна 1,0, хотя я пробовал ее на 0,5, и она не сильно отличалась.
Кто-нибудь знает, что я могу попробовать?
Это даже на что способен ANN? Я не могу себе представить, что этого не произойдет, поскольку их можно научить делать такие сложные вещи.
Любой совет? Спасибо!
Вот где я тренируюсь:
//Initialize it. This will be one with 2 layers, the first having 2 Neurons and the second (output layer) having 1.
vector<int> networkSize;
networkSize.push_back(2);
networkSize.push_back(1);
NeuralNetwork myNet(networkSize,2);
for(int i = 0; i<5000; i++){
double a = randSmallNum();
double b = randSmallNum();
cout << "\n\n\nInputs: " << a << ", " << b << " with expected target: " << a + b;
vector<double> myInput;
myInput.push_back(a);
myInput.push_back(b);
vector<double> target;
target.push_back(a + b);
cout << endl << "Iteration " << i;
vector<double> output = myNet.backPropagate(myInput,target);
cout << "Output gotten: " << output[0];
resultPlot << i << "\t" << abs(output[0] - target[0]) << endl;
}
Редактировать: я настроил свою сеть и следовал этому руководству: A pdf . Я реализовал «Рабочий пример 3.1» и получил те же точные результаты, что и они, поэтому я думаю, что моя реализация верна, по крайней мере, настолько, насколько у них.