我目前正在编写一个反向传播脚本。我不确定如何更新我的体重值。这是一个简单的图像。
我的问题:如何计算和应用错误?
我知道k1和k2会产生错误值。我知道k1和k2会产生单独的错误值(目标 - 输出)。但我不知道是否要使用这些。
我是否应该使用两个错误值的平均值,然后将该单个错误值应用于所有权重?
或者我应该:
update weight Wk1j1 and Wk1j2 with the error value of k1
update weight Wk2j1 and Wk2j2 with the error value of k2
update weight Wj1i1 and Wj1i2 with the error value of j1
update weight Wj2i1 and Wj2i2 with the error value of j2
在你开始拍摄之前,我知道我必须使用sigmoids功能等。这不是问题。它总是声明我必须计算输出的误差值,这是我感到困惑的地方。
然后通过以下方式获取净误差值:
((error_k1^2) + (error_k2^2) + (error_j1^2) + (error_j2^2)) / 2
来自维基:
如图所示,对于每个输出节点都是如此,在我的图像示例中为k1和k2。维基。
图像下方的两行是delta Wh和delta Wi。我应该使用哪个错误值(这基本上是我的问题,我应该用哪个错误值计算新的重量)
答案:
http://www4.rgu.ac.uk/files/chapter3%20-%20bp.pdf 第3页(notad as 18)#4
答案 0 :(得分:2)
反向传播不直接使用错误值。你反向传播的是关于神经网络的每个元素的错误的偏导数。最终为每个重量提供 dE / dW ,并向该渐变的方向迈出一小步。
要做到这一点,你需要知道:
每个神经元的激活值(在进行前馈计算时保留)
误差函数的数学形式(例如,它可以是平方差的和)。输出图层的第一组导数 dE / da (其中 E 是您的错误, a 是神经元的输出)
神经元激活或转移功能的数学形式。您可以在这里找到我们使用 sigmoid 的原因,因为sigmoid函数的 dy / dx 可以方便地用激活值表示, dy / dx = y *(1 - y) - 这很快,也意味着您不必存储或重新计算加权金额。
请注意,我将使用您的其他符号,因为您的标签使得难以表达反向传播的一般形式。
用我的表示法:
括号中的上标(k)或(k + 1)标识网络中的图层。
(k)层中有 N 神经元,用下标 i 索引
层(k + 1)中有 M 神经元,用下标 j
神经元的输入总和是 z
神经元的输出是 a
权重 W ij 并连接 a i in layer (k 到层(k + 1)中的 z j 。注意 W 0j 是偏差项的权重,有时你需要包括它,尽管你的图表没有显示偏差输入或权重。
使用上述表示法,反向传播算法的一般形式是一个五步过程:
1)计算输出层中每个神经元的初始 dE / da 。 E 是您的错误值, a 是神经元的激活。这完全取决于您的错误功能。
然后,对于每一层(以 k =最大值,输出层开始)
2)为每个神经元反向传播 dE / da 到 dE / dz ( a 是你的神经元输出, z < / strong>是图层内所有输入的总和,包括偏差。除了需要知道上面(1)中的值之外,还使用了传递函数的导数:
(现在将 k 减少1,以便与循环的其余部分保持一致):
3)对于上一层中的所有输出,从上层反向传播 dE / dz 到 dE / da 。这基本上涉及将输出神经元连接到上层输入的所有权重的求和。您不需要为输入层执行此操作。请注意它如何使用您在(2)
中计算的值
4)(独立于(3))对于将该层连接到前一层的所有权重,将 dE / dz 从上层反向传播到 dE / dW (此包括偏见词):
只需重复2到4,直到你的所有重量都 dE / dW 。对于更高级的网络(例如,循环播放),您可以通过重新执行步骤1来添加其他错误源。
5)现在你有了权重导数,你可以简单地减去它们(乘以一个学习率),向你希望最小的误差函数迈出一步:
第一次看到这个时,数学符号看起来有点密集。但是如果你看几次,你会看到基本上只有少数变量,并且它们被 i,j,k 值的某种组合索引。此外,使用Matlab,您可以非常轻松地表达向量和矩阵。例如,这就是学习单个培训示例的整个过程:
clear ; close all; clc; more off
InputVector = [ 0.5, 0.2 ];
TrainingOutputVector = [ 0.1, 0.9 ];
learn_rate = 1.0;
W_InputToHidden = randn( 3, 2 ) * 0.6;
W_HiddenToOutput = randn( 3, 2 ) * 0.6;
for i=1:20,
% Feed-forward input to hidden layer
InputsPlusBias = [1, InputVector];
HiddenActivations = 1.0 ./ (1.0 + exp(-InputsPlusBias * W_InputToHidden));
% Feed-forward hidden layer to output layer
HiddenPlusBias = [ 1, HiddenActivations ];
OutputActivations = 1.0 ./ (1.0 + exp(-HiddenPlusBias * W_HiddenToOutput));
% Backprop step 1: dE/da for output layer (assumes mean square error)
OutputActivationDeltas = OutputActivations - TrainingOutputVector;
nn_error = sum( OutputActivationDeltas .* OutputActivationDeltas ) / 2;
fprintf( 'Epoch %d, error %f\n', i, nn_error);
% Steps 2 & 3 combined:
% Back propagate dE/da on output layer to dE/da on hidden layer
% (uses sigmoid derivative)
HiddenActivationDeltas = ( OutputActivationDeltas * W_HiddenToOutput(2:end,:)'
.* ( HiddenActivations .* (1 - HiddenActivations) ) );
% Steps 2 & 4 combined (twice):
% Back propagate dE/da to dE/dW
W_InputToHidden_Deltas = InputsPlusBias' * HiddenActivationDeltas;
W_HiddenToOutput_Deltas = HiddenPlusBias' * OutputActivationDeltas;
% Step 5: Alter the weights
W_InputToHidden -= learn_rate * W_InputToHidden_Deltas;
W_HiddenToOutput -= learn_rate * W_HiddenToOutput_Deltas;
end;
正如所写,这是随机梯度下降(每个训练样例改变一次权重),显然只是学习一个训练样例。
为地方的伪数学符号道歉。与数据溢出不同,Stack Overflow没有简单的内置类似LaTex的数学。我已经跳过了第3步和第4步的一些推导/解释,以避免这个答案永远消失。
答案 1 :(得分:1)
了解神经网络(多层感知器,特别是)如何发挥其神奇作用,可以让机器学习的学生深感满意。特别是如果你能真正完成一项工作并解决简单的分类问题。鉴于您的强烈兴趣,您一定会成功。
一旦你意识到这样的事实,为了训练神经网络,你需要以某种方式计算关于权重的误差的偏导数,反向传播可以通过将其简化为三个核心概念而容易地和定性地导出: (1)拳击 (2)敏感度和 (3)体重更新。 你已经知道(3)是必要的。
我同意刺激性和密集的数学公式(“这个符号又意味着什么?”)让大多数学生不能享受这段旅程。事实上,这个领域的先驱之一伯纳德威德罗就这么说了。
在我今年早些时候撰写的白皮书中(没有编号方程式!),我尽力设计一种直观的符号,使其易于连接到符号化的概念。调用输入I,输出O,目标T等的行。
阅读此内容可能会帮助您解决问题(以及更多): A Gentle Introduction to Backpropagation. 本文包含用于实现算法的伪代码(用于训练神经网络的训练轮)。
伪代码将引导您完成以下易于理解的步骤: