NumpyArrayIterator无classes属性报错,无法生成神经网络混淆矩阵求助
解决AttributeError: 'NumpyArrayIterator' object has no attribute 'classes'的问题
这个报错的根源很明确:你用datagen.flow()生成的test_generator是NumpyArrayIterator类型,它本身就没有classes属性——只有用flow_from_directory()生成的DirectoryIterator才会自带这个属性(因为它是从文件夹结构自动识别类别信息的)。你之前用样本数据能正常运行,大概率是当时的测试生成器是用flow_from_directory创建的,和现在的情况不一样。
快速修复方案
既然你是用flow()加载的测试集,说明你肯定已经有了测试集的真实标签数据(比如y_test),直接用这个原始标签数组就行,不用从生成器里取:
test_generator.reset() pred = model.predict_generator(test_generator, steps=len(test_generator), verbose=2) from sklearn.metrics import classification_report, confusion_matrix, cohen_kappa_score import pandas as pd import numpy as np y_pred = np.argmax(pred, axis=1) # 关键修改:用原始测试集标签代替test_generator.classes # 如果你的y_test是one-hot编码格式,先转成类别索引 y_true = np.argmax(y_test, axis=1) # 如果y_test本来就是类别索引(比如[0,1,0,2,...]),直接用y_true = y_test print('Confusion Matrix') print(pd.DataFrame(confusion_matrix(y_true, y_pred)))
为什么会这样?
flow_from_directory()会扫描指定文件夹的结构,自动为每个样本分配类别标签,所以生成的迭代器会保存classes、class_indices这些属性;- 而
flow()是基于你已经准备好的numpy数组(x_test和y_test)来生成批量数据,它不需要自己识别类别,所以迭代器里不会存储classes这类属性,真实标签本来就在你手里的y_test里。
额外提示
如果你因为某些原因一定要从生成器中获取真实标签,可以遍历生成器收集所有标签,但这种方法效率不如直接用原始y_test:
# 收集生成器中的所有真实标签 y_true = [] for _, y_batch in test_generator: y_true.extend(np.argmax(y_batch, axis=1)) # 如果是one-hot编码 # 如果y_batch是类别索引,直接y_true.extend(y_batch) # 注意:遍历后要重置生成器,否则后续predict会出问题 test_generator.reset()
内容的提问来源于stack exchange,提问作者Fauz
相关产品推荐
相关产品推荐

