不同模型的训练准确率不同但测试准确率相同

我正在开发一个深度学习分类器,处理两个类别。我使用的数据集是不平衡的。我通过下采样来解决这个问题。然后,我创建了两个类别的小样本数据,并构建了如下深度学习模型:

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))

上述三个模型都给出了相同的准确率。甚至混淆矩阵也相同。原因可能是什么?三个模型的训练准确率/指标不同,不应该给出不同的结果吗?

更新:

加载任何一个模型时,我得到的准确率都是97.82%,混淆矩阵如下:

[[143369      0] [  2958      0]]

回答:

您遇到的问题是所有训练的 neural networks 都无法正确学习到第二个类别,即较少表示的那个类别。

测试集上的准确率相同是因为 model_1、model_2 和 model_3 都无法区分类别1和类别2,因此它们都能识别类别1,但无法识别类别2。换句话说,当您在测试集上进行测试时,结果是相同的,尽管训练过程中看到了差异。

这一观察可以从您展示的混淆矩阵中轻松推断出来。

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

  • 143369 + 2958 = 146327。
  • (143369/146327) * 100 = 97.97%(与您报告的准确率略有不同,但大致相同——小的差异来自于evaluate_scorekeras中的计算)

您也可以从这里推断出(不仅仅是视觉上看到没有类别2的TP(真阳性))您有问题。

现在让我们继续解决这个问题!

既然我们已经提到了这一观察,您需要采取以下措施来解决这个问题(或结合其中的一些措施):

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

其次,参考以下程序以获得一个好的模型:

  1. 移除EarlyStopping(patience=3)
  2. 根据不同于准确率的指标保存最佳模型(例如F1-Score)。
  3. 在训练过程中降低学习率(ReduceLROnPlateau)。您可以使用以下回调,这在您的案例中比EarlyStopping更合适:https://keras.io/callbacks/#reducelronplateau
  4. 使用数据集增强。处理不平衡数据集的最佳方法是使用过采样。与其通过下采样来减少数据集的方差,不如通过添加更多的少数类示例来平衡类别的支持度。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注