隐藏层数,隐藏层中的单位和历元直到神经网络开始在训练数据上表现为可接受的行为

时间:2012-10-08 05:41:18

标签: machine-learning artificial-intelligence neural-network data-mining pybrain

我正在尝试使用神经网络解决此问题Kaggle Problem。我正在使用Pybrain Python Library。

这是一个经典的监督学习问题。在下面的代码中:'data'变量是numpy数组(892 * 8)。 7个字段是我的功能,1个字段是我的输出值,可以是“0”或“1”。

from pybrain.datasets import ClassificationDataSet
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.tools.shortcuts import buildNetwork

dataset = ClassificationDataSet(7,1)
for i in data:
    dataset.appendLinked(i[1:],i[0])
net = buildNetwork(7,9,7,1, bias = True,hiddenclass = SigmoidLayer, outclass = TanhLayer)
trainer = BackpropTrainer(net, learningrate = 0.04, momentum = 0.96, weightdecay = 0.02, verbose = True)
trainer.trainOnDataset(dataset, 8000)
trainer.testOnData(verbose = True)

训练我的神经网络后,当我在训练数据上进行测试时,它总是为所有输入提供单一输出。像:

Testing on data:
out:     [  0.075]
correct: [  1.000]
error:  0.42767858
out:     [  0.075]
correct: [  0.000]
error:  0.00283875
out:     [  0.075]
correct: [  1.000]
error:  0.42744569
out:     [  0.077]
correct: [  1.000]
error:  0.42616996
out:     [  0.076]
correct: [  0.000]
error:  0.00291185
out:     [  0.076]
correct: [  1.000]
error:  0.42664586
out:     [  0.075]
correct: [  1.000]
error:  0.42800026
out:     [  0.076]
correct: [  1.000]
error:  0.42719380
out:     [  0.076]
correct: [  0.000]
error:  0.00286796
out:     [  0.076]
correct: [  0.000]
error:  0.00286642
out:     [  0.076]
correct: [  1.000]
error:  0.42696969
out:     [  0.076]
correct: [  0.000]
error:  0.00292401
out:     [  0.074]
correct: [  0.000]
error:  0.00274975
out:     [  0.076]
correct: [  0.000]
error:  0.00286129

我尝试改变learningRate,weightDecay,动量,隐藏单位数,隐藏层数,隐藏层类,输出层类以便解决它,但在每种情况下,如果输入,它会为每个输入提供相同的输出来自培训数据。

我认为我应该运行8000次以上,因为当我为'XOR'构建神经网络时,它在开始给出纳米级错误之前至少需要700次迭代。 'XOR'上的训练数据大小仅为4,而在这种情况下,它是892.所以我在10%的原始数据上运行了8000次迭代(现在训练数据的大小是89),即使这样,它也为每个输入提供相同的输出在培训数据。由于我想将输入分类为'0'或'1',如果我使用输出层类为Softmax,那么它总是给'1'作为输出。

无论是哪种配置(隐藏单元的数量,输出层的类别,学习率,隐藏层的类别,动量),我在'XOR'中使用,它或多或少开始在每种情况下收敛。

有可能有一些配置最终会产生较低的错误率。至少进行一些配置,以便它不会为训练数据中的所有输入提供相同的输出。

我运行了80,000次迭代(训练数据大小为89)。输出样本:

Testing on data:
out:     [  0.340]
correct: [  0.000]
error:  0.05772102
out:     [  0.399]
correct: [  0.000]
error:  0.07954010
out:     [  0.478]
correct: [  1.000]
error:  0.13600274
out:     [  0.347]
correct: [  0.000]
error:  0.06013008
out:     [  0.500]
correct: [  0.000]
error:  0.12497886
out:     [  0.468]
correct: [  1.000]
error:  0.14177601
out:     [  0.377]
correct: [  0.000]
error:  0.07112816
out:     [  0.349]
correct: [  0.000]
error:  0.06100758
out:     [  0.380]
correct: [  1.000]
error:  0.19237095
out:     [  0.362]
correct: [  0.000]
error:  0.06557341
out:     [  0.335]
correct: [  0.000]
error:  0.05607577
out:     [  0.381]
correct: [  0.000]
error:  0.07247926
out:     [  0.355]
correct: [  1.000]
error:  0.20832669
out:     [  0.382]
correct: [  1.000]
error:  0.19116165
out:     [  0.440]
correct: [  0.000]
error:  0.09663233
out:     [  0.336]
correct: [  0.000]
error:  0.05632861

平均错误:0.112558819082

('Max error:',0.21803000849096299,'平均值误差:',0.096632332865968451)

它提供范围内的所有输出(0.33,0.5)。

1 个答案:

答案 0 :(得分:6)

还有另一个神经网络指标,你没有提到 - 适应性权重的数量。我从这开始得到答案,因为它与隐藏层和单元中的数量有关。

为了获得良好的推广,权重数量必须小于Np / Ny,其中Np是模式的数量,Ny是净输出的数量。什么是“多”确切是可讨论的,我建议几次差异,比如10.对于你的任务大约1000个模式和1个输出,这将意味着100个权重。

使用2个隐藏层是没有意义的。对于涉及非线性的大多数任务来说,1就足够了。在您的情况下,额外的隐藏层仅通过影响整体性能来产生差异。因此,如果使用1个隐藏层,其中的神经元数量可以近似为权重数除以输入数,即100/7 = 14.

我建议在所有神经元中使用相同的激活功能,无论是Hypertanh还是Sigmoid。您的输出值实际上已经针对Sigmoid进行了标准化。无论如何,您可以通过输入数据规范化来提高NN性能,以适应所有维度中的[0,1]。当然,要自己标准化每个功能。

如果你可以使用Pybrain lib,开始以更高的学习速度学习,然后按照当前步骤(LR * (N - i)/N)平滑地减少它,其中i是当前步骤,N - 是限制,LR - 初始学习率

正如@Junuxx建议的那样,每M步输出当前错误(如果可能的话)只是为了确保您的程序按预期工作。如果连续步骤中的错误差异小于阈值,则停止学习。只需开始和粗略估计适当的NN参数,选择将阈值设置为0.1-0.01(“纳米级”不需要)。

在80000步骤中运行89个模式的网络并获得结果的事实很奇怪。请仔细检查您是否将正确的数据传递给NN,并请检查您提供的错误值是什么意思。可能显示的错误或输出是从错误的地方获取的。我认为10000个步骤必须足够远,以便为89个模式获得可接受的结果。

至于具体任务,我认为SOM网可能是另一种选择(可能比BP更适合)。

作为旁注,我不熟悉Pybrain,但是用C ++和其他语言编写了一些NN,所以你的时间看起来非常大。