2017-02-22 2 views
2

Еще раз спасибо за то, что нашли время, чтобы прочитать это сообщение.XOR всегда сходится к 0,5 с использованием backpropagation in Sigmoidal neural net C++

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

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

Сеть состоит из 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; 
} 

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

ответ

1

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

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

Смежные вопросы