项目整体是在pytorch中训练好模型后,将保存的pth模型参数转化为onnx,随后通过C++部署。由于医学影像数据的保存格式的特殊性,对于不熟悉C++的新手来说部署面临着很多问题。
onnx模型出现精度偏差解决思路
情况1.确定onnx模型是否出问题:pth转onnx格式可能导致onnx出现参数问题
解决方法:
在pytorch下推理onnx模型,包括cpu和gpu情况,查看结果精度是否有变化
情况2.确定C++代码数据读取和处理是否存在问题:尤其是对于向我这样用习惯python,对C++了解不多的来说,经常在写代码过程中忽略很多数据类型的定义差异,导致虽然能跑通但是数据读取和处理过程出现问题。
解决方法:
从数据读取开始,调试代码,找到数据处理的问题点;
一般情况下,只有这两种原因,不太可能有第三种原因,所以没解决只能说明你还没找到问题点;
onnx模型问题排查
我的模型有两个输入input1,input2,以下是部分自测代码:
# 将张量转化为ndarray格式
def to_numpy(tensor):
return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy()
#测试数据读取
test_dir = glob('\*\*')
test_dataset = CustomDataset(test_dir, args.class_p, args.num, train = False, test = True)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle= False)
#加载onnx预训练的参数
onnx_path = "*.onnx"
ort_session = onnxruntime.InferenceSession(onnx_path)
with torch.no_grad():
for inputs, targets, class_code, path in test_loader:
inputs, targets, class_code = inputs, targets, class_code
input1 = ort_session.get_inputs()[0].name
input2 = ort_session.get_inputs()[1].name
#注意两个输入加入方式
inputs = {input1: to_numpy(inputs), input2: to_numpy(class_code)}
outputs = ort_session.run(None,inputs)
自测后发现onnx模型是没有问题的,那么就应该是C++代码中数据读取和处理的问题
C++代码数据读取和处理代码排查
具体原因是医学影像数据为dcm文件,读出来是Uint16类型,而onnx模型的输入应该是Float32类型。
但修改后,仍然会输出离谱的结果,所以数据读取没有问题,大概率出现在数据处理上。
整个数据处理步骤:读取单个dcm文件——多个dcm通道合并——三维裁剪;
其实这样处理涉及到的被处理的数据比较多,所以我更换了处理步骤:读取单个dcm文件并裁剪——多个dcm通道合并;
整体减少了处理的数据量,同时也简化了数据处理步骤,最后完美解决!
如有其他问题欢迎讨论!