神经网络始终为任何输入生成相同/相似的输出

li.*_*idm 30 haskell neural-network

我有一个问题,我正在尝试为Tic-Tac-Toe创建一个神经网络.但是,出于某种原因,训练神经网络会导致它为任何给定的输入产生几乎相同的输出.

我确实看过人工神经网络基准测试,但我的网络实现是针对每个神经元具有相同激活功能的神经元构建的,即没有恒定的神经元.

为了确保问题不仅仅是由于我选择的训练集(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手动计算错误,网络输出,偏差更新和重量更新,以确保没有错误代码的那些部分(没有,但我可能会再做一次以确保).因为我正在使用批量训练,所以我没有乘以x等式(4).我正在添加重量变化,但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]
Run Code Online (Sandbox Code Playgroud)

减去而不是添加产生相同的问题,除了一切都是0.99而不是0.50的东西.5000个时期产生相同的结果,除了批量训练的网络每个案例返回0.5.(哎呀,即使是10000个时代也没有用于批量训练.)

有什么一般可以产生这种行为?

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

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

编辑:两层,一个输入层,两个输入到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.

Jus*_*tas 26

我有类似的问题,但能够通过改变这些来解决:

  • 将问题缩小到可管理的大小.我首先尝试了太多的输入,隐藏的图层单元太多了.一旦我缩小了问题,我就能看出解决这个小问题的方法是否有效.这也有效,因为当它缩小时,计算权重的时间显着下降,所以我可以尝试许多不同的东西而无需等待.
  • 确保你有足够的隐藏单位.这对我来说是个主要问题.我有大约900个输入连接到隐藏层中的~10个单位.这太小而不能快速收敛.但如果我添加额外的单位,也变得非常慢.缩小输入数量有很大帮助.
  • 更改激活功能及其参数.我起初正在使用tanh.我尝试了其他函数:sigmoid,规范化sigmoid,Gaussian等.我还发现,更改函数参数以使函数更陡或更浅会影响网络收敛的速度.
  • 更改学习算法参数.尝试不同的学习率(0.01到0.9).如果您的算法支持它(0.1到0.9),也可以尝试不同的动量参数.

希望这有助于那些在Google上找到这个主题的人!


小智 13

所以我意识到这对于原始帖子来说太晚了,但是我遇到了这个问题,因为我遇到了类似的问题,而且这里发布的原因都没有涵盖我的情况。

我正在研究一个简单的回归问题,但每次我训练网络时,它都会收敛到一个点,它为每个输入提供相同的输出(或有时是几个不同的输出)。我玩了学习率、隐藏层/节点的数量、优化算法等,但没有任何区别。即使我看着一个简单得可笑的例子,试图预测两个不同输入 (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]))
Run Code Online (Sandbox Code Playgroud)

但它仍然总是输出两个输入的输出平均值。事实证明,原因是我的输出和目标的维度不一样:目标是 Size[2],输出是 Size[2,1],出于某种原因,PyTorch 将输出广播为 Size [2,2] 在 MSE 损失中,这完全搞砸了一切。一旦我改变:

targets = torch.tensor([3.0, 2.0], dtype=torch.float32)
Run Code Online (Sandbox Code Playgroud)

targets = torch.tensor([[3.0], [2.0]], dtype=torch.float32)
Run Code Online (Sandbox Code Playgroud)

它正常工作。这显然是用 PyTorch 完成的,但我怀疑其他库可能以相同的方式广播变量。


use*_*853 7

对我来说,它的发生与您的情况完全相同,无论训练和层数等如何,神经网络的输出始终相同。

事实证明我的反向传播算法有问题。在一处不需要的地方我乘以-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
Run Code Online (Sandbox Code Playgroud)

听起来工作量很大,但恕我直言,效果很好。


li.*_*idm 1

我还没有用问题中的 XOR 问题对其进行测试,但是对于我基于 Tic-Tac-Toe 的原始数据集,我相信我已经让网络进行了一些训练(我只运行了 1000 epoch,这还不够) ):快速传播网络可以赢得/打平超过一半的比赛;反向传播可以得到41%左右。问题归结于实现错误(小错误)以及不理解误差导数(每个权重)和每个神经元的误差之间的差异,这是我在研究中没有发现的。@darkcanuck 关于训练偏差类似于权重的答案可能会有所帮助,尽管我没有实现它。我还用 Python 重写了我的代码,以便我可以更轻松地使用它。因此,虽然我还没有让网络达到极小极大算法的效率,但我相信我已经成功解决了问题。