rknn-toolkit icon indicating copy to clipboard operation
rknn-toolkit copied to clipboard

onnx导出rknn模型输出结果严重错误问题

Open jsxapril opened this issue 1 year ago • 3 comments

想要导出一个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()

谢谢!

jsxapril avatar Nov 27 '24 09:11 jsxapril

我也是onnx推理完全没有问题,但是转化为rknn推理结果也不对,预处理和后处理都正确,就是结果不对

Coke-Lu avatar Jul 17 '25 04:07 Coke-Lu

同问题,不知道什么原因

SoulProficiency avatar Oct 21 '25 03:10 SoulProficiency

我也是这个问题。

fanronghua0123456 avatar Nov 27 '25 01:11 fanronghua0123456