C++ 手写数字输出的神经网络高估
所以,我尝试创建自己的神经网络。非常简单的事情 我的输入是手写数字的MNIST数据库。 输入:28*28个神经元(图像)。 输出:10个神经元(0/1/2/3/4/5/6/7/8/9)。 所以我的网络如下:28*28->15->10 问题仍然存在于我的估计产出中。事实上,我似乎有一个梯度爆炸 我的网络给出的输出如下: 如您所见,第一次估计的输出是错误的。因此,由于反向传播,我的网络调整了权重。但它似乎没有正确地更新权重。事实上,与第二高值相比,估计的产出太高了。 因此,第一个估计输出始终是后续培训的最佳估计输出(在我的示例中为13) 我的反向传播代码:C++ 手写数字输出的神经网络高估,c++,tensorflow,neural-network,artificial-intelligence,conv-neural-network,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 问题仍然存在于我的估计产出中。事实上,我似乎有一个梯度爆炸 我的网络给出的输出如下: 如您所见,第一次估计的输出是错误的。因此,由于反向传播,我的网络调整了权重。但它似乎没有正确地更新权重。事实上,与第二高值相比,估计的产出太高了。 因此,第一个估计输出始终是后续培
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++;
}
}}
VOID BP(网络和网络,双目标[输出神经元]){
双DeltaETotalOut=0;
双DeltaOutNet=0;
双三角网=0;
双三角总重量=0;
双误差=0;
双重错误总数=0;
双输出更新权重[OUTPUT_NEURONS*HIDDEN_NEURONS]={0};
无符号整数_indexOutput=0;
双fNetworkError=0;
//计算误差
对于(int i=0;i
我如何解决这个问题?
我没有研究隐藏层或偏见,这是因为它吗?
谢谢,因为反向传播是出了名的难以实现,特别是调试(我想每个做过反向传播的人都会有关联),所以调试别人编写的一些代码要困难得多 在快速查看代码之后,我很惊讶您计算了一个负的增量项?您是否使用ReLU或任何sigmoid函数?我敢肯定还有更多。但我建议你在找到解决XOR的网络之前远离MNIST 我已经在伪代码中写了一篇关于如何在伪代码中实现反向传播的摘要。我相信你能很容易地把它翻译成C++。
根据我的经验,神经网络确实应该通过矩阵运算来实现。这将使您的代码更快、更易于调试 调试反向传播的方法是使用有限差分法。对于损失函数
J(θ)
我们可以用(J(θ+epsilon*d)-J(θ))/epsilon
和d
表示一个维度的一个热向量来近似每个维度的梯度(注意与导数的相似性)