onnx导出rknn模型输出结果严重错误问题
想要导出一个pytorch模型到rknn,因为这个模型融合了两组模型参数(DISTS: Vgg16+自训练权重)所以采用的先导出到onnx模型、再转化成rknn模型的方式;经过验证,测试数据通过onnx模型推理与pytorch模型精度一致(0.309),但再次转化到rknn模型则结果值完全错误(43744),并且经过反复确认输出数据的预处理模式,偏差量级无差别,可能原因是什么,或是如何定位该问题出错的原因?doc文档已看未找到解决方案。 测试环境: onnx 1.6.0 onnxoptimizer 0.3.13 onnxruntime 1.9.0 protobuf 3.11.2 Numpy 1.19.5 torch 1.9.0 torchvision 0.10.0
onnx模型导出代码: # 创建模型实例 model = DISTS() model.eval()
# 定义输出文件名
output_onnx = '/data/jishuangxi/workspace/iqa_cpp_version/ref_files/DISTS_ONNX/myself_model2.onnx'
output_onnx2 = '/data/jishuangxi/workspace/iqa_cpp_version/ref_files/DISTS_ONNX/myself_model2_simple.onnx'
# 导出模型
torch.onnx.export(
model, # 模型
(x,y), # 输入张量
output_onnx, # 输出文件名
export_params=True, # 是否导出模型参数
opset_version=10, # ONNX 操作集版本,11有问题?10一样不行
do_constant_folding=True, # 是否执行常量折叠优化
# input_names=['input1', 'input2'], # 输入节点名称
# output_names=['output'], # 输出节点名称
input_names=['x.1', 'y'], # 输入节点名称
output_names=['o446'], # 输出节点名称
# dynamic_axes={
# 'input1': {0: 'batch_size'}, # 动态轴
# 'input2': {0: 'batch_size'},
# 'output': {0: 'batch_size'}
#}
)
print(f"Model has been exported to {output_onnx}")
# 加载原始 ONNX 模型~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 读取 ONNX 模型
model = onnx.load(output_onnx)
# 简化模型
model_simplified, check = simplify(model)
# 保存简化后的模型
onnx.save(model_simplified, output_onnx2)
print(f"\nModel has been exported to {output_onnx2}")
rknn模型导出代码: # ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# # Create RKNN object
rknn = RKNN(verbose=True,verbose_file="./rknn_export_build.log")
# ## 模型导出与数据基本没关系,量化有关系~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# pre-process config
# 在构建 RKNN 模型之前,需要先对模型进行通道均值、通道顺序、量化类型等的配置,这些操作可以通过 config 接口进行配置。
# 如果 reorder_channel 设置成’2 1 0‘,则优先做通道调整,再做减均值。(RBG通道)
## output=(input-mean)/std
print('--> Config model')
rknn.config(
mean_values=[[0, 0, 0],[0, 0, 0]],
std_values=[[255,255,255],[255,255,255]], ##TF->torch?
##std_values=[[1,1,1],[1,1,1]], ##TF->torch
#reorder_channel='0 1 2#0 1 2',
#target_platform=["rv1126"],
#quantize_input_node=True,
#optimization_level=3,
#quantized_dtype=asymmetric_quantized-u8,
)
print('done')
# Load ONNX model
print('--> Loading model')
ret = rknn.load_onnx(model=ONNX_MODEL,
inputs=['x.1','y'],
input_size_list=[[3, 256, 256],[3, 256, 256]], #数据形状,填写输入数据形状时不要填batch维
outputs=['o446'])
if ret != 0:
print('Load model.onnx failed!')
exit(ret)
print('done')
# Build model
print('--> Building model')
ret = rknn.build(do_quantization=False,rknn_batch_size=1, dataset='./quant_dataset.txt')
if ret != 0:
print('Build model failed!')
exit(ret)
print('done')
# Export RKNN model
print('--> Export RKNN model')
ret = rknn.export_rknn(RKNN_MODEL)
if ret != 0:
print('Export model.rknn failed!')
exit(ret)
print('done')
# ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ## 加载 RKNN 模型
print('--> Load RKNN model')
ret = rknn.load_rknn(path=RKNN_MODEL)
if ret != 0:
print('load model.rknn failed!')
exit(ret)
print('done')
# init runtime environment
print('\n --> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
exit(ret)
print('done')
## 模型测试与数据有关系,需要格式和预处理一致
print('\n --> data process~~~')
# Set inputs: 数据非原始结构则数据文件需要进行预处理,或是转化成上述config预处理步骤
# img = cv2.imread('./dog_224x224.jpg')
# img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
x = cv2.imread(ref)
y = cv2.imread(dist)
x = cv2.resize(x, (256, 256))
y = cv2.resize(y, (256, 256))
# x = x.astype(np.float32) / 255.0
# y = y.astype(np.float32) / 255.0
x = np.ascontiguousarray(x, dtype=np.float32)/255.0
y = np.ascontiguousarray(y, dtype=np.float32)/255.0
# x = np.transpose(np.expand_dims(x, axis=0), (0, 3, 1, 2))
# y = np.transpose(np.expand_dims(y, axis=0), (0, 3, 1, 2))
# ###x,y: (1, 3, 256, 256) (1, 3, 256, 256)
blob = torch.from_numpy(x).unsqueeze(0)
x = blob.cpu().numpy()
blob = torch.from_numpy(y).unsqueeze(0)
y = blob.cpu().numpy()
##x,y: (1, 256, 256, 3) (1, 256, 256, 3)
print('x,y: ',x.shape, y.shape,[np.min(x),np.max(x)],[np.min(y),np.max(y)])
# Inference
# inputs:待推理的输入,如经过 cv2 处理的图片。格式是 ndarray list
print('\n --> Running model')
outputs = rknn.inference(
inputs=[x,y],
data_type=["float32","float32"],
data_format=['nhwc','nhwc'],
#data_format=['nchw','nchw'],
)
print('done: ',outputs)
rknn.release()
谢谢!
我也是onnx推理完全没有问题,但是转化为rknn推理结果也不对,预处理和后处理都正确,就是结果不对
同问题,不知道什么原因
我也是这个问题。