KerasCV YOLO模型保存加载后报错:'_DictWrapper'对象不可调用
问题:KerasCV YOLOv8模型加载后调用visualize_detections触发TypeError
参考Keras官方YOLOv8教程构建目标检测模型,训练完成后保存模型,加载后调用visualize_detections函数时触发TypeError,提示'_DictWrapper' object is not callable,未执行保存加载操作时该函数可正常运行。
复现代码
backbone = keras_cv.models.YOLOV8Backbone.from_preset("yolo_v8_xs_backbone_coco") yolo = keras_cv.models.YOLOV8Detector( num_classes=len(class_mapping), bounding_box_format="xyxy", backbone=backbone, fpn_depth=1, ) optimizer = tf.keras.optimizers.Adam( learning_rate=LEARNING_RATE, global_clipnorm=GLOBAL_CLIPNORM, ) yolo.compile( optimizer=optimizer, classification_loss="binary_crossentropy", box_loss="ciou" ) stopping_patience = 15 stopping_delta = 0.01 early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=stopping_patience, min_delta=stopping_delta, verbose=1, restore_best_weights=True) history = yolo.fit( train_ds, validation_data=val_ds, epochs=EPOCH, callbacks=[EvaluateCOCOMetricsCallback(val_ds, "model_v2"), early_stopping], ) # saving yolo.save("myyolov8model.keras") # loading model = load_model("myyolov8model_withtraindata_v3.keras", custom_objects={'YOLOV8Detector': keras_cv.models.YOLOV8Detector}, compile=False) model.compile( optimizer=optimizer, classification_loss="binary_crossentropy", box_loss="ciou") visualize_detections(model, dataset=val_ds, bounding_box_format="xyxy", class_mapping=class_mapping)
报错详情
TypeError: File "C:\Users\marlauwe\AppData\Local\anaconda3\Lib\site-packages\keras_cv\models\object_detection\yolo_v8\yolo_v8_detector.py", line 609, in decode_predictions return self.prediction_decoder(box_preds, scores) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: in user code: File "C:\Users\marlauwe\AppData\Local\anaconda3\Lib\site-packages\keras\src\engine\training.py", line 2416, in predict_function * return step_function(self, iterator) File "C:\Users\marlauwe\AppData\Local\anaconda3\Lib\site-packages\keras\src\engine\training.py", line 2401, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "C:\Users\marlauwe\AppData\Local\anaconda3\Lib\site-packages\keras\src\engine\training.py", line 2389, in run_step ** outputs = model.predict_step(data) File "C:\Users\marlauwe\AppData\Local\anaconda3\Lib\site-packages\keras_cv\models\object_detection\yolo_v8\yolo_v8_detector.py", line 616, in predict_step return self.decode_predictions(outputs, args[-1]) File "C:\Users\marlauwe\AppData\Local\anaconda3\Lib\site-packages\keras_cv\models\object_detection\yolo_v8\yolo_v8_detector.py", line 609, in decode_predictions return self.prediction_decoder(box_preds, scores) TypeError: '_DictWrapper' object is not callable
解决方案
问题根源
模型保存与加载过程中,YOLOV8Detector的prediction_decoder组件未被正确序列化,加载后变成了_DictWrapper配置包装对象,而非可调用的解码器实例,导致调用时触发类型错误。
修复步骤
加载模型后,手动重新实例化YOLOV8PredictionDecoder并赋值给模型的prediction_decoder属性:
# 加载模型后添加以下代码 from keras_cv.models.object_detection.yolo_v8 import YOLOV8PredictionDecoder model.prediction_decoder = YOLOV8PredictionDecoder( bounding_box_format="xyxy", num_classes=len(class_mapping), score_threshold=0.25, # 可根据需求调整,默认0.25 iou_threshold=0.7 # 可根据需求调整,默认0.7 )
修改后完整加载代码片段
# loading model = load_model("myyolov8model_withtraindata_v3.keras", custom_objects={'YOLOV8Detector': keras_cv.models.YOLOV8Detector}, compile=False) # 重新设置prediction_decoder from keras_cv.models.object_detection.yolo_v8 import YOLOV8PredictionDecoder model.prediction_decoder = YOLOV8PredictionDecoder( bounding_box_format="xyxy", num_classes=len(class_mapping), score_threshold=0.25, iou_threshold=0.7 ) model.compile( optimizer=optimizer, classification_loss="binary_crossentropy", box_loss="ciou") visualize_detections(model, dataset=val_ds, bounding_box_format="xyxy", class_mapping=class_mapping)
内容的提问来源于stack exchange,提问作者Marlies Lauwers
相关产品推荐
相关产品推荐

