#cpp #нейронные_сети #машинное_обучение
Здравствуйте. Пытался реализовать вот этот алгоритм http://robocraft.ru/blog/algorithm/560.html однако когда провел обучение сети, обнаружил, что выходные данные даже близко не соответствуют действительности. Где же я допустил ошибку? Или алгоритм по ссылке неправильный? Помогите разобраться. double OpenNNL::_changeWeightsByBP(double * trainingInputs, double *trainingOutputs, double speed, double sample_weight) { double * localGradients = new double[_neuronsCount]; double * outputs = new double[_neuronsCount]; double * derivatives = new double[_neuronsCount]; calculateNeuronsOutputsAndDerivatives(trainingInputs, outputs, derivatives); for(int j=0;j<_neuronsPerLayerCount[_layersCount-1];j++) { localGradients[indexByLayerAndNeuron(_layersCount-1, j)] = trainingOutputs[j] - outputs[indexByLayerAndNeuron(_layersCount-1, j)]; } if(_layersCount > 1) { for(int i=_layersCount-2;i>=0;i--) { for(int j=0;j<_neuronsPerLayerCount[i];j++) { localGradients[indexByLayerAndNeuron(i, j)] = 0; for(int k=0;k<_neuronsPerLayerCount[i+1];k++) { localGradients[indexByLayerAndNeuron(i, j)] += _neuronsInputsWeights[indexByLayerNeuronAndInput(i+1, k, j)] * localGradients[indexByLayerAndNeuron(i+1, k)]; } } } } for(int j=0;j<_neuronsPerLayerCount[0];j++) { for(int k=0;k<_inputsCount;k++) { _neuronsInputsWeights[indexByLayerNeuronAndInput(0, j, k)] += speed * localGradients[indexByLayerAndNeuron(0, j)] * derivatives[indexByLayerAndNeuron(0, j)] * trainingInputs[k]; } } for(int i=1;i<_layersCount;i++) { for(int j=0;j<_neuronsPerLayerCount[i];j++) { for(int k=0;k<_neuronsPerLayerCount[i-1];k++) { _neuronsInputsWeights[indexByLayerNeuronAndInput(i, j, k)] += speed * localGradients[indexByLayerAndNeuron(i, j)] * derivatives[indexByLayerAndNeuron(i, j)] * outputs[indexByLayerAndNeuron(i, j)]; } } } delete[] localGradients; delete[] outputs; delete[] derivatives; } И в том алгоритме не сказано, как настраивать смещения нейронов. Может кто-нибудь подсказать как это делать? Если вам понадобится полный код, то он здесь: https://github.com/NicholasShatokhin/OpenNNL
Ответы
Ответ 1
ох, нашел ошибку. В последнем цикле нужно было вместо outputs[indexByLayerAndNeuron(i, j)]; написать: outputs[indexByLayerAndNeuron(i-1, k)]; Все беды от невнимательности.Ответ 2
Таблица весовых коэффициентов синапсов localGradients должна быть размера _neuronsCount*_neuronsCount.Ответ 3
Я вот изучил данный алгоритм по ресурсу, который вы предоставили. Так вот, вы, наверное, "не заметили", что вторая часть полностью посвящена выявлению ошибки в выходном сигнале Y методом обратного распространения ошибки. Выходной сигнал сети y сравнивается с желаемым выходным сигналом z, который хранится в тренировочных данных. Разница между этими двумя сигналами называется ошибкой d выходного слоя сети. Ну, а далее, после этого уже идет выявление нейрона( или связки нейронов одного уровня ), где произошла ошибка( по контрольной сумме, вычисленной функцией f(x) или по суммам контрольных сумм, если имеем дело со связкой ). Выявление происходит распространении сигнала ошибки d (вычисленного в шаге обучения) обратно на все нейроны, чьи выходные сигналы были входящими для последнего нейрона. Собственно, поэтому алгоритм так и называется.
Комментариев нет:
Отправить комментарий