|
板凳
楼主 |
发表于 2020-2-28 20:25:05
|
只看该作者
本帖最后由 ddcat1991 于 2020-2-28 20:36 编辑
谢谢你的回复, 我尝试了打印网络中间层的输出(没有使用量化),发现在第一个Conv-Relu后的输出,计算的结果差异就很大。
> totoal-difference: 88042.95 # onnx与rknn模型 在第一个Conv-Relu操作后输出的权重 差值的绝对值之和
> totoal-weight: 115533.96 # 总权重绝对值之和
> drift-rate: 76.2053% # 当前层输出的 数值差异百分比
输出为第一个Conv-Relu层
模型转换和比较的代码如下:
- import onnx
- from onnx import helper, TensorProto
- import numpy as np
- # Common - Input Setting
- np.random.seed(1234)
- image = np.random.random((1, 3, 240, 320))*2 - 1.0 # 原模型输入为归一化后 -1~1之间的结果
- image = image.astype(np.float32)
- intermidiate_y = '187'
- intermidiate_shape = [1, 16, 120, 160]
- # intermidiate_shape = [1, 4, 8, 10]
- new_model_name = 'toto_%s.onnx' % intermidiate_y
- # load model
- model = onnx.load_model("named_toto.onnx")
- # add output
- intermediate_layer_value_info = helper.make_tensor_value_info(intermidiate_y, TensorProto.FLOAT, intermidiate_shape)
- # intermediate_layer_value_info = helper.ValueInfoProto()
- # intermediate_layer_value_info.name = intermidiate_y
- model.graph.output.extend([intermediate_layer_value_info])
- onnx.save(model, new_model_name)
- onnx.checker.check_model(model)
- # run model
- import onnxruntime as ort
- ort_session = ort.InferenceSession(new_model_name)
- input_name = ort_session.get_inputs()[0].name
- conf_onnx, boxes_onnx, tmp_onnx = ort_session.run(None, {input_name: image})
- # ================ rknn model ========================
- from rknn.api import RKNN
- # Create RKNN object
- rknn = RKNN(verbose=True)
- print('--> Loading model')
- rknn.load_onnx(model=new_model_name)
- print('done')
- rknn.config(batch_size=1)
- rknn.init_runtime()
- # Build model
- print('--> Building model')
- rknn.build(do_quantization=False)
- print('done')
- rknn.export_rknn('./model.rknn')
- print('image.shape:', image.shape)
- conf_rknn, boxes_rknn, tmp_rknn = rknn.inference(inputs=[image])
- ## ========================== Result Compare ===============================
- print('********************* Intermidiante Layer Number: %s *******************' % intermidiate_y)
- tmp_onnx = np.squeeze(tmp_onnx)
- tmp_rknn = np.squeeze(tmp_rknn)
- tmp_onnx = tmp_onnx.reshape(-1,tmp_onnx.shape[-1])
- tmp_rknn = tmp_rknn.reshape(-1,tmp_rknn.shape[-1])
- # for idx in range(tmp_onnx.shape[0],2):
- for idx in range(0,4):
- print('********************* Onnx:%d ****************************' % idx)
- print(tmp_onnx[idx,:20])
- print('********************* Rknn:%d ****************************' % idx)
- print(tmp_rknn[idx,:20])
- difference = np.sum(np.abs(tmp_onnx-tmp_rknn))
- total_weight = np.sum(np.abs(tmp_onnx))
- print('totoal-difference:', difference)
- print('totoal-weight:', total_weight)
- print('drift-rate: %.4f%%' % (difference/total_weight*100))
* 第一个Conv-Relu层就出错了, 第一个Conv是标准的卷积,没有使用分组卷积 (没有开启量化)
* 对比rknn-toolkit pc仿真: 仿真和npu输出结果相同, 但rknn模型与onnx模型的第一层 (Conv-Relu) 的输出差异很大 (误差 76%)
* 目前只尝试了pb的转换,但从pb转换出的模型npu加载失败。
目前使用的版本是 1.3.0, 还有什么别的办法吗?
现在大家一般用哪种模型转换成rknn的比较多呢?
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|