我在学习神经网络的过程中,已经实现了一些全连接网络。我通常会在输入矩阵中添加一列偏置单元
(1s),并在权重矩阵中添加一行额外的权重
,因为这是我在参加在线课程后学会实现神经网络的方式。但在GitHub上的许多实现中,我发现也可以不将偏置单元插入矩阵中,而是单独添加:XW + b
,其中b是偏置单元。
我不明白这是如何工作的。这似乎是一种更好、更高效的实现方式,但我无法理解。例如,考虑以下示例:
1 2 3 4 0.5 0.5 X = 1 4 5 6 W= 2 3 X*W = [4x2 matrix] 1 8 9 5 5 8 2 3
X中的第一列是偏置单元,W中的第一行也是
但如果不直接插入偏置列而是单独添加,则变为:
2 3 4 2 3 X= 4 5 6 W= 5 8 b = 0.5 0.5 X*W = [3x2 matrix] 8 9 5 2 3
可以清楚地看到,第二个表达式的X*W+b
不等于第一个表达式。而且b是一个1x2矩阵
,不能加到X*W
上,后者是一个3x2矩阵
。
那么,我该如何使用第二种方法实现偏置呢?
回答:
所展示的方法是相同的。
最重要的是:
权重只能取-1到1之间的值。
注意:第一个示例也会生成一个3×2矩阵。
1 2 3 4 0.5 0.5 27.5 42.5 X = 1 4 5 6 W= 2 3 X*W = 45.5 70.5 1 8 9 5 5 8 71.5 111.5 2 3
在最后的矩阵中,每行是一组输入,每列是一个神经元。
所展示的方法是相同的:
稍后添加偏置不是问题。
以第二个示例为例:
|27 42 | |27 42 | |0.5 0.5| X*W = |45 70 | X*W+b = |45 70 | + |0.5 0.5| : 相同的结果。 |71 111| |71 111| |0.5 0.5|
如果问题在这里:
参考以下链接中的公式:前馈公式
它假设了一个具有1个输入、1个隐藏和1个输出神经元的神经网络,并且不涉及矩阵乘法。这是一个前馈过程:
sumH1 = I x w1 + b x wb;
注意:(b x wb = 1 x wb = wb)。
这一过程随后在“实现”段落中编码:
z1 = x.dot(W1) + b1a1 = np.tanh(z1)z2 = a1.dot(W2) + b2
或者在这里:
在这里,他假设了一个具有2个输入、500个隐藏和2个输出神经元的示例,其中w1是I和H之间2×500连接中的一个,b1是H的500个偏置中的一个,w2是H和O之间2×500连接中的一个,b2是O的2个偏置中的一个。
总结
你可以使用矩阵进行前馈过程,但你必须为每个连接添加偏置。你展示的第一个示例是最简单的实现方式。显然,如果你选择第二个方法,你不能将1xN矩阵与3×2矩阵相乘。但你可以在调用激活函数时添加偏置:
a1 = tanH(z1 + b[1]);
两种方法中没有一种比另一种更好或更高效的实现。
在第二个示例中,你将矩阵分成了两部分:
I*W :matix[3x4] and b:vector[3] = { 1, 1 , 1 }
在这种情况下,你还需要在每个隐藏神经元上添加偏置。在你的第一个示例中,你直接添加了偏置,其中:matrix[0][0] = 1 x 0.5 + 2 x 2 + 3 x 5 等等..
注意:matrix[0][0] = sumH1;
在第二个示例中,你稍后添加偏置,其中:matrix[0][0] = 2 x 2 + 3 x 5 等等..
和 sumH1 = matrix[0][0] + B[0]
注意:这里的”B”指的是B的权重;B=1。
也许使用第二个示例,代码会显得稍微有序一些。仅此而已。在计算机性能或内存占用上没有显著变化。