【问题标题】:Neural network accuracy optimization神经网络精度优化
【发布时间】:2017-01-24 07:42:14
【问题描述】:

我在 keras 中构建了一个人工神经网络,它有 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 个 epoch 之后我得到:loss: 0.6932 - acc: 0.5000 - val_loss: 0.6970 - val_acc: 0.1429

我的问题是:我怎样才能修改我的神经网络以达到更高的准确性?

【问题讨论】:

    标签: python neural-network theano keras


    【解决方案1】:

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

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

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

    3. 对于您的简单数据,我会避免使用 relu 激活。您可能听说过它们在某种程度上是“最好的”,但与大多数 NN 选项一样,它们有一些问题类型可以很好地工作,而其他一些问题则不是最佳选择。我认为您最好在隐藏层中使用 tanh 或 sigmoid 激活来解决您的问题。为非常深的网络和/或图像/音频上的卷积问题保存 relu。

    4. 使用更多的训练数据。不清楚你喂了多少,但神经网络最适合处理大量训练数据。

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

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

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

    【讨论】:

    • 我试图增加训练数据,但我注意到当我增加它时,准确性下降了。为什么会发生这种情况?
    • @Adriano10:如果不深入参与这个问题,真的很难说。但是,它可能是随机波动(准确度
    • 谢谢一百万!这个答案太棒了!如果你不介意,我有一个相关的问题。不过,我相信这是另一个问题的原因。关于第二个选项,您能否澄清一下我们如何看到网络收敛或仍在学习?
    • @MustafaMuratARAT:绘制(或观察其值)损失函数或您想要优化的任何指标。如果网络在学习,价值就会提高。如果它收敛并且稳定,则学习将逐渐减慢(这对于随机学习方法来说可能是嘈杂的)。如果您正在寻找一个泛化的网络,使用交叉验证集(这是一种常见场景),那么也有可能过度拟合并使交叉验证损失值变得更糟,您需要寻找它。从技术上讲,在最后一种情况下,您将在收敛之前停止学习。 . .
    【解决方案2】:

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

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

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

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

    【讨论】:

    • @Adriano10:答案缺少n,试试from sklearn.preprocessing import StandardScaler
    • 只有一句话:这通常称为standardization(减去均值并除以标准差,以得到均值为零和标准差为 1)。 Normalization 的定义要宽松得多,可以有多种含义(例如转换为 [0,1] 范围左右)。
    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    相关资源
    最近更新 更多