使用训练后ResNet模型推理遇TypeError,求代码修正方案
错误场景
执行代码output = model([image_tensor])时触发TypeError,报错显示conv2d函数接收到无效参数组合,传入了列表而非Tensor类型数据。
完整代码
# import libraries import torch import cv2 import numpy as np # load the trained ResNet model from torch.autograd import Variable model = torch.load("model.pth") model.eval() # load the image of the steel pipe image = cv2.imread("img/75.jpg") DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # preprocess the image image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # convert to RGB image_resized = cv2.resize(image_rgb, (224, 224)) # resize to 224x224 image_normalized = image_resized / 255.0 # normalize to [0, 1] image_tensor = torch.from_numpy(image_normalized) # convert to tensor image_tensor = image_tensor.permute(2, 0, 1) # change the order of channels image_tensor = image_tensor.unsqueeze(0) # add a batch dimension data = Variable(image_tensor).to(DEVICE) # pass the image tensor to the model and get the output print(image) output = model([image_tensor]) # get the predicted bounding boxes, labels, scores, and masks boxes = output["boxes"].detach().numpy() labels = output["labels"].detach().numpy() scores = output["scores"].detach().numpy() masks = output["masks"].detach().numpy() # filter out the objects that are not steel pipes threshold = 0.5 # you can adjust this value indices = np.where((labels == 1) & (scores >= threshold))[0] # assuming label 1 is for steel pipe boxes = boxes[indices] masks = masks[indices] # draw the bounding boxes and masks on the original image for box, mask in zip(boxes, masks): # get the coordinates of the box x1, y1, x2, y2 = box.astype(int) # get the mask for the object mask = mask.squeeze() # resize the mask to match the original image size mask = cv2.resize(mask, (image.shape[1], image.shape[0])) # apply a threshold to binarize the mask mask = (mask > 0.5).astype(np.uint8) # create a color for the mask color = np.random.randint(0, 256, size=3) color = [int(c) for c in color] # draw the bounding box on the image cv2.rectangle(image, (x1, y1), (x2, y2), color, 2) # draw the mask on the image image[mask == 1] = cv2.addWeighted(image[mask == 1], 0.5, np.array(color), 0.5, 0) # save or display the resulting image cv2.imwrite("result.jpg", image) cv2.imshow("Result", image) cv2.waitKey(0) cv2.destroyAllWindows()
报错信息
回溯(最近的调用最后):
文件 "D:\MASTER_Project\testModel.py",第27行,在中
output = model([image_tensor])
文件 "D:\MASTER_Project\venv\lib\site-packages\torch\nn\modules\module.py",第1501行,在_call_impl中
return forward_call(*args, **kwargs)
文件 "D:\MASTER_Project\venv\lib\site-packages\torchvision\models\resnet.py",第285行,在forward中
return self._forward_impl(x)
文件 "D:\MASTER_Project\venv\lib\site-packages\torchvision\models\resnet.py",第268行,在_forward_impl中
x = self.conv1(x)
文件 "D:\MASTER_Project\venv\lib\site-packages\torch\nn\modules\module.py",第1501行,在_call_impl中
return forward_call(*args, **kwargs)
文件 "D:\MASTER_Project\venv\lib\site-packages\torch\nn\modules\conv.py",第463行,在forward中
return self._conv_forward(input, self.weight, self.bias)
文件 "D:\MASTER_Project\venv\lib\site-packages\torch\nn\modules\conv.py",第459行,在_conv_forward中
return F.conv2d(input, weight, bias, self.stride,
TypeError: conv2d()接收到无效的参数组合 - 得到(list, Parameter, NoneType, tuple, tuple, tuple, int),但预期为以下之一:
- (Tensor input, Tensor weight, Tensor bias, tuple of ints stride, tuple of ints padding, tuple of ints dilation, int groups)
不匹配原因是部分参数类型无效:(!list of [Tensor]!, !Parameter!, !NoneType!, !tuple of (int, int)!, !tuple of (int, int)!, !tuple of (int, int)!, int)- (Tensor input, Tensor weight, Tensor bias, tuple of ints stride, str padding, tuple of ints dilation, int groups)
不匹配原因是部分参数类型无效:(!list of [Tensor]!, !Parameter!, !NoneType!, !tuple of (int, int)!, !tuple of (int, int)!, !tuple of (int, int)!, int)
解决方案
1. 修正输入参数类型
ResNet模型的forward方法接受的是Tensor类型输入,而非列表。你错误地将image_tensor用列表包裹传入,导致conv2d层接收到列表而非Tensor,触发类型错误。
将:
output = model([image_tensor])
改为:
# 先将tensor移到模型所在设备(CPU/GPU),同时转换为float32类型匹配模型要求 image_tensor = image_tensor.to(DEVICE).float() output = model(image_tensor)
2. 额外注意事项
- 数据类型匹配:
torch.from_numpy生成的是float64类型Tensor,而PyTorch模型默认使用float32,必须添加.float()转换类型,避免后续数据类型不匹配报错。 - 设备一致性:确保输入Tensor和模型在同一设备(CPU/GPU)上,否则会触发设备不匹配错误。你之前创建了
data变量但未使用,直接使用未移设备的image_tensor会导致问题。 - 模型输出格式:普通ResNet是分类模型,输出的是类别概率张量,而非包含
boxes、labels的字典。如果你的模型是基于ResNet的检测/分割模型(如Mask R-CNN),需单独确认输入格式,但当前报错的核心是输入类型错误,优先解决该问题。
修正后的完整关键代码片段
# preprocess the image image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # convert to RGB image_resized = cv2.resize(image_rgb, (224, 224)) # resize to 224x224 image_normalized = image_resized / 255.0 # normalize to [0, 1] image_tensor = torch.from_numpy(image_normalized) # convert to tensor image_tensor = image_tensor.permute(2, 0, 1) # change the order of channels image_tensor = image_tensor.unsqueeze(0) # add a batch dimension # 修正:将tensor移到目标设备并转换为float32 image_tensor = image_tensor.to(DEVICE).float() # pass the image tensor to the model and get the output print(image) output = model(image_tensor)
内容的提问来源于stack exchange,提问作者Tynoanswers

