Python 神经网络精度优化

Python 神经网络精度优化,python,neural-network,theano,keras,Python,Neural Network,Theano,Keras,我在keras中构建了一个ANN,它有1个输入层(3个输入)、1个输出层(1个输出)和两个隐藏层,分别有12个和3个节点 我构建和培训网络的方式是: from keras.models import Sequential from keras.layers import Dense from sklearn.cross_validation import train_test_split import numpy # fix random seed for reproducibility se

我在keras中构建了一个ANN,它有1个输入层(3个输入)、1个输出层(1个输出)和两个隐藏层,分别有12个和3个节点

我构建和培训网络的方式是:

from keras.models import Sequential
from keras.layers import Dense
from sklearn.cross_validation import train_test_split
import numpy
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

dataset = numpy.loadtxt("sorted output.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:3]
Y = dataset[:,3]
# split into 67% for train and 33% for test
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=seed)
# create model
model = Sequential()
model.add(Dense(12, input_dim=3, init='uniform', activation='relu'))
model.add(Dense(3, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(X_train, y_train, validation_data=(X_test,y_test), nb_epoch=150, batch_size=10)
排序后的输出csv文件如下所示:

所以在150个时代之后,我得到:损失:0.6932-acc:0.5000-val\u损失:0.6970-val\u acc:0.1429


我的问题是:如何修改NN以获得更高的精度?

您可以尝试以下方法。我大致按照重要性的顺序写了这篇文章,也就是说,我将尝试解决您所看到的准确性问题的顺序:

  • 使输入数据正常化。通常,您会获取训练数据的平均值和标准偏差,并使用它们来抵消所有进一步的输入。这是有道理的。记住以同样的方式处理测试数据(使用训练数据的平均值和标准差,而不是重新计算)

  • 为更多的时代而训练。对于功能数量少且训练集大小有限的问题,您通常需要运行数千个历元,然后网络才会收敛。您应该绘制训练和验证损失值,以查看网络是否仍在学习,或者是否已尽可能地融合

  • 对于您的简单数据,我将避免relu激活。你可能听说过它们在某种程度上是“最好的”,但像大多数NN选项一样,它们在工作正常的情况下会遇到一些问题,而在其他情况下,它们不是最佳选择。我认为你最好在隐藏层中激活tanh或sigmoid来解决你的问题。保存relu以解决非常深入的网络和/或图像/音频上的卷积问题

  • 使用更多的培训数据。不清楚你给它喂了多少,但NNs在处理大量训练数据时效果最好

  • 如果你已经有大量的训练数据-增加隐藏层的大小。更复杂的关系需要更多隐藏的神经元(有时需要更多的层),使神经网络能够表达决策面的“形状”

  • 在隐藏层后添加一个或多个,或添加一些其他正则化。网络可能过拟合(尽管训练精度为0.5,我怀疑不是)。与relu不同,使用辍学几乎是解决更棘手的神经网络问题的灵丹妙药——它在许多情况下提高了泛化能力。少量的退出(~0.2)可能有助于解决您的问题,但与大多数超参数一样,您需要搜索最佳值


  • 最后,总是有可能你想要找到的关系,它允许你从X预测Y,但实际上并不存在。在这种情况下,NN的正确结果不比猜测Y好。

    尼尔·斯莱特已经提供了一长串有用的一般建议

    在您的特定示例中,规范化是重要的。如果在代码中添加以下行

    ...
    X = dataset[:,0:3]
    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    X = scaler.fit_transform(X)
    

    即使使用更简单的网络结构,您的玩具数据也将获得100%的准确性。如果没有标准化,优化器将无法工作。

    我试图增加训练数据,但我注意到,当我增加数据时,精确度会下降。为什么会发生这种情况?@Adriano10:如果不积极参与到这个问题中,就很难说了。然而,它可能是随机波动(精度<50%可能首先是其他地方)。我按照尝试的顺序写下了答案。所以,你应该先看看标准化——你输入的那些高正数将阻止任何NN正常工作。万分感谢!这个答案太棒了!如果你不介意的话,我有一个相关的问题。不过,我相信这是另一个问题的原因。关于第二个选项,您能否澄清我们如何看待网络收敛或仍然学习?@MustafaMuratARAT:绘制(或观察)损失函数或任何您想要优化的指标。如果网络在学习,价值就会提高。如果它收敛且稳定,学习将逐渐减慢(对于随机学习方法,这可能是有噪声的)。如果您正在寻找一个通用的网络,使用交叉验证集(这是一个常见的场景),那么它也可能会过度拟合,并且交叉验证损失值会变得更糟,您需要寻找这一点。从技术上讲,在最后一种情况下,您将在收敛之前停止学习@阿德里亚诺10:答案缺少一个
    n
    ,请尝试从sklearn.preprocessing import StandardScaler中选择
    ,只需一句话:这通常被称为(减去平均值,然后除以标准差,以使平均值为零,标准差为1)。定义更为松散,可以有多种含义(例如转换为[0,1]范围左右)。