【问题标题】:Neural Network Overestimating output of handwritten digits神经网络高估手写数字的输出
【发布时间】:2018-08-29 08:40:49
【问题描述】:

所以,我尝试创建自己的神经网络。非常简单的事情。

我的输入是手写数字的 MNIST 数据库。 输入:28*28 个神经元(图像)。 输出:10 个神经元(0/1/2/3/4/5/6/7/8/9)。 所以我的网络如下:28*28 -> 15 -> 10.

问题仍然存在于我的估计输出中。确实,我好像有梯度爆炸。

我的网络给出的输出在这里:https://pastebin.com/EFpBGAZd

如您所见,第一个估计的输出是错误的。所以我的网络通过反向传播调整了权重。但它似乎没有正确更新权重。实际上,与第二高值相比,估计的输出太高了。 因此,第一个估计输出始终是后续训练的最佳估计输出(在我的示例中为 13)。

我的反向传播代码:

VOID BP(NETWORK &Network, double Target[OUTPUT_NEURONS]) {
double DeltaETotalOut = 0;
double DeltaOutNet = 0;
double DeltaErrorNet = 0;
double DeltaETotalWeight = 0;
double Error = 0;
double ErrorTotal = 0;
double OutputUpdatedWeights[OUTPUT_NEURONS*HIDDEN_NEURONS] = { 0 };
unsigned int _indexOutput = 0;
double fNetworkError = 0;

//Calculate Error
for (int i = 0; i < OUTPUT_NEURONS; i++) {
    fNetworkError += 0.5*pow(Target[i] - Network.OLayer.Cell[i].Output, 2); 
}
Network.Error = fNetworkError;


//Output Neurons
for (int i = 0; i < OUTPUT_NEURONS; i++) {
    DeltaETotalOut = -(Target[i] - Network.OLayer.Cell[i].Output); 
    DeltaOutNet = ActivateSigmoidPrime(Network.OLayer.Cell[i].Output); 

    for (int j = 0; j < HIDDEN_NEURONS; j++) {
        OutputUpdatedWeights[_indexOutput] = Network.OLayer.Cell[i].Weight[j] - 0.5 * DeltaOutNet*DeltaETotalOut* Network.HLayer.Cell[j].Output;
        _indexOutput++;
    }
}

//Hidden Neurons
for (int i = 0; i < HIDDEN_NEURONS; i++) {
    ErrorTotal = 0;
    for (int k = 0; k < OUTPUT_NEURONS; k++) {
        DeltaETotalOut = -(Target[k] - Network.OLayer.Cell[k].Output);
        DeltaOutNet = ActivateSigmoidPrime(Network.OLayer.Cell[k].Output);
        DeltaErrorNet = DeltaETotalOut * DeltaOutNet;
        Error = DeltaErrorNet * Network.OLayer.Cell[k].Weight[i];
        ErrorTotal += Error;
    }

    DeltaOutNet = ActivateSigmoidPrime(Network.HLayer.Cell[i].Output); 
    for (int j = 0; j < INPUT_NEURONS; j++) {
        DeltaETotalWeight = ErrorTotal * DeltaOutNet*Network.ILayer.Image[j];
        Network.HLayer.Cell[i].Weight[j] -= 0.5 * DeltaETotalWeight;
    }
}

//Update Weights
_indexOutput = 0;
for (int i = 0; i < OUTPUT_NEURONS; i++) {
    for (int j = 0; j < HIDDEN_NEURONS; j++) {
        Network.OLayer.Cell[i].Weight[j] = OutputUpdatedWeights[_indexOutput];
        _indexOutput++;
    }
}}

我该如何解决这个问题? 我没有在隐藏层上工作,也没有偏见,是因为它吗? 谢谢

【问题讨论】:

    标签: c++ tensorflow neural-network artificial-intelligence conv-neural-network


    【解决方案1】:

    嗯,由于反向传播是出了名的难以实现,尤其是调试(我想做过它的每个人都可以理解),因此调试其他人编写的一些代码要困难得多。

    在快速查看您的代码后,我很惊讶您计算出负 delta 项?您使用的是 ReLU 还是任何 sigmoid 函数?我很确定还有更多。但我建议你远离 MNIST,直到你的网络能够解决 XOR。

    我用伪代码写了一篇关于如何在伪代码中实现反向传播的总结。我相信你可以很容易地将它翻译成 C++。

    Strange convergence in simple Neural Network

    【讨论】:

      【解决方案2】:

      根据我的经验,神经网络确实应该使用矩阵运算来实现。这将使您的代码更快、更容易调试。

      调试反向传播的方法是使用有限差分。对于损失函数J(theta),我们可以用(J(theta + epsilon*d) - J(theta))/epsilond 来近似每个维度的梯度,d 是一个表示一维的单热向量(注意与导数的相似性)。

      https://en.wikipedia.org/wiki/Finite_difference_method

      【讨论】:

        猜你喜欢
        • 2017-04-11
        • 2016-11-04
        • 2019-11-30
        • 1970-01-01
        • 2015-02-23
        • 1970-01-01
        • 2020-03-15
        • 2015-06-24
        相关资源
        最近更新 更多