test_generator = test_datagen.flow_from_directory(
test_dir,
target_size=(150, 150),
batch_size=20,
class_mode='categorical')
test_loss, test_acc = model.evaluate_generator(test_generator, steps=28)
print('test acc:', test_acc)
predict = model.predict_generator(test_generator,steps =28, verbose=0)
print('Prediction: ', predict)
test_imgs, test_labels = next(test_generator)
print(test_labels)
cm =confusion_matrix(test_labels, predict)
我从上面的代码中遇到了2个问题。首先,我得到一个错误,即在我的test_labels和预测之间有不同数量的样本。我的test_labels只存储20个样本(以批量大小写。同时,我从model.predict_generator预测总共有560个图像(20 * 28步)
ValueError: Found input variables with inconsistent numbers of samples: [20, 560]
第二个问题是,如何更改softmax值(从我的4个图像类的浮点数到int的概率)?当我将步骤更改为1(在上述问题中仅测试20个样本而不是总共560个)时出现错误
ValueError: Classification metrics can't handle a mix of multilabel-indicator and continuous-multioutput targets
我认为这是错误,因为当我做出预测时,我会得到一些4-d列表(来自4个类),例如。
Prediction: [[2.9905824e-12 5.5904431e-10 1.8195983e-11 1.0000000e+00]
[2.7073351e-21 1.0000000e+00 8.3221777e-21 4.9091786e-22]
[4.2152173e-05 6.1331893e-04 3.7486094e-05 9.9930704e-01]
无论如何,我可以得到我的模型预测的确切类别(例如我的测试损失和测试准确度)。
或者是否还有其他简单的方法来获取我不知道的Keras中的混淆矩阵? :(
Edit1(从desertnaut获得) 返回的test_labels变量如下所示
array([[0., 0., 0., 1.],
[0., 0., 0., 1.],
[0., 1., 0., 0.],
[0., 1., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 0., 1.],
[1., 0., 0., 0.],
[0., 0., 0., 1.],
[0., 1., 0., 0.],
[0., 0., 0., 1.],
[0., 0., 0., 1.],
[0., 1., 0., 0.],
[0., 0., 0., 1.],
[0., 0., 0., 1.],
[0., 0., 1., 0.],
[0., 1., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 0., 1.],
[0., 0., 0., 1.],
[0., 0., 1., 0.]], dtype=float32), array([[1., 0., 0., 0.],
[0., 0., 0., 1.],
^这只是1个周期(总共28个,另外27个这个列表)。此快照位于输出中间的某处。该列表太长,无法显示最顶级的数组(无法滚动到Spyder的输出框顶部)。我尝试使用argmax作为上面的第二个问题。 e.g。
test_class = np.argmax(test_labels, axis=1)
test_class = test_class.tolist()
print(test_class)
但我没有得到正确答案。我认为因为循环不同。我认为您给出的predict_class的输出是1个列表,其中包含所有560个样本预测。但对于test_label,它算作28个不同的循环。 predict_class的输出是这样的。 e.g。
[3, 1, 1, 2, 0, 0, 3, 1, 2, 0, 0, 1, 2, 2, 1, 3, 2, 2, 0, 2, 0, 3, 0, 1, 3, 3, 1, 2, 0, 1, 1, 0, 2, 1, 0, 2, 1, 3, 1, 0, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 2, 3, 1, 3, 1, 1, 3, 2, 2, 0, 1, 1, 0, 2, 1, 3, 3, 2, 0, 1, 1, 0, 3, 0, 0, 2, 3, 2, 1, 1, 2, 3, 0, 0, 2, 1, 3, 2, 3, 1, 0, 0, 3, 0, 3, 1, 1, 3, 1, 0, 1, 2, 0, 0, 0, 0, 3, 2, 2, 3, 3, 1, 3, 0, 3, 2, 0, 0, 0, 2, 1, 0, 2, 2, 1, 0, 1, 2, 2, 2, 3, 2, 1, 2, 2, 0, 0, 2, 3, 3, 1, 2, 2, 3, 0, 2, 1, 1, 3, 0, 1, 0, 1, 3, 3, 1, 3, 0, 1, 3, 0, 2, 1, 1, 3, 0, 1, 0, 1, 1, 3, 2, 3, 3, 0, 1, 1, 3, 2, 0, 3, 2, 0, 1, 3, 3, 2, 1, 1, 1, 0, 2, 0, 2, 2, 0, 2, 2, 0, 0, 1, 2, 2, 0, 0, 1, 1, 1, 0, 2, 2, 0, 3, 0, 3, 2, 2, 0, 1, 1, 1, 3, 0, 2, 2, 1, 3, 3, 3, 1, 2, 0, 3, 0, 0, 3, 1, 1, 3, 0, 2, 2, 2, 2, 3, 0, 2, 3, 0, 3, 2, 3, 2, 3, 3, 0, 0, 2, 3, 2, 0, 0, 3, 1, 3, 0, 0, 1, 1, 0, 1, 0, 0, 3, 0, 0, 1, 1, 3, 1, 3, 2, 1, 0, 1, 0, 2, 3, 0, 1, 2, 1, 2, 2, 2, 2, 0, 2, 2, 1, 3, 2, 2, 2, 1, 3, 3, 2, 0, 3, 0, 1, 2, 2, 2, 3, 1, 0, 2, 3, 2, 1, 0, 1, 2, 0, 2, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 3, 3, 2, 1, 0, 0, 3, 0, 0, 2, 1, 0, 2, 3, 2, 3, 2, 1, 3, 0, 2, 1, 0, 0, 0, 1, 2, 2, 3, 2, 3, 2, 0, 3, 2, 1, 0, 0, 3, 2, 3, 0, 2, 0, 1, 0, 0, 3, 2, 3, 1, 3, 2, 2, 2, 0, 1, 2, 0, 2, 0, 0, 0, 3, 1, 3, 2, 3, 2, 1, 2, 3, 3, 1, 3, 3, 0, 1, 1, 2, 0, 1, 2, 3, 0, 2, 2, 2, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 0, 1, 3, 0, 2, 3, 1, 0, 2, 3, 2, 3, 1, 1, 2, 1, 2, 3, 0, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 0, 0, 2, 0, 1, 0, 3, 1, 0, 0, 2, 1, 2, 3, 3, 2, 2, 1, 2, 2, 0, 2, 0, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 0, 3, 2, 2, 3, 0, 1, 3, 2, 3, 3, 0, 3, 1, 2, 3, 3, 0, 3, 3, 3, 2, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0, 0, 1, 2, 2, 2, 3, 0, 0, 1, 1, 0, 2, 0, 2, 0, 3, 3, 1, 0, 2, 2, 1, 0, 0, 3, 0, 3, 3, 3]
^ 1个560个样本的列表。
test_class的输出(使用argmax编辑)。 e.g。
[[7, 3, 0, 2], [9, 3, 2, 0], [0, 2, 9, 6], [0, 2, 3, 1], [2, 3, 0, 1], [6, 0, 1, 4], [5, 0, 1, 2], [1, 3, 2, 0], [0, 2, 3, 5], [0, 1, 3, 7], [1, 0, 8, 4], [3, 7, 1, 0], [3, 5, 0, 2], [9, 0, 3, 1], [0, 2, 1, 9], [8, 5, 1, 0], [2, 0, 1, 8], [0, 5, 1, 3], [0, 17, 1, 4], [2, 1, 7, 0], [0, 4, 5, 1], [1, 2, 0, 4], [0, 2, 3, 1], [2, 0, 1, 3], [3, 2, 1, 0], [0, 2, 7, 6], [5, 0, 18, 2], [2, 0, 7, 1]]
是否有numpy或scipy中的函数使其成为560个样本的列表而不是28个列表* 20batches。
EDIT2
谢谢!两者现在都列在一个列表中。但是,无论如何都要检查样品是否以同样的方式洗牌?我获得了87.8%的分类准确度。但我得到的conf_matrix非常低。
[[33 26 35 46]
[43 25 41 31]
[38 36 36 30]
[32 30 39 39]]
答案 0 :(得分:0)
对于你的第二个问题,由于你的预测来自一个热门编码,你应该只是获得最大的参数;以你所示的3个预测为例:
import numpy as np
# your shown predictions:
predict = np.array( [[2.9905824e-12, 5.5904431e-10, 1.8195983e-11 ,1.0000000e+00],
[2.7073351e-21, 1.0000000e+00, 8.3221777e-21, 4.9091786e-22],
[4.2152173e-05, 6.1331893e-04, 3.7486094e-05, 9.9930704e-01]])
predict_class = np.argmax(predict, axis=1)
predict_class = predict_class.tolist()
predict_class
# [3, 1, 3]
关于你的第一个问题:我假设你无法独立获得整个数据集的test_labels
(否则你可能会使用这个长度为560的数组作为你的混淆矩阵);如果是这样,您可以使用 [OP编辑后更新]:
test_labels = []
for i in range(28):
test_imgs, batch_labels = next(test_generator)
batch_labels = np.argmax(batch_labels, axis=1).tolist()
test_labels = test_labels + batch_labels
之后,test_labels
和predict_class
都是长度为560的列表,您应该可以获得整个测试集的混淆矩阵
cm =confusion_matrix(test_labels, predict_class)
为确保预测和测试标签确实一致,您应该将shuffle=False
参数添加到test_datagen.flow_from_directory()
(默认值为True
- docs)。< / p>
鉴于混淆矩阵,如果您需要进一步的分类测量,如精确度,召回等,请查看my answer here。
答案 1 :(得分:0)
您也可以使用sklearn
import numpy as np
# your shown predictions:
predict = np.array( [[2.9905824e-12, 5.5904431e-10, 1.8195983e-11 ,1.0000000e+00],
[2.7073351e-21, 1.0000000e+00, 8.3221777e-21, 4.9091786e-22],
[4.2152173e-05, 6.1331893e-04, 3.7486094e-05, 9.9930704e-01]])
labels = ['class1', 'class2', 'class3', 'class4']
from sklearn.preprocessing import LabelBinarizer
lb.fit(labels)
predict_class = lb.inverse_transform(predict)
print(predict_class)
# ['class4', 'class2', 'class4']