ValueError:分类指标无法处理 CNN 中的多标签指标和多类目标的混合

数据挖掘 美国有线电视新闻网 图像分类 卷积神经网络
2022-02-09 11:05:31

我对 ML 和 CNN 还很陌生,这是我的第一次尝试。我已经设法让我的模型运行,现在我正在尝试生成混淆矩阵和分类报告,但我收到一个错误。我把代码放在下面给你看。我的数据集上的一些上下文是一个包含 9,339 个图像的数据集,并根据它们可能属于的家庭对这些图像进行分类,总共有 25 个家庭/类。该数据集名为 Malimg。

编码:

import numpy as np
import graphviz
import keras
from sklearn.utils import class_weight
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Activation, Conv2D, MaxPooling2D, BatchNormalization
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from keras.preprocessing.image import ImageDataGenerator
from ann_visualizer.visualize import ann_viz
from matplotlib import pyplot as plt 
from sklearn.metrics import multilabel_confusion_matrix, classification_report, confusion_matrix


path_to_data = "malimg_dataset"


train_test_generate_batches = ImageDataGenerator()
batch = train_test_generate_batches.flow_from_directory(directory=path_to_data, target_size=(64,64), batch_size=10000)
imgs, labels = next(batch) #generates batches of data from the path of the directory 
X_train, X_test, y_train, y_test = train_test_split(imgs/255.,labels, train_size=0.7, test_size=0.3) #splits the dataset into training and testing samples with 30% of the overall samples being test data.


num_classes = 25


model = Sequential()


model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(64,64,3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(16, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.25))
model.add(Dropout(0.5))
model.add(Dense(50, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer = 'adam', metrics=['accuracy'])


y_train_new = np.argmax(y_train, axis=1)
class_weights = class_weight.compute_class_weight('balanced', np.unique(y_train_new), y_train_new)


history = model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10,  class_weight=class_weights)
scores = model.evaluate(X_test, y_test)

model.summary()

Y_pred = np.argmax(model.predict(X_test),axis=1)
print('Confusion Matrix')
print(multilabel_confusion_matrix(y_test, Y_pred))
print('Classification Report')

我收到的错误是:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-25-f1724cc7d7f9> in <module>
      1 Y_pred = np.argmax(model.predict(X_test),axis=1)
      2 print('Confusion Matrix')
----> 3 print(multilabel_confusion_matrix(y_test, Y_pred))

~/opt/anaconda3/envs/projectnew/lib/python3.6/site-packages/sklearn/utils/validation.py in inner_f(*args, **kwargs)
     70                           FutureWarning)
     71         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 72         return f(**kwargs)
     73     return inner_f
     74 

~/opt/anaconda3/envs/projectnew/lib/python3.6/site-packages/sklearn/metrics/_classification.py in multilabel_confusion_matrix(y_true, y_pred, sample_weight, labels, samplewise)
    436 
    437     """
--> 438     y_type, y_true, y_pred = _check_targets(y_true, y_pred)
    439     if sample_weight is not None:
    440         sample_weight = column_or_1d(sample_weight)

~/opt/anaconda3/envs/projectnew/lib/python3.6/site-packages/sklearn/metrics/_classification.py in _check_targets(y_true, y_pred)
     89     if len(y_type) > 1:
     90         raise ValueError("Classification metrics can't handle a mix of {0} "
---> 91                          "and {1} targets".format(type_true, type_pred))
     92 
     93     # We can't have more than one value on y_type => The set is no more needed

ValueError: Classification metrics can't handle a mix of multilabel-indicator and multiclass targets

谁能给我任何关于正在发生的事情的背景信息?如果可能的话,也许建议代码应该是什么样子。这是我的第一次尝试,但我确信这与我有 25 个不同的班级这一事实有关,而且我不喜欢我这样做的事实。我最初使用的是confusion_matrix,但后来尝试了multilabel_confusion_matrix,因为我认为这可以解决我的问题,但它没有。

1个回答

我想到了。您必须将测试标签转换为个位数,而不是一次性编码。

为了实现这一点,我将混淆矩阵代码从:

Y_pred = np.argmax(model.predict(X_test),axis=1)
print('Confusion Matrix')
print(multilabel_confusion_matrix(y_test, Y_pred))
print('Classification Report')

到:

y_test_arg=np.argmax(y_test,axis=1)
Y_pred = np.argmax(model.predict(X_test),axis=1)
print('Confusion Matrix')
print(confusion_matrix(y_test_arg, Y_pred))