任何人都可以推荐一个网站或者简要介绍一下NN中如何实现反向传播?我理解基本概念,但我不确定如何编写代码。
我发现的很多资料只是显示方程而没有解释为什么他们这样做,变量名很难找到。
示例:
void bpnn_output_error(delta, target, output, nj, err)
double *delta, *target, *output, *err;
int nj;
{
int j;
double o, t, errsum;
errsum = 0.0;
for (j = 1; j <= nj; j++) {
o = output[j];
t = target[j];
delta[j] = o * (1.0 - o) * (t - o);
errsum += ABS(delta[j]);
}
*err = errsum;
}
在那个例子中,有人可以解释
的目的delta[j] = o * (1.0 - o) * (t - o);
感谢。
答案 0 :(得分:9)
的目的
delta [j] = o *(1.0 - o)*(t - o);
是在反向传播网络中找到输出节点的错误。
o表示节点的输出,t是节点的预期输出值。
术语,(o *(1.0 - o),是使用的常用传递函数的衍生物,sigmoid函数。(其他传递函数并不罕见,并且需要重写具有sigmoid的代码函数和导数之间的不匹配可能意味着训练不会收敛。)节点有一个“激活”值,通过传递函数输入以获得输出o,如
o = f(激活)
主要的是反向传播使用梯度下降,并且错误通过应用链规则向后传播。问题是信用分配问题,或者如果你愿意的话,对于输出不能与预期值直接比较的隐藏节点的问题。我们从已知和可比较的输出节点开始。误差与输出的一阶导数乘以预期输出和实际输出之间的原始误差值成比例。
更具象征意义的是,我们将该行写为
delta [j] = f'(activation_j)*(t_j - o_j)
其中f是你的传递函数,f'是它的第一个导数。
进一步回到隐藏层中,节点处的错误是其对下一层发现的错误的估计贡献。因此,后续图层的增量乘以连接权重,并将这些乘积相加。该总和乘以隐藏节点激活的一阶导数以获得隐藏节点的增量,或
delta [j] = f'(activation_j)* Sum(delta [k] * w_jk)
其中j现在引用隐藏节点,k引用后续层中的节点。
答案 1 :(得分:2)
(t-o)
是网络输出中的错误,因为t
是目标输出,o
是实际输出。它以标准化形式存储在delta
数组中。用于规范化的方法取决于实现,而o * ( 1.0 - o )
似乎正在这样做(我可能错误地认为这个假设)。
为整个训练集累积此归一化误差,以判断训练何时完成:通常当errsum
低于某个目标阈值时。
答案 2 :(得分:1)
实际上,如果你了解这个理论,程序应该很容易理解。您可以阅读本书并使用铅笔执行一些简单的示例,以确定传播的确切步骤。这是实现数值程序的一般原则,您必须在小案例中了解详细信息。
如果您了解Matlab,我建议您阅读一些Matlab源代码(例如here),这比C语言更容易理解。
对于你问题中的代码,名称是不言自明的,输出可能是你预测的数组,目标可能是训练标签的数组,delta是预测和真值之间的误差,它也可以作为要更新为权重向量的值。
答案 3 :(得分:0)
基本上,backprop所做的是在训练数据上运行网络,观察输出,然后调整节点的值,迭代地从输出节点返回到输入节点。