获取keras模型中3个类的混淆矩阵
Posted
技术标签:
【中文标题】获取keras模型中3个类的混淆矩阵【英文标题】:Get confusion matrix for 3 classes in keras model 【发布时间】:2021-07-28 07:20:10 【问题描述】:所以我有类似 (10000, 178, 178, 3) 形状的数据,其中我有 10000 个样本,每个样本都有 3 个不同的颜色通道(不是 RGB 通道),我将它们分为 3 个这样的类,所以我有 3 个标签 0, 1 & 2
:
导入库:
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.models import Sequential
from keras import regularizers
from keras.layers import Dense, Activation, Flatten, Dropout, BatchNormalization
from keras import optimizers
import keras
from keras.callbacks import LearningRateScheduler
from tensorflow.keras import optimizers
import tensorflow as tf
from keras.layers import LeakyReLU
from sklearn.metrics import classification_report, confusion_matrix
label = np.where((np.array(val) < 0.1), 0, np.where((np.array(val) < 0.2) ,1, 2))
一个热编码:
def to_one_hot(y, num_class=3):
results = numpy.zeros((len(y), num_class))
for i, label in enumerate(y):
results[i, label] = 1
return results
y_train_vec = to_one_hot(label)
为训练和测试拆分:
rand_indices = np.random.permutation(len(data))
train_indices = rand_indices[0:7460]
valid_indices = rand_indices[7460:len(data)]
x_test = data_array[valid_indices, :]
y_test = y_train_vec[valid_indices, :].astype('float')
x_train = data_array[train_indices, :]
y_train = y_train_vec[train_indices, :].astype('float')
然后我使用这个神经网络来训练这个数据集:
weight_decay = 1e-4
model = Sequential()
model.add(Conv2D(32, (20,20), padding='same', kernel_regularizer=regularizers.l2(weight_decay), input_shape=x_tr.shape[1:]))
model.add(LeakyReLU(alpha=0.01))
model.add(BatchNormalization())
model.add(Conv2D(32, (30,30), padding='same', kernel_regularizer=regularizers.l2(weight_decay)))
model.add(LeakyReLU(alpha=0.01))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.summary()
那我在这里训练它:
def lr_schedule(epoch):
lrate = 0.001
if epoch > 30:
lrate = 0.0005
elif epoch > 60:
lrate = 0.0003
return lrate
batch_size = 128
opt_rms = tf.keras.optimizers.Adam()
model.compile(loss= 'categorical_crossentropy', optimizer = opt_rms, metrics=['accuracy'])
history = model.fit(x_train, y_train, batch_size, epochs=100, verbose=1,
callbacks=[LearningRateScheduler(lr_schedule)])
现在我想要 3 个类的混淆矩阵,我知道如何为 2 个这样的类执行此操作,但有人可以告诉我如何为 3 个类做同样的事情:
T=0.5
y_pred = model.predict(x_val)
y_pred_bool = y_pred>=T
confusion_matrix(y_val, y_pred_bool)
【问题讨论】:
请提供必要的导入,以便清楚您在代码中使用的方法来自何处。谢谢! @AkshaySehgal 请检查更新的代码。谢谢! 【参考方案1】:你能得到y_pred_bool
的形状,或者发布几行看看它是什么样子的吗?
一般来说,如果您的目标存储在单个列中(形状 (N,)
):
# Libraries
import numpy as np
from sklearn.metrics import confusion_matrix
from sklearn.metrics import multilabel_confusion_matrix
# Target and predictions in (N,) shape
y_true = np.array([0, 1, 2])
y_pred = np.array([0, 1, 1])
# Get confusion matrix
confusion_matrix(y_true=y_true, y_pred=y_pred)
> array([[1, 0, 0],
[0, 1, 0],
[0, 1, 0]])
如果您的目标和预测标签被编码为指示符列,您可以使用sklearn.metrics.multilabel_confusion_matrix
。这将以一对一的方式为每个类生成一个混淆矩阵。例如:
# Libraries
import numpy as np
from sklearn.metrics import confusion_matrix
from sklearn.metrics import multilabel_confusion_matrix
# Target and predictions in (N, 3) shape
y_true = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
y_pred = np.array([[1, 0, 0], [0, 1, 0], [0, 1, 0]])
# Get confusion matrix for each class
multilabel_confusion_matrix(y_true=y_true, y_pred=y_pred)
> array([[[2, 0],
[0, 1]],
[[1, 1],
[0, 1]],
[[2, 0],
[1, 0]]])
【讨论】:
嘿抱歉回复晚了,我病了。这是我的 y_pred 的输出:array([[7.3365694e-01, 2.3474902e-01, 3.1593997e-02], [3.1977770e-01, 6.1781120e-01, 6.2411133e-02], [6.8967247e-01, 1.8431199e-01, 1.2601557e-01], ..., [2.8589216e-01, 7.0550179e-01, 8.6060567e-03], [9.8009664e-01, 1.9454861e-02, 4.4847900e-04], [5.3596318e-01, 4.6394366e-01, 9.3131493e-05]], dtype=float32)
这是我的 y_pred_bool 的形状:(2487, 3)
其中 2487 没有测试记录以上是关于获取keras模型中3个类的混淆矩阵的主要内容,如果未能解决你的问题,请参考以下文章
使用 sklearn 使用 Keras 数据生成器绘制混淆矩阵