c++ - 在 S 型神经网络 C++ 中使用反向传播,异或总是向 0.5 收敛

标签 c++ neural-network backpropagation

再次感谢您花时间阅读这篇文章。

我知道这个问题已经被问了很多,而且我已经检查了很多关于这个问题的帖子:然而,我对使用反向传播的成功 XOR 学习的探索仍未完成。

我按照建议尝试调整学习率、动量、有/无偏差等,但仍然没有成功。

网络由 2 个输入神经元、2 个隐藏神经元、1 个输出、所有 Sigmoid 组成。 对于每个输入,输出神经元似乎总是收敛在 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;
}

再次感谢您阅读本文,我知道这个问题已经被问了很多次了! 为我指明正确的方向将不胜感激。

最佳答案

有趣的是,如果它可以帮助某人,从 Sigmoid() 网络更改为 TanH() 网络解决了这个问题。

在某种程度上它确实有意义,然而,Sigmoid 传递函数似乎非常适合此类问题,因为 XOR 已经在 0 和 1 之间标准化...

关于c++ - 在 S 型神经网络 C++ 中使用反向传播,异或总是向 0.5 收敛,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42403003/

相关文章:

python - 前馈神经网络语言模型

c++ - 为什么会有函数隐式转换为 boolean 值?

c++ - DirectShow 过滤器 : Transform

python - 如何评估/提高具有不平衡数据集的神经网络预测的准确性?

c++矩阵模板库需要用于神经网络计算

machine-learning - 激活函数的导数与偏导数。损失函数

python - 修正线性单元的反向传播

neural-network - 我可以在反向传播过程中(选择性地)反转Theano梯度吗?

c++ - 创建对象后创建 shared_ptr

c++ - 使用重载运算符时获取临时错误的地址