ImageAI加载模型报错:变量形状与值形状不兼容
问题描述
我使用imageai.Detection.Custom.CustomObjectDetection类加载通过imageai.Detection.Custom.DetectionModelTrainer训练的模型,对测试图像进行目标标注。已按官方文档配置好包含所有标签的数据集,但运行检测代码时出现维度不兼容的错误,想确认问题出在检测代码、训练代码还是数据集?
错误堆栈
Traceback (most recent call last): File "./model_predict.py", line 25, in <module> detector.loadModel() File "/home/thecoder3281f/Documents/cca/env/lib/python3.7/site-packages/imageai/Detection/Custom/__init__.py", line 666, in loadModel self.__model.load_weights(self.__model_path) File "/home/thecoder3281f/Documents/cca/env/lib/python3.7/site-packages/tensorflow/python/keras/engine/training.py", line 2234, in load_weights hdf5_format.load_weights_from_hdf5_group(f, self.layers) File "/home/thecoder3281f/Documents/cca/env/lib/python3.7/site-packages/tensorflow/python/keras/saving/hdf5_format.py", line 710, in load_weights_from_hdf5_group K.batch_set_value(weight_value_tuples) File "/home/thecoder3281f/Documents/cca/env/lib/python3.7/site-packages/tensorflow/python/util/dispatch.py", line 201, in wrapper return target(*args, **kwargs) File "/home/thecoder3281f/Documents/cca/env/lib/python3.7/site-packages/tensorflow/python/keras/backend.py", line 3706, in batch_set_value x.assign(np.asarray(value, dtype=dtype(x))) File "/home/thecoder3281f/Documents/cca/env/lib/python3.7/site-packages/tensorflow/python/ops/resource_variable_ops.py", line 891, in assign (tensor_name, self._shape, value_tensor.shape)) ValueError: Cannot assign to variable last1/kernel:0 due to variable shape (1, 1, 1024, 15) and value shape (45, 1024, 1, 1) are incompatible
环境信息
- OS: Ubuntu 22.04
- Python版本: 3.7.15
- GPU: NVIDIA Geforce RTX 2060
- CPU: AMD Ryzen 5 3600
- 文件夹结构符合官方文档规范
训练代码
import os from imageai.Detection.Custom import DetectionModelTrainer os.environ["SM_FRAMEWORK"] = "tf.keras" trainer = DetectionModelTrainer() trainer.setModelTypeAsYOLOv3() trainer.setDataDirectory(data_directory="custom_image_db") trainer.setTrainConfig(object_names_array=[], batch_size=4, num_experiments=20, train_from_pretrained_model="pretrained-yolov3.h5") trainer.trainModel()
检测代码
import os execution_path = os.getcwd() from imageai.Detection.Custom import CustomObjectDetection detector = CustomObjectDetection() detector.setModelTypeAsYOLOv3() detector.setModelPath("custom_image_db/models (1)/detection_model-ex-020--loss-0030.816.h5") detector.setJsonPath("custom_image_db/json (1)/detection_config.json") detector.loadModel() detections = detector.detectObjectsFromImage(input_image="testimg1.jpg", output_image_path="testimg1-detected.jpg", extract_detected_objects=True) for detection in detections: print(detection["name"], " : ", detection["percentage_probability"], " : ", detection["box_points"])
样本XML标注文件
<?xml version="1.0" encoding="utf-8"?> <annotation> <folder>images</folder> <filename>af278bd0-AdobeStock_15555240_Preview.jpeg</filename> <source> <database>MyDatabase</database> <annotation>COCO2017</annotation> <image>flickr</image> <flickrid>NULL</flickrid> <annotator>1</annotator> </source> <owner> <flickrid>NULL</flickrid> <name>Label Studio</name> </owner> <size> <width>1000</width> <height>667</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>Fall</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>35</xmin> <ymin>100</ymin> <xmax>921</xmax> <ymax>603</ymax> </bndbox> </object> <object> <name>Pain</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>557</xmin> <ymin>62</ymin> <xmax>923</xmax> <ymax>314</ymax> </bndbox> </object> </annotation>
问题分析与解决
问题出在训练代码,核心错误是训练时未正确指定数据集的类别列表:
- 训练代码中
trainer.setTrainConfig()的object_names_array参数设为空列表[],但你的数据集明确包含Fall和Pain两个类别。 - YOLOv3的输出层维度由类别数量决定(计算公式:
3*(类别数+5),其中5对应坐标和置信度参数)。训练时未指定类别列表会导致模型按0类别构建输出层,与实际数据集的类别数不匹配,最终生成的模型权重维度混乱,检测加载时出现形状不兼容的错误。
解决步骤
- 修改训练代码,将
object_names_array设置为与数据集匹配的类别列表:trainer.setTrainConfig(object_names_array=["Fall", "Pain"], batch_size=4, num_experiments=20, train_from_pretrained_model="pretrained-yolov3.h5") - 删除之前训练生成的
models和json文件夹,重新训练模型。 - 使用新训练生成的模型文件和对应的
detection_config.json运行检测代码。
额外检查点
- 确认所有标注文件中的类别名称与
object_names_array里的内容完全一致,大小写、拼写不能出错。 - 检测代码加载的模型文件和json文件必须来自同一次训练,不能混用不同训练任务的文件。
内容的提问来源于stack exchange,提问作者NinePlusTenEqualsTwentyOne
相关产品推荐
相关产品推荐

