【问题标题】:OpenCV pytorch prediction error with onnx model使用 onnx 模型的 OpenCV pytorch 预测误差
【发布时间】:2022-01-21 00:15:35
【问题描述】:

我的代码在这里。我制作了一个细胞预测模型并将其转换为 onnx,然后加载 OpenCV 以使用 OpenCV 进行预测,但出了点问题

import cv2
import torchvision.models as models
import torch.onnx
import torchvision.transforms as transforms
import numpy as np
Onnx 和模型
original_model = models.resnet50(pretrained=True)

opencv_net = cv2.dnn.readNetFromONNX('resnet50.onnx')
Opencv 预测
opencv_net = cv2.dnn.readNetFromONNX('resnet50.onnx')
input_img=cv2.imread('image.bmp',cv2.COLOR_BGR2GRAY)
input_img=input_img.astype(np.float32)
input_img=cv2.resize(input_img,(256,256))

mean=np.array([0.485, 0.456, 0.406]) * 255.0
scale=1/255.0
std=[0.229, 0.224, 0.225]
input_blob = cv2.dnn.blobFromImage(
    image=input_img,
    scalefactor=scale,
    size=(224, 224),  # img target size
    mean=mean,
    #swapRB=True,  # BGR -> RGB
    crop=True  # center crop
)

input_blob[0] /= np.asarray(std, dtype=np.float32).reshape(3, 1, 1)
print("Input blob shape: {}\n".format(input_blob.shape))
preproc_img=input_blob

opencv_net.setInput(preproc_img)
out = opencv_net.forward()
print("OpenCV DNN prediction: \n")
print("* shape: ", out.shape)

test_class_id = np.argmax(out)

test_labels=opencv_net.getLayerNames()
#print((test_labels))

confidence = out[0][test_class_id]
print("* class ID: {}, label: {}".format(test_class_id, test_labels[test_class_id]))
print("* confidence: {:.4f}".format(confidence))
Opencv 预测输出
OpenCV DNN prediction: 

* shape:  (1, 2)
* class ID: 1, label: 323
* confidence: 8.4153
**!!!问题来了!!! Pytorch 推理**
original_model.eval()
preproc_img = torch.FloatTensor(preproc_img)
# inference
out = original_model(preproc_img)

print("\nPyTorch model prediction: \n")
print("* shape: ", out.shape)

test_class_id = torch.argmax(out, axis=1).item()
print("* class ID: {}, label: {}".format(test_class_id, test_labels[test_class_id]))

confidence = out[0][test_class_id]
print("* confidence: {:.4f}".format(confidence.item()))
错误?
* shape:  torch.Size([1, 1000])
Traceback (most recent call last):
  File "X.py", line 121, in <module>
    print("* class ID: {}, label: {}".format(test_class_id, test_labels[test_class_id]))
IndexError: tuple index out of range

Process finished with exit code 1
当我使用相同的 img 和相同的模型时,这怎么可能?

【问题讨论】:

  • OpenCV 推理与原始框架略有不同,但当差异很大时,blob 参数有问题。检查输入图像上的 pytorch 预处理,并对 opencv 执行相同的操作。在您的代码中,检查均值和通道交换以及可能需要除以标准差。我建议你也测试 onnx-runtime。
  • 不要将 cv2.dnn.blobFromImage 用于灰度图像。单通道输入不需要任何通道拆分。
  • 在 input_img=cv2.imread('image.bmp',cv2.COLOR_BGR2GRAY) 中不要使用用于 cv2.cvtColor 功能的 COLOR_BGR2GRAY 标签。请改用 cv2.IMREAD_GRAYSCALE。
  • @Micka 当我使用“cv2.IMREAD_GRAYSCALE”时出现此错误,我必须使用灰度图像错误:形状 (1,224,224) 的不可广播输出操作数与广播形状 (3,224,224)
  • @iGian 我的输入图像参数看起来与我的 PyTorch 代码相同。不知何故,它适用于 OpenCV DNN,但是当我在同一个 .py 代码文件中对 PyTorch 使用相同的方法时,即使图像相同,也会给我这个错误的形状 (torch.Size([1, 1000])

标签: python opencv deep-learning pytorch onnx


【解决方案1】:

我解决了这个问题。问题在于模型。我在这里使用的是 resnet 50 pretrained,但我需要我的模型,所以我用这些线来解决它并且它的工作。

model = models.resnet50(pretrained = True)
model.fc = nn.Linear(in_features=2048, out_features=2, bias=True)
weights = torch.load('model_best.pth',map_location ='cpu')
model.load_state_dict(weights)
model.eval()

给我同样的 opencv 输出

PyTorch model prediction: 

* shape:  torch.Size([1, 2])
* class ID: 1, label: 323
* confidence: 8.4153

【讨论】:

    猜你喜欢
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 2023-01-31
    • 2021-10-16
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多