我有一个问题,我正在尝试为Tic-Tac-Toe创建一个神经网络。但是,出于某种原因,训练神经网络会导致它为任何给定的输入产生几乎相同的输出。
我确实看过Artificial neural networks benchmark,但我的网络实现是针对每个神经元具有相同激活功能的神经元构建的,即没有恒定的神经元。
为了确保问题不仅仅是由于我选择的训练集(1218板状态和遗传算法产生的移动),我试图训练网络重现XOR。使用逻辑激活函数。我没有使用导数,而是将误差乘以output*(1-output)
,因为有些消息来源暗示这相当于使用导数。我可以将Haskell源代码放在HPaste上,但看起来有点尴尬。网络有3层:第一层有2个输入和4个输出,第二层有4个输入和1个输出,第三层有1个输出。在第二层中增加到4个神经元没有帮助,在第一层中也没有增加到8个输出。
然后,我根据http://hebb.mit.edu/courses/9.641/2002/lectures/lecture04.pdf手动计算错误,网络输出,偏差更新和权重更新,以确保代码的这些部分没有错误(没有,但我可能会再做一次只是为了确保)。因为我正在使用批量训练,所以我没有在等式(4)中乘以x
。我正在添加重量变化,但http://www.faqs.org/faqs/ai-faq/neural-nets/part2/section-2.html建议减去重量。
即使在这个简化的网络中,问题仍然存在。例如,这些是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的“trainUntilConvergence”也没有让我成为一个训练有素的网络,但20000个时代确实如此,隐藏层中有16个神经元。 10000个时代和4个神经元,不是那么多,而是接近。因此,在Haskell中,输入层具有2个输入和输入。 2个输出,隐藏层有2个输入和8个输出,输出层有8个输入和1个输出......我遇到10000个时期的相同问题。并有20000个时代。
编辑4:我根据上面的MIT PDF再次手动运行网络,并且值匹配,因此代码应该是正确的,除非我误解了这些方程式。
我的部分源代码位于http://hpaste.org/42453/neural_network__not_working ;我正在努力清理我的代码并将其放在Github(而不是私人Bitbucket)存储库中。
所有相关的源代码现在都在https://github.com/l33tnerd/hsann。
答案 0 :(得分:23)
我有类似的问题,但能够通过改变这些来解决:
希望这可以帮助那些在Google上找到这个帖子的人!
答案 1 :(得分:0)
在没有看到代码示例的情况下很难分辨,但偏差错误会产生这种影响(例如忘记向输入添加偏差),所以我会仔细研究代码的那一部分。
答案 2 :(得分:0)
在没有看到代码示例的情况下很难分辨但是它可能会出现因为隐藏的神经元的数量而隐藏神经元的数量和隐藏层的数量,因此不可能用小的一组训练网络训练数据。直到有可能制作一个较小的层和神经网络使用更大的网络是不对的。因此也许你的问题解决了这个问题。
答案 3 :(得分:0)
根据您的意见,我同意@finnw您有偏见问题。您应该将偏差视为常量“1”(或者如果您愿意,则为-1)输入到每个神经元。每个神经元对于偏差也有自己的权重,因此神经元的输出应该是加权输入的总和加上通过激活函数的偏差乘以其权重。偏差权重在训练期间更新,就像其他权重一样。
Fausett的“神经网络基础”(p.300)有一个XOR示例,它使用二进制输入和一个带有2个输入的网络,1个隐藏的4个神经元层和一个输出神经元。权重在+0.5和-0.5之间随机初始化。学习率为0.02时,示例网络在大约3000个时期之后收敛。如果您遇到偏见问题(以及任何其他错误),您应该能够在同一个球场获得结果。
另请注意,如果网络中没有隐藏图层,则无法解决XOR问题。
答案 4 :(得分:0)
我没有在问题中使用XOR问题对其进行测试,但对于我基于Tic-Tac-Toe的原始数据集,我相信我已经有了一些网络进行训练(我只运行了1000个时代,这不是足够了:快速传播网络可以赢得/超过一半的游戏;反向传播可以获得约41%。问题归结为实现错误(小错误)而不理解错误导数(每个重量)与每个神经元的错误之间的差异,我在我的研究中没有接受。虽然我没有实施,但是@ darkcanuck关于训练偏差的答案可能会有所帮助。我还用Python重写了我的代码,以便我可以更轻松地破解它。因此,虽然我还没有让网络与minimax算法的效率相匹配,但我相信我已经设法解决了这个问题。
答案 5 :(得分:0)
当我的数据没有正确归一化时,我遇到了类似的问题。一旦我对数据进行了标准化,一切就可以正常运行。
最近,我再次遇到此问题,在调试后,我发现神经网络提供相同输出可能还有另一个原因。如果您的神经网络具有权重衰减项,例如 RSNNS 包中的衰减项,请确保您的衰减项不会太大,以至于所有权重基本上都为0。
我在R中使用插入符包。最初,我使用的是衰减超参数= 0.01。当我查看诊断信息时,我看到正在为每次折叠(交叉验证)计算RMSE,但Rsquared始终为NA。在这种情况下,所有预测都得出相同的值。
一旦我将衰减降低到一个非常低的值(1E-5和更低),我就得到了预期的结果。
我希望这会有所帮助。
答案 6 :(得分:0)
所以我意识到这对于原始帖子来说已经太晚了,但是我遇到了这个问题,因为我遇到了类似的问题,而且这里发布的原因都没有涵盖我的情况是什么。
我正在研究一个简单的回归问题,但是每次我训练网络时,都会收敛到为每个输入提供相同输出(有时是几个不同输出)的地步。我玩了学习率,隐藏层/节点数,优化算法等,但这没什么区别。即使当我看一个荒谬的简单示例时,也要尝试预测两个不同输入(1d)的输出(1d):
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
class net(nn.Module):
def __init__(self, obs_size, hidden_size):
super(net, self).__init__()
self.fc = nn.Linear(obs_size, hidden_size)
self.out = nn.Linear(hidden_size, 1)
def forward(self, obs):
h = F.relu(self.fc(obs))
return self.out(h)
inputs = np.array([[0.5],[0.9]])
targets = torch.tensor([3.0, 2.0], dtype=torch.float32)
network = net(1,5)
optimizer = torch.optim.Adam(network.parameters(), lr=0.001)
for i in range(10000):
out = network(torch.tensor(inputs, dtype=torch.float32))
loss = F.mse_loss(out, targets)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print("Loss: %f outputs: %f, %f"%(loss.data.numpy(), out.data.numpy()[0], out.data.numpy()[1]))
但仍然始终输出两个输入的输出平均值。事实证明,原因是我的输出和目标的尺寸不同:目标是Size [2],输出是Size [2,1],由于某种原因,PyTorch将输出广播为Size MSE损失中的[2,2],这完全把一切搞砸了。一旦更改:
targets = torch.tensor([3.0, 2.0], dtype=torch.float32)
到
targets = torch.tensor([[3.0], [2.0]], dtype=torch.float32)
它可以正常工作。显然,这是通过PyTorch完成的,但我怀疑其他库也可能以相同的方式广播变量。
答案 7 :(得分:0)
当层数很大时,我的模型也遇到了同样的问题。我使用的学习率为0.0001。当我将学习率降低到0.0000001时,问题似乎已解决。我认为当学习率太低时,算法会停留在局部最小值上
答案 8 :(得分:0)
发生的情况与您的情况完全相同,无论训练和层数等如何,神经网络的输出始终相同。
结果证明我的反向传播算法有问题。在一个地方,我乘以不需要的-1。
可能存在另一个类似的问题。问题是如何调试它?
调试步骤:
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
听起来很多工作,但是恕我直言,效果很好。
答案 9 :(得分:0)
我知道,对于原始帖子来说,这还为时已晚,但也许我可以帮助某人,因为我遇到了同样的问题。
对我来说,问题是我的输入数据的重要列中缺少值,而培训/测试数据却不丢失。我用零值替换了这些值,然后结果似乎是合理的。所以也许检查您的数据,也许它被误传了
答案 10 :(得分:-1)
我遇到了与机器学习算法类似的问题,当我查看代码时,我发现了随机生成器并不是随机的。如果您不使用新的随机种子(例如,这样的Unix时间,请参阅http://en.wikipedia.org/wiki/Unix_time),那么可以一遍又一遍地获得完全相同的结果。