Detectron2汽车损伤检测模型加载报IndexError维度越界求助
问题分析与解决方案
核心错误原因
你遇到的IndexError: too many indices for tensor of dimension 3是因为Detectron2模型的输入格式不符合要求:
- Detectron2的推理模式期望输入是字典列表(每个字典代表一张图片,包含
image等键),而非直接传入张量。 - 你传入的是单个4D张量,模型会错误地将其当作输入列表,遍历其第一维度后尝试访问
x["image"],但3D张量没有字典键,因此触发索引错误。
同时你的代码还存在另外两个关键问题:
- 每个图片张量被额外添加了 batch 维度(
unsqueeze(0)),导致张量维度错误。 - 错误地用
torch.argmax处理模型输出,Detectron2实例分割模型的输出是包含预测实例的字典,而非分类张量。
分步修复代码
1. 修正图片预处理函数
移除不必要的batch维度,调整图像范围以匹配Detectron2默认配置:
def load_and_preprocess_image(image_path): image = Image.open(image_path).convert("RGB") original_width, original_height = image.size transform = transforms.Compose([ transforms.Resize((640, 640)), # 匹配模型训练时的输入尺寸 transforms.ToTensor(), # 转换为[0,1]范围的张量 transforms.Lambda(lambda x: x * 255), # 缩放至[0,255]以匹配Detectron2默认均值 ]) img = transform(image) print("Preprocessed image shape:", img.shape) return { "image": img, "image_path": image_path, "width": original_width, "height": original_height }
2. 修正模型推理函数
改为传入字典列表格式的输入,并返回模型的实例预测结果:
def detect_parts(model, input_dict): # 包装成Detectron2期望的批量输入格式 batched_input = [input_dict] with torch.no_grad(): output = model(batched_input) # 返回单张图片的推理结果 return output[0]
3. 修正主循环中的结果处理逻辑
从模型输出的实例中提取预测类别,而非使用torch.argmax:
for angle in range(1, 9): image_path = f"{image_folder}{angle}.jpg" position = determine_position(image_path) print(f"Checking angle {angle}, image path: {image_path}") print(f"Length of batched_inputs: {len(batched_inputs)}") if len(batched_inputs) >= angle: input_dict = batched_inputs[angle-1] print(f"Accessing batched_inputs at index {angle-1}") # 检测汽车零件 parts_result = detect_parts(carparts_model, input_dict) parts_instances = parts_result["instances"] parts_pred_classes = parts_instances.pred_classes.cpu().numpy() detected_parts = [car_parts[idx] for idx in parts_pred_classes] # 检测受损零件 damage_result = detect_parts(damagedetect_model, input_dict) damage_instances = damage_result["instances"] damage_pred_classes = damage_instances.pred_classes.cpu().numpy() damaged_parts = [car_parts[idx] for idx in damage_pred_classes] print(f"Image: {angle}.jpg") print(f"Position: {position}") print("Detected Parts:", detected_parts) print("Damaged Parts:", damaged_parts) print("----------------------------------") else: print(f"Not enough elements in batched_inputs for angle {angle}")
额外注意事项
- 类别顺序匹配:确保
car_parts列表的顺序与你训练模型时使用的数据集类别顺序完全一致,否则预测结果会对应错误的零件名称。 - 配置文件验证:检查模型配置文件中的
MODEL.ROI_HEADS.NUM_CLASSES是否与你训练时的类别数量一致。 - 归一化适配:如果你的模型训练时使用了
Normalize变换(均值[0.485, 0.456, 0.406],标准差[0.229, 0.224, 0.225]),则需要移除Lambda(lambda x: x*255),并确保配置文件中的PIXEL_MEAN和PIXEL_STD设置为对应值。
内容的提问来源于stack exchange,提问作者Kabir Juneja
相关产品推荐
相关产品推荐

