为什么在训练模型时会有如此不一致的结果?

时间:2018-09-05 11:28:18

标签: python neural-network keras deep-learning

我正在使用Keras训练模型。

我已经初始化了numpytensorflow种子。我进行了50次迭代,在同一训练,验证和测试集上训练和测试我的Keras深度学习架构(始终相同)。我得到了那些结果:

print (np.mean(train_accuracy_vec))
print (np.std(train_accuracy_vec))
print ()
print (np.mean(valid_accuracy_vec))
print (np.std(valid_accuracy_vec))
print ()
print (np.mean(test_accuracy_vec))
print (np.std(test_accuracy_vec))
print ()

我明白了:

enter image description here

有时,它会提供令人无法接受的误报率,而有时,效果很好。我根据EarlyStopping的行为使用了val_acc

那么,什么原因会导致如此大的不稳定呢?

验证分数远低于测试分数也有点奇怪吗?

谢谢

编辑:尽管@Thomas Pinetz给出了类似的答案,但第二次我却没有得到更好的结果:仍然是较高的标准...

更准确地说,这是我的循环制作过程:

# tf, random and numpy seeds...
# lots of data reading, preprocessing,...(including split between train, valid and test sets) 
for k in range (0,50) :
    print (k)
    model = Sequential()
    model.add(Dense(200, activation='elu', input_dim=trainX.shape[1], init=keras.initializers.glorot_uniform(1)))
    model.add(Dropout(0.3))
    # some additional layers...
    model.compile(loss='binary_crossentropy',metrics=['accuracy'], optimizer='adam')
    model.fit(trainX, trainY, validation_data=(validX, validY), epochs=100, verbose=0 , callbacks=callbacks_list)  

    train_score = model.evaluate(trainX, trainY)
    train_accuracy_vec.append (train_score[1])
    print(train_score)
    trainPredict = model.predict(trainX)
    print(confusion_matrix(trainY, trainPredict.round()))

    # and the same for valid and test...

enter image description here

2 个答案:

答案 0 :(得分:2)

导致两次运行之间出现差异的原因是权重的随机初始化。基于梯度下降的方法陷入局部极小值,因此,在每次运行中找到的最佳解决方案取决于初始权重。您对此无能为力。这是神经网络的固有问题。或许可以看看Xavier / He的初始化。

关于为什么您的验证错误比测试错误严重的多,这确实很奇怪。但是,如果您的数据集相对较小,并且您在所有运行中都使用相同的拆分,则可能恰好是测试集具有与训练集相似的模式,而验证却具有不同的模式。您最好在每次运行时进行拆分。

答案 1 :(得分:1)

要在喀拉拉邦获得可再现的结果,请遵循以下说明:https://keras.io/getting-started/faq/#how-can-i-obtain-reproducible-results-using-keras-during-development

可能是多线程导致了问题。

编辑:

每次运行一个返回随机数的方法时,该数字取决于您的初始种子。因此,尽管您的脚本始终返回相同的值,例如训练/验证/测试集评估的均值和标准差相同,因此在for循环的每次迭代中都不会使用相同的随机数。

您可以尝试的是遍历整个脚本,并在for循环的开始处设置随机集。也许那时您将获得相同的结果。

在生成和训练DL模型时存在各种随机性。从权重的初始化到训练集的顺序,默认情况下是随机的。如果不重置随机种子,则此初始化将不同。数据集的顺序相同。在每个时期中,您的训练数据都会被打乱,并且每次for循环运行中的训练数据都会有所不同。还有一些层使用诸如dropout之类的随机元素,它们需要相同的种子来保证相同的性能。