我一直在努力掌握反向传播的技巧,并找到了用于此操作的标准数学公式。我实现了一个看似正常工作的解决方案(并且以优异的成绩通过了相关测试)。
然而……实际的解决方案(在MATLAB中实现,并使用向量化)在两个重要方面与公式不符。
公式看起来是这样的:
delta-layer2 = (Theta-layer2 转置) x delta-layer3 点乘 x gprime(– 现在不重要)
工作代码看起来是这样的:
% d3 是 delta3,d2 是 delta2,Theta2 是减去偏置列% 维度:d3--[5000x10], d2--[5000x25], Theta2--[10x25]d3 = (a3 - y2);d2 = (d3 * Theta2) .* gPrime(z2);
我无法将我实现的内容与数学公式调和,原因有二:
- 工作代码在表达式的第一部分中颠倒了项;
- 工作代码没有转置 Theta-layer2,但公式要求转置。
这是怎么回事?各个矩阵的维度似乎不允许有其他工作组合。
Josh
回答:
这个问题没有错,我不知道为什么会收到那些负评;反向传播算法的实现并不像看起来那么直观。我数学不太好,也从未使用过MATLAB(通常使用C语言),所以我最初避免回答这个问题,但它值得回答。
首先,我们需要做一些简化。
1° 我们将仅使用一个 in_Data
集合,因此:vector in_Data[N]
(在下面的例子中 N = 2)(如果我们仅使用一个路径成功了,那么扩展到矩阵并不困难)。
2° 我们将使用这种结构:2 I, 2 H, 2 O(如果我们能用这个成功,我们就能应对所有情况)这个网络(我从这个博客上借来的)
让我们开始:我们知道为了更新权重:
注意: M=num_pattern
,但我们之前声明 in_data
为向量,所以你可以删除上述公式中的求和以及下面的公式中的矩阵。所以这是你的新公式:
我们将研究两个连接:w1 和 w5。让我们写出导数:
让我们编写代码:(我真的不太懂MATLAB,所以我会写一个伪代码)
vector d[num_connections+num_output_neurons] // 导数的数量 = 连接的数量(不包括偏置,有8个连接); +2 输出神经元的导数vector z[num_neurons] // z 是每个神经元的输出。vector w[num_connections] // 是的,一个向量!我们之前已经移除了矩阵和求和。// O 层d[10] = (a[O1] - y[O1]); // 从最后开始计算误差。 d[9] = (a[O2] - y[O2]); // H -> O 层for i=5; i<=8; i++ (隐藏到输出层连接){ d[i] = (d)*g_prime(z[i])}// I -> H 层 for i=1; i<=8 i++ (输入到隐藏层连接){ for j=1; i<=num_connection_from_neuron i++ (以 d[1] 为例,它取决于 H1 与输出的连接数量){ d[i] = d1 + (d[j+4]*w[j+4] ) } d[i] = d[i]*g_prime(z[i]);}
如果你需要将其扩展到矩阵,请在评论中说明,我会扩展代码。
这样你就找到了所有的导数。也许这并不是你确切在寻找的。我甚至不确定我写的所有内容都是正确的(我希望是正确的)。我将在这些天尝试编写反向传播代码,以便能够纠正错误(如果有的话)。我希望这对你有所帮助,总比没有好。
此致,Marco。