不同模型的训练精度不同,但测试精度相同

时间:2020-02-07 06:04:56

标签: python tensorflow machine-learning keras deep-learning

我正在开发一个深度学习分类器-2个班级。我正在使用的数据集不平衡。我做了下采样以解决同样的问题。然后,我创建两个类的数据的一个小样本,并创建一个深度学习模型,如下所示:

dl_model = Sequential()

n_cols = X_train.shape[1]

dl_model.add(Dense(1024, activation='relu', input_shape=(n_cols,)))
dl_model.add(Dense(512, activation='relu'))
dl_model.add(Dense(256, activation='relu'))
dl_model.add(Dense(256, activation='relu'))
dl_model.add(Dense(128, activation='relu'))
dl_model.add(Dense(64, activation='relu'))
dl_model.add(Dense(2, activation='softmax'))

adam= optimizers.Adam(lr=0.001)

dl_model.compile(optimizer=adam, loss='sparse_categorical_crossentropy', metrics=['accuracy'])

early_stopping_monitor = EarlyStopping(patience=3)

dl_model.fit(X_train, y_train, epochs=10, validation_split=0.2, batch_size=1000,callbacks=[early_stopping_monitor], shuffle=True)

model_json = dl_model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)

dl_model.save_weights("model.h5")

对于不同的超参数调整,我得到如下结果:

模型1-train_loss: 7.7971 - train_acc: 0.5160 - val_loss: 9.6992 - val_acc: 0.3982

模型2-train_loss: 2.8257 - train_acc: 0.8201 - val_loss: 2.9312 - val_acc: 0.8160

模型3-train_loss: 3.1887 - train_acc: 0.8002 - val_loss: 3.5195 - val_acc: 0.7808

我保存了每个模型,然后将其加载到另一个文件中,在其中将模型应用于整个数据集并按以下方式计算指标:

sc = MinMaxScaler()
X = sc.fit_transform(X)

json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
loaded_model.load_weights("model.h5")

loaded_model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
score = loaded_model.evaluate(X, y, verbose=0)
print("Deep learning accuracy %s: %.2f%%" % (loaded_model.metrics_names[1], score[1]*100))

以上3个模型均提供相同的精度。甚至是相同的混乱矩阵。可能是什么原因?三种模型的训练准确性/指标不同,难道不应该给出不同的结果吗?

更新:

加载任何模型时,我得到的97.82%和混淆矩阵的准确度与:

[[143369      0]

 [  2958      0]]

1 个答案:

答案 0 :(得分:1)

这里存在的问题是,您训练的所有神经网络都无法正确学习第二类,而第二类的代表性就不太好。

由于模型_1或模型_2或模型_3都无法区分类别1和类别2,因此他们全部都知道可以识别类别1,因此您对测试集的准确性是相同的识别第2类。换句话说,在测试集上进行测试时,无论训练期间看到的差异如何,结果都是相同的。

可以从您在此处显示的混淆矩阵轻松推断出此观察结果。

假设您不知道上述观察。让我们做一些简单的数学运算:

  • 143369 + 2958 = 146327。
  • (143369/146327)* 100 = 97.97%(比您报告的准确性高一点,但在相同的范围内–细微的差异源自evaluate_score中的keras

您还可以由此推断(不仅从视觉上看,您没有针对第2类的TP(真阳性))。

让我们现在着手解决这个问题!

由于我们已经提到了这一观察结果,因此您必须执行以下操作来解决此问题(或将其中一些合并):

首先,从较低的学习率开始(0.0001是更好的开始选择)。

第二,请参考以下过程以获得良好的模型:

  1. 删除EarlyStopping(patience=3)
  2. 根据与准确性不同的指标来保存最佳模型(例如F1-Score)
  3. 减少训练时的学习率(ReduceLROnPlateau)。您可以使用以下回调方法,此回调方法比EarlyStopping更适合您的情况:https://keras.io/callbacks/#reducelronplateau
  4. 使用数据集充实。解决不平衡数据集的最佳方法是使用过采样。您可以通过在少数类中添加更多示例来平衡对类的支持,而不是对代表性良好的类进行欠采样,从而减少数据集的差异。