如何从Tensorflow预取数据集中提取类别以生成混淆矩阵

我试图使用以下代码为我的图像分类器绘制混淆矩阵,但收到错误消息:’PrefetchDataset’对象没有属性’classes’

Y_pred = model.predict(validation_dataset)y_pred = np.argmax(Y_pred, axis=1)print('Confusion Matrix')print(confusion_matrix(validation_dataset.classes, y_pred)) # 生成错误消息

‘PrefetchDataset’对象没有属性’classes’


回答:

免责声明: 这对已打乱的数据集不起作用。

你可以使用tf.stack来拼接所有数据集的值。像这样:

true_categories = tf.concat([y for x, y in test_dataset], axis=0)

为了可重复性,假设你有一个数据集,一个神经网络和一个训练循环:

import tensorflow_datasets as tfdsimport tensorflow as tffrom sklearn.metrics import confusion_matrixdata, info = tfds.load('iris', split='train',                       as_supervised=True,                       shuffle_files=True,                       with_info=True)AUTOTUNE = tf.data.experimental.AUTOTUNEtrain_dataset = data.take(120).batch(4).prefetch(buffer_size=AUTOTUNE)test_dataset = data.skip(120).take(30).batch(4).prefetch(buffer_size=AUTOTUNE)model = tf.keras.Sequential([    tf.keras.layers.Dense(8, activation='relu'),    tf.keras.layers.Dense(16, activation='relu'),    tf.keras.layers.Dense(info.features['label'].num_classes, activation='softmax')    ])model.compile(loss='sparse_categorical_crossentropy', optimizer='adam',               metrics='accuracy')history = model.fit(train_dataset, validation_data=test_dataset, epochs=50, verbose=0)

现在你的模型已经拟合完毕,你可以预测测试集:

y_pred = model.predict(test_dataset)
array([[2.2177568e-05, 3.0841196e-01, 6.9156587e-01],       [4.3539176e-06, 1.2779665e-01, 8.7219906e-01],       [1.0816366e-03, 9.2667454e-01, 7.2243840e-02],       [9.9921310e-01, 7.8686583e-04, 9.8775059e-09]], dtype=float32)

这将是一个(n_samples, 3)的数组,因为我们处理的是三个类别。我们需要一个(n_samples, 1)的数组以供sklearn.metrics.confusion_matrix使用,因此取argmax:

predicted_categories = tf.argmax(y_pred, axis=1)
<tf.Tensor: shape=(30,), dtype=int64, numpy=array([2, 2, 2, 0, 2, 2, 2, 2, 1, 1, 2, 0, 0, 2, 1, 1, 1, 2, 0, 2, 1, 2,       1, 0, 2, 0, 1, 2, 1, 0], dtype=int64)>

然后,我们可以从预取数据集中提取所有y值:

true_categories = tf.concat([y for x, y in test_dataset], axis=0)
[<tf.Tensor: shape=(4,), dtype=int64, numpy=array([1, 1, 1, 0], dtype=int64)>, <tf.Tensor: shape=(4,), dtype=int64, numpy=array([2, 2, 2, 2], dtype=int64)>, <tf.Tensor: shape=(4,), dtype=int64, numpy=array([1, 1, 1, 0], dtype=int64)>, <tf.Tensor: shape=(4,), dtype=int64, numpy=array([0, 2, 1, 1], dtype=int64)>, <tf.Tensor: shape=(4,), dtype=int64, numpy=array([1, 2, 0, 2], dtype=int64)>, <tf.Tensor: shape=(4,), dtype=int64, numpy=array([1, 2, 1, 0], dtype=int64)>, <tf.Tensor: shape=(4,), dtype=int64, numpy=array([2, 0, 1, 2], dtype=int64)>, <tf.Tensor: shape=(2,), dtype=int64, numpy=array([1, 0], dtype=int64)>]

然后,你就可以准备好获取混淆矩阵了:

confusion_matrix(predicted_categories, true_categories)
array([[ 9,  0,  0],       [ 0,  9,  0],       [ 0,  2, 10]], dtype=int64)

(9 + 9 + 10) / 30 = 0.933是准确率得分。它对应于model.evaluate(test_dataset):

8/8 [==============================] - 0s 785us/step - loss: 0.1907 - accuracy: 0.9333

结果也与sklearn.metrics.classification_report一致:

              precision    recall  f1-score   support           0       1.00      1.00      1.00         8           1       0.82      1.00      0.90         9           2       1.00      0.85      0.92        13    accuracy                           0.93        30   macro avg       0.94      0.95      0.94        30weighted avg       0.95      0.93      0.93        30

这是完整的代码:

import tensorflow_datasets as tfdsimport tensorflow as tffrom sklearn.metrics import confusion_matrixdata, info = tfds.load('iris', split='train',                       as_supervised=True,                       shuffle_files=True,                       with_info=True)AUTOTUNE = tf.data.experimental.AUTOTUNEtrain_dataset = data.take(120).batch(4).prefetch(buffer_size=AUTOTUNE)test_dataset = data.skip(120).take(30).batch(4).prefetch(buffer_size=AUTOTUNE)model = tf.keras.Sequential([    tf.keras.layers.Dense(8, activation='relu'),    tf.keras.layers.Dense(16, activation='relu'),    tf.keras.layers.Dense(info.features['label'].num_classes, activation='softmax')    ])model.compile(loss='sparse_categorical_crossentropy', optimizer='adam',               metrics='accuracy')history = model.fit(train_dataset, validation_data=test_dataset, epochs=50, verbose=0)y_pred = model.predict(test_dataset)predicted_categories = tf.argmax(y_pred, axis=1)true_categories = tf.concat([y for x, y in test_dataset], axis=0)confusion_matrix(predicted_categories, true_categories)

更一般地说,你可以使用sklearn.metrics.ConfusionMatrixDisplay.from_predictions来绘制混淆矩阵。

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中创建了一个多类分类项目。该项目可以对…

发表回复

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