我正在构建我的第一个单层感知器网络,我正在训练它以模拟最简单的逻辑门(AND和OR)与两个输入的行为。
网络由两个输入节点和一个偏差组成。使用单层感知器的delta规则学习算法,tanh函数作为激活函数。
在对AND数据集进行培训时,网络应在给定输入1
时给出接近(1, 1)
的答案,对于任何其他输入(例如(0, 1)
,{{1 },或(1, 0)
。在对OR数据集进行训练时,如果给出(1, 1)
以外的任何输入,它应该返回接近1
的答案。
然而,它表现出一种我无法理解的行为。当我在OR数据集上训练时,它收敛得很好(即错误率非常低 - (0, 0)
或更低):
0.01
但是,它并没有很好地收敛于AND数据集:
$ python nn.py
[0 0]: (actual result = [[0.00051257]]). (expected result from training set=0, error rate=[[-0.00051257]])
[0 1]: (actual result = [[0.98865851]]). (expected result from training set=1, error rate=[[0.01134149]])
[1 0]: (actual result = [[0.98865222]]). (expected result from training set=1, error rate=[[0.01134778]])
[1 1]: (actual result = [[0.99993485]]). (expected result from training set=1, error rate=[[6.51512784e-05]])
我已尝试将$ python nn.py
[0 0]: (actual result = [[-0.28911014]]). (expected result from training set=0, error rate=[[0.28911014]])
[0 1]: (actual result = [[0.23984154]]). (expected result from training set=0, error rate=[[-0.23984154]])
[1 0]: (actual result = [[0.28911014]]). (expected result from training set=0, error rate=[[-0.28911014]])
[1 1]: (actual result = [[0.68570095]]). (expected result from training set=1, error rate=[[0.31429905]])
调整为epoch
- 500
之间的各种数字,但无效。并10000
到eta
到0.1
之间的任何地方。
观察下面的汇聚图,您将看到神经网络如何更好地收集OR数据集,而不是AND数据集,正如“渐渐稀疏”所描述的那样。橙色情节。
我认为OR和AND门是相反的,如果网络在一个网络上运行,那么它应该在另一个上工作。我在这里缺少什么?
此处我附上了1.0
。
注意:当你看到你时,我会看到我已经将权重矩阵初始化为1s而不是某些随机值。这只是因为我想要一些确定性来帮助我排除故障。据我了解,它不应该影响算法的正确性(虽然它可能会使收敛速度变慢)。
在@Dennis Soemers'之后,权重现已正确初始化为一些随机值。建议。问题依然存在。
nn.py
答案 0 :(得分:4)
除了关于权重随机初始化的说明(现在已经解决了,将该点移到了答案的底部),重要的是要注意您使用tanh
作为激活,但是期望输出接近0
或1
。 tanh
更适合您期望[-1, 1]
而不是[0, 1]
的输出的情况。
我怀疑,使用您的网络架构,根本不可能使输出更接近AND问题的输出而不是您已经获得的输出。考虑tanh
函数的这个图:
让w0
表示偏见的权重(始终为1
),w1
和w2
表示第一个和第二个输入的权重x1
和分别为x2
。我们的输出总是y = tanh(w0 + w1 x1 + w2 x2)
。
让我们首先考虑x1 = x2 = 0
的情况,我们希望输出大约为0
。换句话说,我们想拥有tanh(w0 + 0 + 0) ~= 0
。如果您查看图片,只有当我们的偏见'权重w0
本身也大约为0
时才有可能。
现在,请考虑x1 = 1
或x2 = 1
,其他输入为1
的情况。同样,期望的输出是0
,从上面我们已经知道我们必须有w0 ~= 0
。所以,现在我们知道我们希望以下两件事情大致正确:
tanh(w1 x1) = 0
tanh(w2 x2) = 0
如果我们再次查看图片,我们会再次看到,如果权重w1
和w2
大约等于0
,则上述两个点都只能为真。所以,现在我们只考虑了四种可能的输入中的三种,我们已经卡住了想要使所有的权重大致等于0
。如果我们想要这个,我们输出的最终输入注定也大致等于0
。因此,总而言之,使用tanh()
激活函数和您为网络选择的特定体系结构,无法精确获得AND问题所需的输出值。
注意:如果您采取稍微不那么严格的“解决”概念,您所拥有的网络仍然能够成功“解决”AND问题。请注意,根据您获得的结果,它可以干净地分离不同的案例。它并不能干净地提供非常接近0
或1
的输出,但您可以很容易地提出一个阈值(例如0.5
)并说“下面的每个输出此阈值被视为0
,其上方的每个输出都被视为1
“。
如果您希望输出更接近精确0
和1
,则可以考虑使用sigmoid function代替tanh
。它具有非常相似的形状,但仅在[0, 1]
(恰好是您想要的输出范围)而不是[-1, 1]
生成输出。
注意:当你看,你会发现我已经将权重矩阵初始化为1s而不是某些随机值。这只是因为我想要一些确定性来帮助我排除故障。据我了解,它不应该影响算法的正确性(尽管它可能会使收敛速度变慢)
这确实是您问题的原因(或至少是)。当所有权重具有相同的初始值时,您将获得无法再破坏的对称性。一些权重对将始终具有相同的起始值,相同的梯度,相同的错误,并且完全相同地更新(意味着它们保持永久相同)。您还可以在输出和错误中看到这一点;注意有些数字几乎相同(在AND问题的情况下,一个恰好是另一个的负数)。
您将需要使用随机初始权重,以便从头开始打破这些对称性。如果你想要确定性,你可以通过使用随机数生成器的固定种子来做到这一点,这样你总能获得相同的“随机”初始权重。