神经网络精度优化

Neural network accuracy optimization

我在 keras 中构建了一个 ANN,它有 1 个输入层(3 个输入)、一个输出层(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 个时期后我得到:loss: 0.6932 - acc: 0.5000 - val_loss: 0.6970 - val_acc: 0.1429

我的问题是:如何修改我的神经网络以获得更高的准确度?

您可以尝试以下操作。我大致按照重要性的顺序写了这篇文章 - 即我会尝试解决您看到的准确性问题的顺序:

  1. 标准化您的输入数据。通常你会采用训练数据的均值和标准差,并使用它们来抵消+缩放所有进一步的输入。为此有一个standard normalising function in sklearn。请记住以相同的方式处理您的测试数据(使用训练数据中的均值和标准差,而不是重新计算)

  2. 训练更多时期。对于特征数量少且训练集大小有限的问题,在网络收敛之前,您通常必须 运行 数以千计的 epoch。您应该绘制训练和验证损失值,以查看网络是否仍在学习,或者已经尽可能收敛。

  3. 对于你的简单数据,我会避免 relu 激活。您可能听说过它们以某种方式 "best",但与大多数 NN 选项一样,它们在某些类型的问题上表现良好,而在其他情况下则不是最佳选择。我认为您最好在隐藏层中使用 tanh 或 sigmoid 激活来解决您的问题。为 images/audio.

  4. 上的非常深的网络 and/or 卷积问题保存 relu
  5. 使用更多训练数据。不清楚你给它喂了多少,但神经网络在处理大量训练数据时效果最好。

  6. 如果您已经有大量训练数据 - 增加隐藏层的大小。更复杂的关系需要更多的隐藏神经元(有时需要更多层),NN 才能表达决策面的 "shape"。 Here is a handy browser-based network allowing you to play with that idea and get a feel for it

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

最后,您想要找到的可以让您根据 X 预测 Y 的关系总是有可能并不存在。在这种情况下,NN 的正确结果并不比猜测 Y 好多少。

Neil Slater 已经提供了一长串有用的一般性建议。

在您的具体示例中,规范化是重要的事情。如果您将以下行添加到代码中

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

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