Haskell 神经网络总是为任何输入产生相同/相似的输出

Haskell 神经网络总是为任何输入产生相同/相似的输出,haskell,neural-network,Haskell,Neural Network,我有一个问题,我正试图创建一个神经网络的Tic-Tac-Toe。然而,出于某种原因,训练神经网络会使它对任何给定的输入产生几乎相同的输出 我确实看了一下,但我的网络实现是为神经元构建的,每个神经元都有相同的激活功能,即没有恒定的神经元 为了确保问题不仅仅是因为我选择了训练集(1218个板状态和由遗传算法生成的移动),我尝试训练网络来重现XOR。采用logistic激活函数。我没有使用导数,而是将误差乘以output*(1-output),因为一些资料表明这相当于使用导数。我可以将Haskell源

我有一个问题,我正试图创建一个神经网络的Tic-Tac-Toe。然而,出于某种原因,训练神经网络会使它对任何给定的输入产生几乎相同的输出

我确实看了一下,但我的网络实现是为神经元构建的,每个神经元都有相同的激活功能,即没有恒定的神经元

为了确保问题不仅仅是因为我选择了训练集(1218个板状态和由遗传算法生成的移动),我尝试训练网络来重现XOR。采用logistic激活函数。我没有使用导数,而是将误差乘以
output*(1-output)
,因为一些资料表明这相当于使用导数。我可以将Haskell源代码放在HPaste上,但这看起来有点尴尬。网络有3层:第一层有2个输入和4个输出,第二层有4个输入和1个输出,第三层有1个输出。在第二层增加到4个神经元没有帮助,在第一层增加到8个输出也没有帮助

然后,我手动计算错误、网络输出、偏差更新和权重更新,以确保代码的这些部分没有错误(没有,但我可能会再次这样做以确保)。因为我使用的是批量训练,所以在等式(4)中我没有乘以
x
。我增加了重量的变化,但建议减去它

即使在这个简化的网络中,问题依然存在。例如,这些是经过500次批量培训和增量培训后的结果

Input    |Target|Output (Batch)      |Output(Incremental)
[1.0,1.0]|[0.0] |[0.5003781562785173]|[0.5009731800870864]
[1.0,0.0]|[1.0] |[0.5003740346965251]|[0.5006347214672715]
[0.0,1.0]|[1.0] |[0.5003734471544522]|[0.500589332376345]
[0.0,0.0]|[0.0] |[0.5003674110937019]|[0.500095157458231]
减法而不是加法会产生同样的问题,只是所有的东西都是0.99而不是0.50。5000个历元产生相同的结果,除了批量训练网络对每种情况返回0.5。(见鬼,即使10000个纪元也不能用于批量培训。)

一般来说,有什么东西会导致这种行为吗

此外,我还研究了增量训练的中间误差,虽然隐藏/输入层的输入不同,但输出神经元的误差始终为+/-0.12。对于批量训练,误差在增加,但非常缓慢,误差都非常小(x10^-7)。不同的初始随机权重和偏差也没有区别

请注意,这是一个学校项目,因此提示/指南会更有帮助。虽然重新发明轮子和建立自己的网络(用一种我不太熟悉的语言!)是一个可怕的想法,但我觉得这更适合学校的项目(所以我知道发生了什么……至少在理论上是这样。我的学校似乎没有计算机科学老师)

编辑:两个层,一个输入层为2个输入到8个输出,一个输出层为8个输入到1个输出,生成的结果基本相同:每个培训案例的结果为0.5+/-0.2(左右)。我也在和pyBrain玩,看看那里的网络结构是否有效

编辑2:我使用的学习率为0.1。对不起,忘了这件事

编辑3:Pybrain的“TrainUntillConvergence”也没有给我提供一个经过充分训练的网络,但是20000个时代确实提供了,隐藏层中有16个神经元。10000个时代和4个神经元,虽然不多,但很接近。因此,在Haskell中,输入层有2个输入和2个输出,隐藏层有2个输入和8个输出,输出层有8个输入和1个输出…我在10000个纪元中遇到了同样的问题。有20000个时代

编辑4:我根据上面的MIT PDF再次手动运行网络,并且值匹配,因此代码应该是正确的,除非我误解了这些公式

我的一些源代码位于;我正在努力清理代码,并将其放入Github(而不是私有Bitbucket)存储库中


所有相关的源代码现在都在。

如果没有看到代码示例,很难判断,但偏差bug可能会产生这种影响(例如,忘记将偏差添加到输入中),因此,我将更仔细地查看代码的这一部分。

如果没有看到代码示例,很难判断,但网络可能会发生,因为它有隐藏的neron数。随着neron数和隐藏层数的增加,不可能用少量的训练数据训练网络。直到有可能用较小的层和nerons使用较大的网是错误的。因此,也许你的问题解决了,注意这一点

根据您的评论,我同意@finnw的说法,您存在偏见问题。您应该将偏差视为每个神经元的恒定“1”(或-1,如果您愿意)输入。每个神经元也会有自己的偏差权重,因此神经元的输出应该是经过激活函数的加权输入加上偏差乘以其权重的总和。偏差权重在训练期间会像其他权重一样进行更新

Fausett的《神经网络基础》(第300页)有一个异或示例,使用二进制输入和一个具有2个输入、1个隐藏层(由4个神经元和1个输出神经元组成)的网络。权重在+0.5和-0.5之间随机初始化。学习率为0.02时,示例网络在大约3000个时代后收敛。如果你解决了偏见问题(和任何其他错误),你应该能够在相同的范围内得到结果


还要注意的是,如果网络中没有隐藏层,就无法解决XOR问题。

我没有用问题中的XOR问题测试它,但对于我最初基于Tic-Tac-Toe的数据集,我相信我已经让网络进行了一定程度的训练(我只运行了1000个时代,这还不够):quickpropagation网络可以赢得/平局超过一半的比赛;反向传播可以得到约41%。问题归结为实现错误(小错误)和不理解
targets = torch.tensor([3.0, 2.0], dtype=torch.float32)
targets = torch.tensor([[3.0], [2.0]], dtype=torch.float32)
Step1 : Write the algorithm such that it can take variable number of input layers and variable number of input & output nodes.
Step2 : Reduce the hidden layers to 0. Reduce input to 2 nodes, output to 1 node.
Step3 : Now train for binary-OR-Operation.
Step4 : If it converges correctly, go to Step 8.
Step5 : If it doesn't converge, train it only for 1 training sample
Step6 : Print all the forward and prognostication variables (weights, node-outputs, deltas etc)
Step7 : Take pen&paper and calculate all the variables manually.
Step8 : Cross verify the values with algorithm.
Step9 : If you don't find any problem with 0 hidden layers. Increase hidden layer size to 1. Repeat step 5,6,7,8