Keras非序列9分类图像模型获取类别标签异常:预期category6得0.05920969
看起来你遇到的核心问题是多输出模型的预测结果结构没搞对——带Bounding Box的图像识别模型通常是多输出模型(一个输出对应分类概率,另一个对应边界框坐标),而你当前的代码默认model.predict()返回的是单一的分类概率数组,这就导致后续取np.argmax(pred[0])时,实际取的可能是边界框输出里的某个数值,自然得不到正确的类别标签。
再加上你提到预期输出是category6却得到了0.05920969这个数值,说明你误把某个概率值当成了类别索引的结果,本质还是没正确提取分类输出部分。
具体解决步骤
1. 先确认你的模型输出结构
首先运行以下代码查看模型的输出层信息,搞清楚哪个输出是分类结果,哪个是边界框:
model.summary()
你会看到类似这样的输出(示例):
... output_1 (Dense) (None, 9) 4617 output_2 (Dense) (None, 4) 2052 ...
这里output_1是9分类的概率输出(形状(None,9)),output_2是边界框的4个坐标输出(形状(None,4))。
2. 修改预测代码,正确提取分类输出
多输出模型调用model.predict()时,返回的是一个列表,列表中的每个元素对应一个输出层的预测结果。你需要把分类输出和边界框输出分开,再处理分类部分:
修改你的predict_labels函数:
def predict_labels (event,context): img_url = event['imageUrl'] img_id = event['id'] human_id = event['humanId'] img_path = '/tmp/img' os.system('curl -o ' + img_path + ' ' + img_url) new_image = load_image(img_path) # 多输出模型:拆分分类和边界框预测结果 pred_category, pred_bbox = model.predict(new_image) # 从分类概率中取最大值对应的类别 class_idx = np.argmax(pred_category[0]) sonuc = kategoriler[class_idx] response = { 'id' : img_id, 'humanId' : human_id, 'clothes' : { 'category' : sonuc, 'subCategory' : '-' }, 'pred_category': str(pred_category), 'pred_bbox': str(pred_bbox) } return json.dumps(response)
注意:如果你的模型输出顺序和示例相反(比如先输出边界框再输出分类),要把
pred_category, pred_bbox换成pred_bbox, pred_category,以匹配model.summary()里的输出顺序。
3. 验证类别列表的顺序是否和训练时一致
另外要确保kategoriler的顺序和你训练时的类别顺序完全一致:
- 如果你用
ImageDataGenerator.flow_from_directory训练,类别顺序是按文件夹名称字母升序排列的; - 如果是手动编码标签,要和训练时
labelencoder的编码顺序一致。
如果顺序不对,即使分类索引正确,也会匹配到错误的类别名称。
调试小技巧
如果还是有问题,可以在预测后打印这些信息辅助排查:
print("预测结果类型:", type(pred)) print("每个输出的形状:", [p.shape for p in pred]) print("分类概率数组:", pred_category[0]) print("最大概率的索引:", class_idx)
这样就能清楚看到每个部分的数值,快速定位哪里出了问题。
内容的提问来源于stack exchange,提问作者mantaray

