神经网络过高估计手写数字的输出

时间:2018-03-20 13:40:39

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

所以,我尝试创建自己的神经网络。真的很简单。

我的输入是手写数字的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++;
    }
}}

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

2 个答案:

答案 0 :(得分:0)

好吧,因为Backpropagation很难实现,尤其是调试(我想每个人都可以联系),调试其他人编写的代码要困难得多。

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

我在伪代码中写了一个关于如何在伪代码中实现Backpropagation的摘要。我相信你很容易将它翻译成C ++。

Strange convergence in simple Neural Network

答案 1 :(得分:0)

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

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

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