我的单层感知器收敛于OR数据集,但不收敛于AND数据集

时间:2018-05-19 21:56:28

标签: python machine-learning neural-network perceptron

我正在构建我的第一个单层感知器网络,我正在训练它以模拟最简单的逻辑门(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之间的各种数字,但无效。并10000eta0.1之间的任何地方。

观察下面的汇聚图,您将看到神经网络如何更好地收集OR数据集,而不是AND数据集,正如“渐渐稀疏”所描述的那样。橙色情节。 enter image description here

我认为OR和AND门是相反的,如果网络在一个网络上运行,那么它应该在另一个上工作。我在这里缺少什么?

此处我附上了1.0

的源代码

注意:当你看到你时,我会看到我已经将权重矩阵初始化为1s而不是某些随机值。这只是因为我想要一些确定性来帮助我排除故障。据我了解,它不应该影响算法的正确性(虽然它可能会使收敛速度变慢)。 在@Dennis Soemers'之后,权重现已正确初始化为一些随机值。建议。问题依然存在。

nn.py

1 个答案:

答案 0 :(得分:4)

除了关于权重随机初始化的说明(现在已经解决了,将该点移到了答案的底部),重要的是要注意您使用tanh作为激​​活,但是期望输出接近01tanh更适合您期望[-1, 1]而不是[0, 1]的输出的情况。

我怀疑,使用您的网络架构,根本不可能使输出更接近AND问题的输出而不是您已经获得的输出。考虑tanh函数的这个图:

enter image description here

w0表示偏见的权重(始终为1),w1w2表示第一个和第二个输入的权重x1和分别为x2。我们的输出总是y = tanh(w0 + w1 x1 + w2 x2)

让我们首先考虑x1 = x2 = 0的情况,我们希望输出大约为0。换句话说,我们想拥有tanh(w0 + 0 + 0) ~= 0。如果您查看图片,只有当我们的偏见'权重w0本身也大约为0时才有可能。

现在,请考虑x1 = 1x2 = 1,其他输入为1的情况。同样,期望的输出是0,从上面我们已经知道我们必须有w0 ~= 0。所以,现在我们知道我们希望以下两件事情大致正确:

  • tanh(w1 x1) = 0
  • tanh(w2 x2) = 0

如果我们再次查看图片,我们会再次看到,如果权重w1w2大约等于0,则上述两个点都只能为真。所以,现在我们只考虑了四种可能的输入中的三种,我们已经卡住了想要使所有的权重大致等于0。如果我们想要这个,我们输出的最终输入注定也大致等于0。因此,总而言之,使用tanh()激活函数和您为网络选择的特定体系结构,无法精确获得AND问题所需的输出值。

注意:如果您采取稍微不那么严格的“解决”概念,您所拥有的网络仍然能够成功“解决”AND问题。请注意,根据您获得的结果,它可以干净地分离不同的案例。它并不能干净地提供非常接近01的输出,但您可以很容易地提出一个阈值(例如0.5)并说“下面的每个输出此阈值被视为0,其上方的每个输出都被视为1“。

如果您希望输出更接近精确01,则可以考虑使用sigmoid function代替tanh。它具有非常相似的形状,但仅在[0, 1](恰好是您想要的输出范围)而不是[-1, 1]生成输出。

  

注意:当你看,你会发现我已经将权重矩阵初始化为1s而不是某些随机值。这只是因为我想要一些确定性来帮助我排除故障。据我了解,它不应该影响算法的正确性(尽管它可能会使收敛速度变慢)

这确实是您问题的原因(或至少是)。当所有权重具有相同的初始值时,您将获得无法再破坏的对称性。一些权重对将始终具有相同的起始值,相同的梯度,相同的错误,并且完全相同地更新(意味着它们保持永久相同)。您还可以在输出和错误中看到这一点;注意有些数字几乎相同(在AND问题的情况下,一个恰好是另一个的负数)。

您将需要使用随机初始权重,以便从头开始打破这些对称性。如果你想要确定性,你可以通过使用随机数生成器的固定种子来做到这一点,这样你总能获得相同的“随机”初始权重。