XOR всегда сходится к 0,5 с помощью обратного распространения в сигмоидальной нейронной сети Переполнение стека

Еще раз спасибо, что нашли время, чтобы прочитать этот пост.

Я знаю, что этот вопрос задавали много раз, и я проверил много сообщений об этой проблеме: однако мои поиски успешного изучения XOR с использованием обратного распространения остаются незаконченными.

Я пытался, как и предполагалось, настроить скорость обучения, импульс, с / без предвзятости и т. Д., Но все еще безуспешно.

Сеть состоит из 2 входных нейронов, 2 скрытых нейронов, 1 выхода, все Сигмоида.
Выходной нейрон, кажется, всегда сходится около 0,5 для каждого входа.

Поэтому я прошу ваши драгоценные навыки по этому вопросу.
Я использую самодельную библиотеку C ++ (так что я могу глубоко изучить, как работают основы).

Вот интересующие меня строки моего кода:

Получить производную ошибки от выходного нейрона

void ClOutputSigmoidNeuron::ComputeErrorGradient()
{
double wanted_output = this->m_dataset->GetNextData();
double delta = wanted_output - this->m_result_buffer;
this->m_error_gradient = delta * this->SigmoidDerivative(this->m_result_buffer);
}

Получить производную от скрытого нейрона

void ClSigmoidNeuron::ComputeErrorGradient()
{
double tmpBuffer = 0.00;
for(std::size_t i=0;i<this->m_output_connections.size();i++)
{
ClNeuron* target_neuron = (ClNeuron*)m_output_connections[i]->m_target_neuron;
tmpBuffer += (target_neuron->m_error_gradient * this->m_output_connections[i]->m_weight);
}

//Get the sigmoid derivative
this->m_error_gradient = tmpBuffer * this->SigmoidDerivative(this->m_result_buffer);
}

Обновление весов для общего нейрона:

void ClNeuron::UpdateWeights()
{
for(std::size_t i=0;i<this->m_input_connections.size();i++)
{
double momentum = this->m_input_connections[i]->m_weight_last_delta * this->m_input_connections[i]->m_momentum_value;
double new_weight_delta = this->m_learning_rate * this->m_error_gradient * this->m_input_connections[i]->m_data + momentum ;
this->m_input_connections[i]->m_weight += new_weight_delta;
this->m_input_connections[i]->m_weight_last_delta = new_weight_delta;
this->m_input_connections[i]->m_number_of_time_updated++;
}
}

Передаточные функции

double ClNeuron::Sigmoid(double p_value)
{
return 1.00 / (1.00 + std::exp(p_value*-1.00));
}double ClNeuron::SigmoidDerivative(double p_value)
{
double sigmoid = this->Sigmoid(p_value);
return sigmoid * (1.00 - sigmoid);
}

Функция используется для обучения

bool ClBackPropagationSupervisedTrainer::Train()
{
for (std::size_t i = 0; i < this->m_dataset_size; i++)
{
this->m_network->Fire();

if (!this->m_network->ComputeErrorGradients())
{
std::cout << "ClBackPropagationSupervisedTrainer:Train - Oups" << std::endl;
return false;
}

this->m_network->UpdateWeights();
}

return true;
}

Опять же, спасибо за чтение, я знаю, что этот вопрос задавали много!
Указывать мне в правильном направлении будет принята с благодарностью.

2

Решение

Интересно, что в случае, если это может кому-то помочь, переход от сети Sigmoid () к сети TanH () решил проблему.

В некотором смысле это имеет смысл, и все же функция передачи Сигмоида кажется идеальной для такого рода проблем, поскольку XOR уже нормализован между 0 & 1 …

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector