diff --git a/README.md b/README.md index 4846874..234f2e2 100644 --- a/README.md +++ b/README.md @@ -11,32 +11,37 @@ Note: # Download From version 1.3.0, some wheel packages are larger than 100MB, can not be uploaded directly. So, you need to go to the releases page to download. You can download from releases page: https://github.com/rockchip-linux/rknn-toolkit/releases -- All wheel packages are in compressed file: [rknn-toolkit-v1.7.3-packages.tar.gz](https://github.com/rockchip-linux/rknn-toolkit/releases/download/v1.7.3/rknn-toolkit-v1.7.3-packages.tar.gz "rknn-toolkit-v1.7.3-packages.tar.gz") or [rknn-toolkit-v1.7.3-packages.zip](https://github.com/rockchip-linux/rknn-toolkit/releases/download/v1.7.3/rknn-toolkit-v1.7.3-packages.zip "rknn-toolkit-v1.7.3-packages.zip ") -- All examples, docs and platform-tools are in compressed file: [Source code(zip)](https://github.com/rockchip-linux/rknn-toolkit/archive/v1.7.3.zip "Source code(zip)") or [Source code(tar.gz)](https://github.com/rockchip-linux/rknn-toolkit/archive/v1.7.3.tar.gz "Source code(tar.gz)") +- All wheel packages are in compressed file: [rknn-toolkit-v1.7.5-packages.tar.gz](https://github.com/rockchip-linux/rknn-toolkit/releases/download/v1.7.5/rknn-toolkit-v1.7.5-packages.tar.gz "rknn-toolkit-v1.7.5-packages.tar.gz") or [rknn-toolkit-v1.7.5-packages.zip](https://github.com/rockchip-linux/rknn-toolkit/releases/download/v1.7.5/rknn-toolkit-v1.7.5-packages.zip "rknn-toolkit-v1.7.5-packages.zip ") +- All examples, docs and platform-tools are in compressed file: [Source code(zip)](https://github.com/rockchip-linux/rknn-toolkit/archive/v1.7.5.zip "Source code(zip)") or [Source code(tar.gz)](https://github.com/rockchip-linux/rknn-toolkit/archive/v1.7.5.tar.gz "Source code(tar.gz)") - You can also download all packages, docker image, examples, docs and platform-tools from baidu cloud: [rknn-toolkit](https://eyun.baidu.com/s/3bqgIr0N "RKNN-Toolkit"), fetch code: rknn - You can download RKNN Toolkit Lite packages and examples from [rknn-toolkit-lite](rknn-toolkit-lite) # Checksums ## MD5 ``` -7d672e911c26af34112bbfcfed86aef7 rknn_toolkit-1.7.3-cp35-cp35m-linux_aarch64.whl -e751a1c2782879dedbe3904448e07105 rknn_toolkit-1.7.3-cp36-cp36m-linux_x86_64.whl -20db420731b4976b15b0fbddef9984e3 rknn_toolkit-1.7.3-cp36-cp36m-macosx_10_15_x86_64.whl -1ebba11b78766cd320a470bb397578cb rknn_toolkit-1.7.3-cp36-cp36m-win_amd64.whl -0cdd9c288a748bcef84848fd5dc12d80 rknn_toolkit-1.7.3-cp37-cp37m-linux_aarch64.whl -f06e1f88864c5a4759e4258cb536c38d rknn_toolkit-1.7.3-cp37-cp37m-macosx_10_15_x86_64.whl -8e5c63a241b809b78ca65d226344d0eb rknn_toolkit-1.7.3-cp38-cp38-linux_x86_64.whl +055ea6bc3b82cd437ebe645076c66960 rknn_toolkit-1.7.5-cp35-cp35m-linux_aarch64.whl +dec84a1226a22914e9912f1ce61cad64 rknn_toolkit-1.7.5-cp36-cp36m-linux_x86_64.whl +3a0f2d0cadb58e60f26fe039394205ab rknn_toolkit-1.7.5-cp36-cp36m-macosx_10_15_x86_64.whl +af96a8ab4cffa1037d41deb155e3d92e rknn_toolkit-1.7.5-cp36-cp36m-win_amd64.whl +4511b18f5a3127fb7375c2dddf597641 rknn_toolkit-1.7.5-cp37-cp37m-linux_aarch64.whl +8873a605594264125aa33bdaf2fc08b3 rknn_toolkit-1.7.5-cp37-cp37m-macosx_10_15_x86_64.whl +da4cd1a1968f9e9aa5414a67598f5374 rknn_toolkit-1.7.5-cp38-cp38-linux_x86_64.whl -a24f157407e16bc255fc387404eb2030 rknn-toolkit-v1.7.3-packages.tar.gz -8dbeeecb06b9201b9f464909ad8d9544 rknn-toolkit-v1.7.3-packages.zip +0818a331d3bba755036cfee296bdad31 rknn-toolkit-v1.7.5-packages.tar.gz +f5de735b9b733d74f97db5cce46c2c70 rknn-toolkit-v1.7.5-packages.zip -4b50d8966908e80567843c3623e33d46 rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_aarch64.whl -dc669361506646104e823d569055b849 rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_x86_64.whl -15a26aad303769f8f2f38f5888529a57 rknn_toolkit_lite-1.7.3-cp36-cp36m-macosx_10_15_x86_64.whl -cd490d13dc1e40e24ab76100a9b82ced rknn_toolkit_lite-1.7.3-cp36-cp36m-win_amd64.whl -17f10789ec42fdc687c3c02ef6dc1141 rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_aarch64.whl -030a09ed522620aa6dfb4ccac578518b rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_armv7l.whl -079aaf9c2c39b2c2a6858688ed733973 rknn_toolkit_lite-1.7.3-cp37-cp37m-macosx_10_15_x86_64.whl -b1b32a4e8803dd9303ab1a72ae8deccf rknn_toolkit_lite-1.7.3-cp38-cp38-linux_x86_64.whl +7adbd9698c7b528413d0ba73b591c83f rknn_toolkit_lite-1.7.5-cp310-cp310-linux_aarch64.whl +3457be77486bcd70c66213f46ce223e3 rknn_toolkit_lite-1.7.5-cp35-cp35m-linux_aarch64.whl +5d1ed1ac6dff669be03578ce39787eea rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_aarch64.whl +2f15ccb2c4140a436d5dfbc8e9544630 rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_armv7l.whl +210fe992928bd57ff638d346e394a5f2 rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_x86_64.whl +16b13b9b710b90f2de10c820180f1c51 rknn_toolkit_lite-1.7.5-cp36-cp36m-macosx_10_15_x86_64.whl +27012b2aa02b78a3720bf9d34e5a42cf rknn_toolkit_lite-1.7.5-cp36-cp36m-win_amd64.whl +90d1f4c19552837a60e7d713c8b86e01 rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_aarch64.whl +0dbfe4e8fc4a50c95d5f8114e379bce5 rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_armv7l.whl +82e046302a2527bec6ebbd957446e8e6 rknn_toolkit_lite-1.7.5-cp37-cp37m-macosx_10_15_x86_64.whl +efe50cbb488c49f4953ff156caef6d07 rknn_toolkit_lite-1.7.5-cp38-cp38-linux_aarch64.whl +59f3f1df13bad289daadab276684c8df rknn_toolkit_lite-1.7.5-cp38-cp38-linux_x86_64.whl +63868f54eae2c98da69679abf4710881 rknn_toolkit_lite-1.7.5-cp39-cp39-linux_aarch64.whl ``` # Feedback and Community Support - QQ Group Chat: 1025468710 (full, please join group 2) diff --git a/doc/RKNN_OP_Support_And_Limit.xlsx b/doc/RKNN_OP_Support_And_Limit.xlsx index ad00f1f..3375a09 100644 Binary files a/doc/RKNN_OP_Support_And_Limit.xlsx and b/doc/RKNN_OP_Support_And_Limit.xlsx differ diff --git a/doc/RKNN_OP_Support_And_Limit_CN.xlsx b/doc/RKNN_OP_Support_And_Limit_CN.xlsx index 221973f..1cb1098 100644 Binary files a/doc/RKNN_OP_Support_And_Limit_CN.xlsx and b/doc/RKNN_OP_Support_And_Limit_CN.xlsx differ diff --git a/doc/RKNN_OP_Support_V1.7.3.md b/doc/RKNN_OP_Support_V1.7.5.md similarity index 100% rename from doc/RKNN_OP_Support_V1.7.3.md rename to doc/RKNN_OP_Support_V1.7.5.md diff --git a/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.3_CN.pdf b/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.3_CN.pdf deleted file mode 100644 index 5248352..0000000 Binary files a/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.3_CN.pdf and /dev/null differ diff --git a/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.3_EN.pdf b/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.3_EN.pdf deleted file mode 100644 index 5c013a9..0000000 Binary files a/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.3_EN.pdf and /dev/null differ diff --git a/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.5_CN.pdf b/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.5_CN.pdf new file mode 100644 index 0000000..440acd8 Binary files /dev/null and b/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.5_CN.pdf differ diff --git a/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.5_EN.pdf b/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.5_EN.pdf new file mode 100644 index 0000000..b4632d1 Binary files /dev/null and b/doc/Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP_V1.7.5_EN.pdf differ diff --git a/doc/Rockchip_Quick_Start_RKNN_Toolkit_V1.7.3_CN.pdf b/doc/Rockchip_Quick_Start_RKNN_SDK_V1.7.5_CN.pdf similarity index 68% rename from doc/Rockchip_Quick_Start_RKNN_Toolkit_V1.7.3_CN.pdf rename to doc/Rockchip_Quick_Start_RKNN_SDK_V1.7.5_CN.pdf index 3e8ec9c..30045d1 100644 Binary files a/doc/Rockchip_Quick_Start_RKNN_Toolkit_V1.7.3_CN.pdf and b/doc/Rockchip_Quick_Start_RKNN_SDK_V1.7.5_CN.pdf differ diff --git a/doc/Rockchip_Quick_Start_RKNN_Toolkit_V1.7.3_EN.pdf b/doc/Rockchip_Quick_Start_RKNN_SDK_V1.7.5_EN.pdf similarity index 62% rename from doc/Rockchip_Quick_Start_RKNN_Toolkit_V1.7.3_EN.pdf rename to doc/Rockchip_Quick_Start_RKNN_SDK_V1.7.5_EN.pdf index a2033b1..9f93f70 100644 Binary files a/doc/Rockchip_Quick_Start_RKNN_Toolkit_V1.7.3_EN.pdf and b/doc/Rockchip_Quick_Start_RKNN_SDK_V1.7.5_EN.pdf differ diff --git a/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.3_CN.pdf b/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.3_CN.pdf deleted file mode 100644 index 541363c..0000000 Binary files a/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.3_CN.pdf and /dev/null differ diff --git a/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.3_EN.pdf b/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.3_EN.pdf deleted file mode 100644 index cbc5177..0000000 Binary files a/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.3_EN.pdf and /dev/null differ diff --git a/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.5_CN.pdf b/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.5_CN.pdf new file mode 100644 index 0000000..82f2026 Binary files /dev/null and b/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.5_CN.pdf differ diff --git a/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.5_EN.pdf b/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.5_EN.pdf new file mode 100644 index 0000000..a3dcf9c Binary files /dev/null and b/doc/Rockchip_Trouble_Shooting_RKNN_Toolkit_V1.7.5_EN.pdf differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.3_CN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.3_CN.pdf deleted file mode 100644 index df76c9a..0000000 Binary files a/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.3_CN.pdf and /dev/null differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.3_EN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.3_EN.pdf deleted file mode 100644 index 69a2cee..0000000 Binary files a/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.3_EN.pdf and /dev/null differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.5_CN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.5_CN.pdf new file mode 100644 index 0000000..88a46b1 Binary files /dev/null and b/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.5_CN.pdf differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.5_EN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.5_EN.pdf new file mode 100644 index 0000000..4f25650 Binary files /dev/null and b/doc/Rockchip_User_Guide_RKNN_Toolkit_Lite_V1.7.5_EN.pdf differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.3_EN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.3_EN.pdf deleted file mode 100644 index 631ff0c..0000000 Binary files a/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.3_EN.pdf and /dev/null differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.3_CN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.5_CN.pdf similarity index 52% rename from doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.3_CN.pdf rename to doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.5_CN.pdf index 4bbb478..8afa5d3 100644 Binary files a/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.3_CN.pdf and b/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.5_CN.pdf differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.5_EN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.5_EN.pdf new file mode 100644 index 0000000..c2db457 Binary files /dev/null and b/doc/Rockchip_User_Guide_RKNN_Toolkit_V1.7.5_EN.pdf differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.3_CN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.5_CN.pdf similarity index 78% rename from doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.3_CN.pdf rename to doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.5_CN.pdf index 790e000..e1fdddd 100644 Binary files a/doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.3_CN.pdf and b/doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.5_CN.pdf differ diff --git a/doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.3_EN.pdf b/doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.5_EN.pdf similarity index 83% rename from doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.3_EN.pdf rename to doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.5_EN.pdf index b133d09..8e883af 100644 Binary files a/doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.3_EN.pdf and b/doc/Rockchip_User_Guide_RKNN_Toolkit_Visualization_V1.7.5_EN.pdf differ diff --git a/doc/changelog.txt b/doc/changelog.txt index 03edc96..e0fe53c 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -1,3 +1,23 @@ +2023-07-31 +版本:v1.7.5 +1. 新增功能: + 增加模型稀疏化功能; + 增加量化参数导出功能; + 量化模块增加离群点检测功能; + 性能分析模块增加各类型算子耗时统计功能。 +2. 功能优化: + 完善对 PyTorch QAT 模型的支持; + 重写 ONNX 模型优化器; + 完善可视化功能; + 优化 MMSE 功能; + 完善图优化模块; + TFLite 转换器增加对不支持算子的检测。 +3. 完善算子支持, 新增erf支持。 +4. 移除对离线预编译 / 模拟器的支持。 +5. 升级部分依赖模块。 +6. 修复已知bug。 + + 2022-08-20 版本:v1.7.3 1. 功能优化: diff --git a/examples/caffe/caffe_upsample/cat.jpg b/examples/caffe/caffe_upsample/cat.jpg deleted file mode 100644 index 62ea7d1..0000000 Binary files a/examples/caffe/caffe_upsample/cat.jpg and /dev/null differ diff --git a/examples/caffe/caffe_upsample/dataset.txt b/examples/caffe/caffe_upsample/dataset.txt deleted file mode 100644 index 23dca25..0000000 --- a/examples/caffe/caffe_upsample/dataset.txt +++ /dev/null @@ -1 +0,0 @@ -cat.jpg diff --git a/examples/caffe/caffe_upsample/deploy.prototxt b/examples/caffe/caffe_upsample/deploy.prototxt deleted file mode 100644 index 61381c5..0000000 --- a/examples/caffe/caffe_upsample/deploy.prototxt +++ /dev/null @@ -1,21 +0,0 @@ -name: "CaffeNet" -layer { - name: "data" - type: "Input" - top: "data" - input_param { shape: { dim: 1 dim: 3 dim: 240 dim: 320 } } -} - -layer { - name: "interp1" - type: "Resize" - bottom: "data" - top: "interp1" - resize_param { - height:480 - width: 640 - interp_mode: 1 - } -} - - diff --git a/examples/caffe/caffe_upsample/solver_iter_45.caffemodel b/examples/caffe/caffe_upsample/solver_iter_45.caffemodel deleted file mode 100644 index ee01f67..0000000 Binary files a/examples/caffe/caffe_upsample/solver_iter_45.caffemodel and /dev/null differ diff --git a/examples/caffe/caffe_upsample/test.py b/examples/caffe/caffe_upsample/test.py deleted file mode 100644 index 59e88bf..0000000 --- a/examples/caffe/caffe_upsample/test.py +++ /dev/null @@ -1,66 +0,0 @@ -import numpy as np -import cv2 -from rknn.api import RKNN - -if __name__ == '__main__': - - # Create RKNN object - rknn = RKNN() - - # Set model config - print('--> Config model') - rknn.config(mean_values=[[0, 0, 0]], std_values=[[1, 1, 1]], reorder_channel='2 1 0') - print('done') - - # Load Caffe model - print('--> Loading model') - ret = rknn.load_caffe(model='./deploy.prototxt', - proto='caffe', - blobs='./solver_iter_45.caffemodel') - if ret != 0: - print('Load interp_test failed! Ret = {}'.format(ret)) - exit(ret) - print('done') - - # Build model - print('--> Building model') - ret = rknn.build(do_quantization=True, dataset='./dataset.txt') - if ret != 0: - print('Build interp_test failed!') - exit(ret) - print('done') - - # Export RKNN model - print('--> Export RKNN model') - ret = rknn.export_rknn('./interp_test.rknn') - if ret != 0: - print('Export interp_test.rknn failed!') - exit(ret) - print('done') - - # Set inputs - old_img = cv2.imread('./cat.jpg') - img = cv2.cvtColor(old_img, cv2.COLOR_BGR2RGB) - - print('--> Init runtime environment') - ret = rknn.init_runtime() - if ret != 0: - print('Init runtime environment failed') - exit(ret) - print('done') - - # Inference - print('--> Running model') - outputs = rknn.inference(inputs=[img]) - - result = outputs[0].astype(np.uint8) - - new_img = np.reshape(np.transpose(np.reshape(result, (3, 480 * 640))), (480, 640, 3)) - - cv2.imshow("image", old_img) - cv2.imshow("new image", new_img) - cv2.waitKey(5000) - cv2.destroyAllWindows() - - rknn.release() - diff --git a/examples/caffe/mobilenet_v2/README.md b/examples/caffe/mobilenet_v2/README.md new file mode 100644 index 0000000..2e7d025 --- /dev/null +++ b/examples/caffe/mobilenet_v2/README.md @@ -0,0 +1,75 @@ +# Example for Caffe mobilenet_v2 + + +## Model Source +The model used in this example come from the following open source projects: +https://github.com/shicai/MobileNet-Caffe + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +[1]: 0.73388671875 +[115 996]: 0.033447265625 +[115 996]: 0.033447265625 +[927]: 0.026214599609375 +[794]: 0.024169921875 +``` + +1. The label index with the highest score is 1, the corresponding label is `goldfish`. +2. The download link for labels file: https://github.com/HoldenCaulfieldRye/caffe/blob/master/data/ilsvrc12/synset_words.txt. +3. Different platforms, different versions of tools and drivers may have slightly different results. + + +## Notes + +- The prototxt in the open source model uses the old version of Caffe, which has been modified in the actual example. The modified content is as follows +``` +# Comment or remove the following content: +input: "data" +input_dim: 1 +input_dim: 3 +input_dim: 224 +input_dim: 224 + +# Add the following content +layer { + name: "data" + type: "Input" + top: "data" + input_param { + shape { + dim: 1 + dim: 3 + dim: 224 + dim: 224 + } + } +} +``` + diff --git a/examples/caffe/mobilenet_v2/test.py b/examples/caffe/mobilenet_v2/test.py index ba9ae91..860bcfe 100644 --- a/examples/caffe/mobilenet_v2/test.py +++ b/examples/caffe/mobilenet_v2/test.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -22,16 +24,39 @@ def show_outputs(outputs): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # Set model config print('--> Config model') - rknn.config(mean_values=[[103.94, 116.78, 123.68]], std_values=[[58.82, 58.82, 58.82]], reorder_channel='2 1 0') + rknn.config(mean_values=[[103.94, 116.78, 123.68]], + std_values=[[58.82, 58.82, 58.82]], + reorder_channel='2 1 0', + target_platform=[target]) print('done') - # Load caffe model + # Load model (from https://github.com/shicai/MobileNet-Caffe) print('--> Loading model') ret = rknn.load_caffe(model='./mobilenet_v2.prototxt', proto='caffe', @@ -62,7 +87,11 @@ def show_outputs(outputs): img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') exit(ret) diff --git a/examples/caffe/vgg-ssd/README b/examples/caffe/vgg-ssd/README deleted file mode 100644 index 890f343..0000000 --- a/examples/caffe/vgg-ssd/README +++ /dev/null @@ -1,3 +0,0 @@ -1. Download models_VGGNet_VOC0712_SSD_300x300.tar.gz from https://drive.google.com/file/d/0BzKzrI_SkD1_WVVTSmQxU0dVRzA/view -2. Extract the VGG_VOC0712_SSD_300x300_iter_120000.caffemodel from models_VGGNet_VOC0712_SSD_300x300.tar.gz -3. Or you can also download the caffemodel directly from https://eyun.baidu.com/s/3jJhPRzo , password is rknn diff --git a/examples/caffe/vgg-ssd/README.md b/examples/caffe/vgg-ssd/README.md new file mode 100644 index 0000000..6001db0 --- /dev/null +++ b/examples/caffe/vgg-ssd/README.md @@ -0,0 +1,70 @@ +# Example for Caffe VGG-SSD + + +## Model Source +The model used in this example come from the following open source projects: +https://github.com/weiliu89/caffe/tree/ssd +The download link provided by this project has expired, please download the model weight from the following network disk link(fetch code is `rknn`): +https://eyun.baidu.com/s/3jJhPRzo + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +The test result should be similar to picutre `ref_detect_result.jpg`. + +*Note: Different platforms, different versions of tools and drivers may have slightly different results.* + + +## Notes + +- The prototxt in the open source model uses the old version of Caffe, which has been modified in the actual example. The modified content is as follows +``` +# Comment or remove the following content: +input: "data" +input_shape { + dim: 1 + dim: 3 + dim: 300 + dim: 300 +} + +# Add the following content: +layer { + name: "input" + type: "Input" + top: "data" + input_param { + shape { + dim: 1 + dim: 3 + dim: 300 + dim: 300 + } + } +} +``` +- The DetectionOutput layer is also been removed. diff --git a/examples/caffe/vgg-ssd/ref_detect_results.jpg b/examples/caffe/vgg-ssd/ref_detect_results.jpg new file mode 100644 index 0000000..8185342 Binary files /dev/null and b/examples/caffe/vgg-ssd/ref_detect_results.jpg differ diff --git a/examples/caffe/vgg-ssd/test.py b/examples/caffe/vgg-ssd/test.py index c62e53f..0b926f4 100644 --- a/examples/caffe/vgg-ssd/test.py +++ b/examples/caffe/vgg-ssd/test.py @@ -1,3 +1,5 @@ +import platform +import sys import os import math import numpy as np @@ -144,16 +146,35 @@ def ssd_post_process(conf_data, loc_data): draw.text((x1+margin, text_bottom-text_height-margin), display_str, fill='black', font=font) np.copyto(img, np.array(img_pil)) - cv2.imwrite("result.jpg", img) + cv2.imwrite("results.jpg", img) + print("The detection results have been saved to results.jpg") if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) if not os.path.exists('./VGG_VOC0712_SSD_300x300_iter_120000.caffemodel'): print('!!! Missing VGG_VOC0712_SSD_300x300_iter_120000.caffemodel !!!\n' \ - '1. Download models_VGGNet_VOC0712_SSD_300x300.tar.gz from https://drive.google.com/file/d/0BzKzrI_SkD1_WVVTSmQxU0dVRzA/view\n' \ - '2. Extract the VGG_VOC0712_SSD_300x300_iter_120000.caffemodel from models_VGGNet_VOC0712_SSD_300x300.tar.gz\n' \ - '3. Or you can also download caffemodel from https://eyun.baidu.com/s/3jJhPRzo , password is rknn\n') + '1. Please download caffemodel from https://eyun.baidu.com/s/3jJhPRzo , fetch code is: rknn\n') exit(-1) # Create RKNN object @@ -161,7 +182,10 @@ def ssd_post_process(conf_data, loc_data): # Set model config print('--> Config model') - rknn.config(mean_values=[[103.94, 116.78, 123.68]], std_values=[[1, 1, 1]], reorder_channel='2 1 0') + rknn.config(mean_values=[[103.94, 116.78, 123.68]], + std_values=[[1, 1, 1]], + reorder_channel='2 1 0', + target_platform=[target]) print('done') # Load caffe model @@ -195,7 +219,11 @@ def ssd_post_process(conf_data, loc_data): img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') exit(ret) @@ -206,6 +234,7 @@ def ssd_post_process(conf_data, loc_data): outputs = rknn.inference(inputs=[img]) print('done') + # Post process: get detected objects, corresponding scores and coordinates outputs[0] = outputs[0].reshape((-1, 1)) outputs[1] = outputs[1].reshape((-1, 1)) ssd_post_process(outputs[1], outputs[0]) diff --git a/examples/common_function_demos/accuracy_analysis/README.md b/examples/common_function_demos/accuracy_analysis/README.md index 1f76ed5..199429d 100644 --- a/examples/common_function_demos/accuracy_analysis/README.md +++ b/examples/common_function_demos/accuracy_analysis/README.md @@ -1,70 +1,69 @@ -## RKNN-Toolkit accuracy_analysis 例程 +# Example of accuracy analysis -#### 一.使用说明 +## Overview -​ 本例程以 shufflenetv2.onnx 模型作为示范,展示 RKNN-Toolkit 精度分析 accuracy_analysis 接口的使用流程,在常规量化模式效果有限的情况下,使用混合量化 hybrid_quantization 接口,提高 RKNN 模型的最终推理精度。实际使用时,请根据具体需求,在推理精度与推理速度的之间作一定的取舍。 +This example uses the shufflenetv2.onnx model as a demonstration to show the usage flow of the RKNN-Toolkit accuracy analysis. And when the post-quantization accuracy is not good, use the hybrid_quantization interface to improve the inference accuracy of the RKNN model. In actual use, please make a certain trade-off between inference accuracy and inference speed according to specific needs. +## Steps for usage -#### 二.使用步骤 - -1. 生成常规量化模型,并生成精度分析报告。 +1. Generate conventional quantization RKNN model and generate accuracy analysis report. `python normal_quantizition.py` - - 执行后在该工程目录下可得到 normal_quantization_analysis 的文件夹,各文件/目录的含义参考 《Rockchip_User_Guide_RKNN_Toolkit_CN.docx》的 4.3章节说明。 - - - 这里我们生成文件夹中 individual_qnt_error_analysis.txt 文件,可以看到Conv_418_152、Conv_434_142、Conv_530_69 网络层的 cosine_norm 值分别为0.972651、0.989210、0.963591,我们就判断这几个网络层对量化不友好,需要我们使用混合量化去处理这些网络层。而其他网络层的 cosine_norm 值都在0.99以上,通常可以认为是量化友好的。我们先记录下这些网络层的名称,供后续步骤使用。 + - After execution, the normal_quantization_analysis folder can be obtained in the project directory. For the meaning of each file/directory, refer to Chapter 4.3 of "Rockchip_User_Guide_RKNN_Toolkit_CN.docx". + - From the generated individual_qnt_error_analysis.txt file, you can see that the normalized cosine values ​​of the three layers Conv_418, Conv_434, and Conv_530 are 0.97, 0.98, and 0.96 respectively, which are relatively low compared to other layers and can be considered unfriendly to quantization. These operators can be expressed with high-precision data types (such as int16 or float16) through hybrid quantization. The normalized cosine values ​​of other network layers are all above 0.99, which can be considered quantization-friendly. Record the names of these network layers first for later steps. + - The default target platform of this script is rv1126. If you want to run the exported RKNN model on rk1808/rk3399pro, you need to specify the target when calling the script, such as: `python normal_quantizition.py rk1808`. - -2. 执行混合量化步骤一,生成配置文件,具体资料可参考《Rockchip_User_Guide_RKNN_Toolkit_CN.docx》的 4.5 章节 。 +2. Execute hybrid quantization step 1 to generate a quantization configuration file. For details, please refer to Chapter 4.5 of "Rockchip_User_Guide_RKNN_Toolkit_CN.docx". `python hybrid_quantization_step1.py` - - 打开生成的 torchjitexport.quantization.cfg 配置文件,参考 《Rockchip_User_Guide_RKNN_Toolkit_CN.docx》4.5 节 的说明,我们就可以在 customized_quantize_layers 信息里面添加我们想要使用混合量化处理的网络层(从步骤1中得到)。 + - Open the generated torchjitexport.quantization.cfg configuration file, refer to the instructions in Section 4.5 of "Rockchip_User_Guide_RKNN_Toolkit_CN.docx", and add the network layer (obtained from step 1) and the corresponding high-precision data type that you want to use hybrid quantization processing in the customized_quantize_layers information。 - - 配置文件中的 customized_quantize_layers 会给初始混合量化层的建议,这个建议的效果不一定是最优的,实际使用过程中请根据具体模型灵活设置。示例模型生成的 quantization.cfg 混合量化建议为: + - customized_quantize_layers in the config file will suggest a default hybrid quantization layers. The RKNN model generated according to this suggestion may not be optimal. Please set it flexibly according to the specific model during actual use. The quantization.cfg generated by the example model is recommended for hybrid quantification as follows (different platforms, different versions of tools, the layer names may have some differences): ``` customized_quantize_layers: - Reshape_614_2: dynamic_fixed_point-i16 - Gemm_615_1: dynamic_fixed_point-i16 - AveragePool_612_3: dynamic_fixed_point-i16 - Reshape_614_2_acuity_mark_perm_213: dynamic_fixed_point-i16 - Conv_434_142: dynamic_fixed_point-i16 - Conv_436_133: dynamic_fixed_point-i16 - Slice_363_204: dynamic_fixed_point-i16 - Conv_364_201: dynamic_fixed_point-i16 - Conv_530_69: dynamic_fixed_point-i16 - Conv_466_118: dynamic_fixed_point-i16 - Conv_418_152: dynamic_fixed_point-i16 - Conv_383_181: dynamic_fixed_point-i16 - Conv_367_193: dynamic_fixed_point-i16 - Conv_345_195: dynamic_fixed_point-i16 - Conv_353_196: dynamic_fixed_point-i16 - Conv_343_202: dynamic_fixed_point-i16 - Conv_348_209: dynamic_fixed_point-i16 + Reshape_Reshape_614_2: dynamic_fixed_point-i16 + Gemm_Gemm_615_1: dynamic_fixed_point-i16 + AveragePool_AveragePool_612_3: dynamic_fixed_point-i16 + Reshape_Reshape_614_2_acuity_mark_perm_157: dynamic_fixed_point-i16 + Conv_Conv_434_104: dynamic_fixed_point-i16 + Conv_Conv_436_101: dynamic_fixed_point-i16 + Slice_Slice_363_148: dynamic_fixed_point-i16 + Conv_Conv_364_145_acuity_mark_perm_209: dynamic_fixed_point-i16 + Conv_Conv_530_49: dynamic_fixed_point-i16 + Conv_Conv_466_86: dynamic_fixed_point-i16 + Conv_Conv_418_113: dynamic_fixed_point-i16 + Conv_Conv_383_132: dynamic_fixed_point-i16 + Conv_Conv_367_141: dynamic_fixed_point-i16 + Conv_Conv_345_146: dynamic_fixed_point-i16 + Conv_Conv_353_147: dynamic_fixed_point-i16 + Conv_Conv_343_149: dynamic_fixed_point-i16 + Conv_Conv_348_153: dynamic_fixed_point-i16 ``` - 这里我们按照步骤一的观察结果,修改为: + Here we follow the observation results of step 1 and modify it as: ``` customized_quantize_layers: - Conv_434_142: dynamic_fixed_point-i16 - Conv_530_69: dynamic_fixed_point-i16 - Conv_418_152: dynamic_fixed_point-i16 + Conv_Conv_434_104: dynamic_fixed_point-i16 + Conv_Conv_530_49: dynamic_fixed_point-i16 + Conv_Conv_418_113: dynamic_fixed_point-i16 ``` + - The default target platform of this script is rv1126. If you want to run the exported RKNN model on rk1808/rk3399pro, you need to specify the target when calling the script, shuc as: `python hybrid_quantization_step1.py rk1808`. - -3. 执行混合量化步骤二,生成混合量化模型。 +3. Execute the second step of hybrid quantization, recalculate the quantization parameters, and generate a hybrid quantization RKNN model. `python hybrid_quantization_step2.py` - + *Note: The default target platform of this script is rv1126. If you want to run the exported RKNN model on rk1808/rk3399pro, you need to specify the target when calling the script, such as: `python hybrid_quantization_step1.py rk1808`.* -4. 对比原模型、常规量化模型和混合量化模型的分类结果得分。 + +4. Compare the classification result scores of the original model, conventional quantization model and hybrid quantization model. `python run_onnx_model.py` @@ -77,31 +76,67 @@ [879]: 0.0001287872582906857 ``` - - `python run_normal_quantization_model.py` ``` -----TOP 5----- - [155]: 0.8933969140052795 - [154]: 0.08192264288663864 - [364]: 0.0026254409458488226 - [193]: 0.00216865842230618 - [879]: 0.0014796829782426357 + [155]: 0.9094294309616089 + [154]: 0.06887859851121902 + [364]: 0.0020060015376657248 + [193]: 0.0018231587018817663 + [879]: 0.0012439332203939557 ``` - - `python run_hybrid_quantization_model.py` ``` -----TOP 5----- - [155]: 0.9505037665367126 - [154]: 0.04464513808488846 - [364]: 0.0006053716060705483 - [194]: 0.0005000471719540656 - [879]: 0.0003411838551983237 + [155]: 0.9504370093345642 + [154]: 0.04463796317577362 + [194 364]: 0.0005500342231243849 + [194 364]: 0.0005500342231243849 + [879]: 0.00041292302194051445 + ``` + + - It can be seen that the classification score of the hybrid quantization model has been greatly improved, and is closer to the classification score of the original model. Here users can also try to use the default recommended configuration for hybrid quantization. + - Different platforms, different versions of tools and drivers may have slightly different results. + + +## Parameter description for scripts + + +- normal_quantizition + ``` + python normal_quantizition.py [target] + ``` + - target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. + + +- hybrid_quantization_step1 + ``` + python hybrid_quantization_step1.py [target] + ``` + - target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. + + +- hybrid_quantization_step2 + ``` + python hybrid_quantization_step2.py [target] ``` + - target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. - 可以看到混合量化模型的分类得分得到了不小的提升,更接近于原始模型的分类得分。这里用户也可以自己尝试使用默认推荐配置进行混合量化时,混合量化模型的得分效果。 +- run_normal_quantization_model + ``` + python run_normal_quantization_model.py [target] [device_id] + ``` + - target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. + - device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + + +- run_hybrid_quantization_model + ``` + python run_hybrid_quantization_model.py [target] [device_id] + ``` + - target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. + - device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. diff --git a/examples/common_function_demos/accuracy_analysis/README_CN.md b/examples/common_function_demos/accuracy_analysis/README_CN.md new file mode 100644 index 0000000..de3bf09 --- /dev/null +++ b/examples/common_function_demos/accuracy_analysis/README_CN.md @@ -0,0 +1,146 @@ +# RKNN-Toolkit accuracy_analysis 例程 + +## 使用说明 + +​ 本例程以 shufflenetv2.onnx 模型作为示范,展示 RKNN-Toolkit 精度分析 accuracy_analysis 接口的使用流程。在常规量化模式效果有限的情况下,通过使用混合量化,提高 RKNN 模型的推理精度。实际使用时,请根据具体需求,在推理精度与推理速度的之间作一定的取舍。 + + +## 使用步骤 + +1. 生成常规量化模型,并生成精度分析报告。 + + `python normal_quantizition.py` + + - 执行后在该工程目录下可得到 normal_quantization_analysis 文件夹,各文件/目录的含义参考 《Rockchip_User_Guide_RKNN_Toolkit_CN.docx》4.3章节说明。 + + - 观察生成的 individual_qnt_error_analysis.txt 文件,可以看到 Conv_418、Conv_434、Conv_530 这三层归一化后的余弦值分别为 0.97、0.98、0.96,比其他层的归一化余弦值低一些,初步判断这几层对量化不友好,需要使用混合量化去处理这些网络层。而其他网络层归一化后的余弦值都在0.99以上,通常可以认为是量化友好的。先记录下量化不友好网络层的名称,供后续步骤使用。 + + - 这个脚本默认的 target 是 rv1126,如果要在 rk1808/rk3399pro 上运行导出的 RKNN 模型,需要在调用该脚本时指定target,如: `python normal_quantizition.py rk1808`。 + + +2. 执行混合量化步骤一,生成配置文件,具体资料可参考《Rockchip_User_Guide_RKNN_Toolkit_CN.docx》的 4.5 章节 。 + + `python hybrid_quantization_step1.py` + + - 打开生成的 torchjitexport.quantization.cfg 配置文件,参考 《Rockchip_User_Guide_RKNN_Toolkit_CN.docx》4.5 节 的说明,在 customized_quantize_layers 信息里面添加想要使用混合量化处理的网络层(从步骤1中得到)。 + + - 配置文件中的 customized_quantize_layers 会给初始混合量化层的建议,这个建议的效果不一定是最优的,实际使用过程中请根据具体模型灵活设置。示例模型生成的 quantization.cfg 混合量化建议为: + + ``` + customized_quantize_layers: + Reshape_Reshape_614_2: dynamic_fixed_point-i16 + Gemm_Gemm_615_1: dynamic_fixed_point-i16 + AveragePool_AveragePool_612_3: dynamic_fixed_point-i16 + Reshape_Reshape_614_2_acuity_mark_perm_157: dynamic_fixed_point-i16 + Conv_Conv_434_104: dynamic_fixed_point-i16 + Conv_Conv_436_101: dynamic_fixed_point-i16 + Slice_Slice_363_148: dynamic_fixed_point-i16 + Conv_Conv_364_145_acuity_mark_perm_209: dynamic_fixed_point-i16 + Conv_Conv_530_49: dynamic_fixed_point-i16 + Conv_Conv_466_86: dynamic_fixed_point-i16 + Conv_Conv_418_113: dynamic_fixed_point-i16 + Conv_Conv_383_132: dynamic_fixed_point-i16 + Conv_Conv_367_141: dynamic_fixed_point-i16 + Conv_Conv_345_146: dynamic_fixed_point-i16 + Conv_Conv_353_147: dynamic_fixed_point-i16 + Conv_Conv_343_149: dynamic_fixed_point-i16 + Conv_Conv_348_153: dynamic_fixed_point-i16 + ``` + + 按照步骤一的观察结果,修改为: + + ``` + customized_quantize_layers: + Conv_Conv_434_104: dynamic_fixed_point-i16 + Conv_Conv_530_49: dynamic_fixed_point-i16 + Conv_Conv_418_113: dynamic_fixed_point-i16 + ``` + + - 这个脚本默认的 target 是 rv1126,如果要在 rk1808/rk3399pro 上运行导出的 RKNN 模型,需要在调用该脚本时指定target,如: `python hybrid_quantization_step1.py rk1808` + + +3. 执行混合量化步骤二,生成混合量化模型。 + + `python hybrid_quantization_step2.py` + + *Note: 这个脚本默认的 target 是 rv1126,如果要在 rk1808/rk3399pro 上运行导出的 RKNN 模型,需要在调用该脚本时指定target,如: `python hybrid_quantization_step1.py rk1808`* + + +4. 对比原模型、常规量化模型和混合量化模型的分类结果得分。 + + `python run_onnx_model.py` + + ``` + -----TOP 5----- + [155]: 0.9758387804031372 + [154]: 0.02226063795387745 + [364]: 0.00038293670513667166 + [960]: 0.00022784945031162351 + [879]: 0.0001287872582906857 + ``` + + `python run_normal_quantization_model.py` + + ``` + -----TOP 5----- + [155]: 0.9094294309616089 + [154]: 0.06887859851121902 + [364]: 0.0020060015376657248 + [193]: 0.0018231587018817663 + [879]: 0.0012439332203939557 + ``` + + `python run_hybrid_quantization_model.py` + + ``` + -----TOP 5----- + [155]: 0.9504370093345642 + [154]: 0.04463796317577362 + [194 364]: 0.0005500342231243849 + [194 364]: 0.0005500342231243849 + [879]: 0.00041292302194051445 + ``` + + 可以看到混合量化模型的分类得分得到了不小的提升,更接近于原始模型的分类得分。这里用户也可以自己尝试使用默认推荐配置进行混合量化。 + + Note: 不同平台、不同版本的工具得到的结果可能有细微差异。 + + +## 各脚本参数说明 + + +- normal_quantizition + ``` + python normal_quantizition.py [target] + ``` + - target: 目标设备平台,可选参数,默认值是 rv1126。可填如下值: rk1806, rk1808, rk3399pro, rv1109, rv1126。 + + +- hybrid_quantization_step1 + ``` + python hybrid_quantization_step1.py [target] + ``` + - target: 目标设备平台,可选参数,默认值是 rv1126。可填如下值: rk1806, rk1808, rk3399pro, rv1109, rv1126。 + + +- hybrid_quantization_step2 + ``` + python hybrid_quantization_step2.py [target] + ``` + - target: 目标设备平台,可选参数,默认值是 rv1126。可填如下值: rk1806, rk1808, rk3399pro, rv1109, rv1126。 + + +- run_normal_quantization_model + ``` + python run_normal_quantization_model.py [target] [device_id] + ``` + - target: 目标设备平台,可选参数,默认值是 rv1126。可填如下值: rk1806, rk1808, rk3399pro, rv1109, rv1126。 + - device_id: 目标设备 ID,如果连有多个设备,需要填写设备 ID 进行区分。该参数是一个可选参数,如果不填写,默认的设备 ID 为 None。 + + +- run_hybrid_quantization_model + ``` + python run_hybrid_quantization_model.py [target] [device_id] + ``` + - target: 目标设备平台,可选参数,默认值是 rv1126。可填如下值: rk1806, rk1808, rk3399pro, rv1109, rv1126。 + - device_id: 目标设备 ID,如果连有多个设备,需要填写设备 ID 进行区分。该参数是一个可选参数,如果不填写,默认的设备 ID 为 None。 diff --git a/examples/common_function_demos/accuracy_analysis/hybrid_quantization_step1.py b/examples/common_function_demos/accuracy_analysis/hybrid_quantization_step1.py index f844b67..1bb4605 100644 --- a/examples/common_function_demos/accuracy_analysis/hybrid_quantization_step1.py +++ b/examples/common_function_demos/accuracy_analysis/hybrid_quantization_step1.py @@ -1,15 +1,34 @@ +import sys from rknn.api import RKNN ONNX_MODEL = 'shufflenetv2_x1.onnx' if __name__ == '__main__': + # Default target platform + target = 'rv1126' + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) > 2: + print('Too much arguments') + print('Usage: python {} [target]'.format(sys.argv[0])) + print('Such as: python {} rv1126'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # model config print('--> Config model') - rknn.config(mean_values=[[123.68, 116.28, 103.53]], std_values=[[57.38, 57.38, 57.38]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.68, 116.28, 103.53]], + std_values=[[57.38, 57.38, 57.38]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load onnx model diff --git a/examples/common_function_demos/accuracy_analysis/hybrid_quantization_step2.py b/examples/common_function_demos/accuracy_analysis/hybrid_quantization_step2.py index f17e78d..45ca19d 100644 --- a/examples/common_function_demos/accuracy_analysis/hybrid_quantization_step2.py +++ b/examples/common_function_demos/accuracy_analysis/hybrid_quantization_step2.py @@ -1,13 +1,32 @@ +import sys from rknn.api import RKNN if __name__ == '__main__': + # Default target platform + target = 'rv1126' + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) > 2: + print('Too much arguments') + print('Usage: python {} [target]'.format(sys.argv[0])) + print('Such as: python {} rv1126'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # Set model config print('--> config model') - rknn.config(mean_values=[[123.68, 116.28, 103.53]], std_values=[[57.38, 57.38, 57.38]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.68, 116.28, 103.53]], + std_values=[[57.38, 57.38, 57.38]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Hybrid quantization step2 diff --git a/examples/common_function_demos/accuracy_analysis/normal_quantization.py b/examples/common_function_demos/accuracy_analysis/normal_quantization.py index 89b5ad6..bca2ba5 100644 --- a/examples/common_function_demos/accuracy_analysis/normal_quantization.py +++ b/examples/common_function_demos/accuracy_analysis/normal_quantization.py @@ -1,3 +1,4 @@ +import sys import numpy as np from rknn.api import RKNN @@ -24,13 +25,30 @@ def show_outputs(outputs): if __name__ == '__main__': + # Default target platform + target = 'rv1126' + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + else: + print('Too much arguments') + print('Usage: python {} [target]'.format(sys.argv[0])) + print('Such as: python {} rv1126'.format(sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # pre-process config print('--> Config model') - rknn.config(mean_values=[[123.68, 116.28, 103.53]], std_values=[[57.38, 57.38, 57.38]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.68, 116.28, 103.53]], + std_values=[[57.38, 57.38, 57.38]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load ONNX model diff --git a/examples/common_function_demos/accuracy_analysis/run_hybrid_quantization_model.py b/examples/common_function_demos/accuracy_analysis/run_hybrid_quantization_model.py index 5f4c969..2bf74ea 100644 --- a/examples/common_function_demos/accuracy_analysis/run_hybrid_quantization_model.py +++ b/examples/common_function_demos/accuracy_analysis/run_hybrid_quantization_model.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -25,6 +27,26 @@ def softmax(x): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() @@ -43,7 +65,11 @@ def softmax(x): # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') exit(ret) diff --git a/examples/common_function_demos/accuracy_analysis/run_normal_quantization_model.py b/examples/common_function_demos/accuracy_analysis/run_normal_quantization_model.py index dc687c5..b3de8f9 100644 --- a/examples/common_function_demos/accuracy_analysis/run_normal_quantization_model.py +++ b/examples/common_function_demos/accuracy_analysis/run_normal_quantization_model.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -25,6 +27,26 @@ def softmax(x): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() @@ -43,7 +65,11 @@ def softmax(x): # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') exit(ret) diff --git a/examples/common_function_demos/batch_size/README.md b/examples/common_function_demos/batch_size/README.md index aed354b..237f663 100644 --- a/examples/common_function_demos/batch_size/README.md +++ b/examples/common_function_demos/batch_size/README.md @@ -1,3 +1,83 @@ -the inputs data need to be merged together using np.concatenate. +# Example for multi-batch + + + +## Model Source +The model used in this example come from the TensorFlow Lite offical model zoo: +https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1.md + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test images classification results. For example, the inference results of this example are as follows: +``` +mobilenet_v1 input[0] +-----TOP 5----- +[156]: 0.85400390625 +[155]: 0.092041015625 +[205]: 0.01226806640625 +[284]: 0.006488800048828125 +[260]: 0.002246856689453125 + +mobilenet_v1 input[1] +-----TOP 5----- +[156]: 0.85400390625 +[155]: 0.092041015625 +[205]: 0.01226806640625 +[284]: 0.006488800048828125 +[260]: 0.002246856689453125 + +mobilenet_v1 input[2] +-----TOP 5----- +[156]: 0.85400390625 +[155]: 0.092041015625 +[205]: 0.01226806640625 +[284]: 0.006488800048828125 +[260]: 0.002246856689453125 + +mobilenet_v1 input[3] +-----TOP 5----- +[156]: 0.85400390625 +[155]: 0.092041015625 +[205]: 0.01226806640625 +[284]: 0.006488800048828125 +[260]: 0.002246856689453125 +``` + +1. The label index with the highest score is 156, the corresponding label is `Pekinese, Pekingese, Peke`. +2. The label used in this model contains background, so its index will be 1 more than other examples. +3. The top-5 perdictions of 4 inputs should be exactly the same. +4. Different platforms, different versions of tools and drivers may have slightly different results. + + +## Notes + +1. the inputs data need to be merged together using np.concatenate. +``` e.g: img = np.concatenate((img, img, img, img), axis=0) +``` diff --git a/examples/common_function_demos/batch_size/test.py b/examples/common_function_demos/batch_size/test.py index 4750e46..92a5956 100644 --- a/examples/common_function_demos/batch_size/test.py +++ b/examples/common_function_demos/batch_size/test.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -5,9 +7,9 @@ def show_outputs(outputs): output_ = outputs[0].reshape((-1, 1001)) - for output in output_: + for idx, output in enumerate(output_): output_sorted = sorted(output, reverse=True) - top5_str = 'mobilenet_v1\n-----TOP 5-----\n' + top5_str = 'mobilenet_v1 input[{}]\n-----TOP 5-----\n'.format(idx) for i in range(5): value = output_sorted[i] index = np.where(output == value) @@ -23,14 +25,37 @@ def show_outputs(outputs): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN(verbose=False) # Set model config print('--> Config model') - rknn.config(mean_values=[[103.94, 116.78, 123.68]], std_values=[[58.82, 58.82, 58.82]], reorder_channel='0 1 2', - quantized_dtype='asymmetric_quantized-u8') + rknn.config(mean_values=[[127.5, 127.5, 127.5]], + std_values=[[127.5, 127.5, 127.5]], + reorder_channel='0 1 2', + quantized_dtype='asymmetric_quantized-u8', + target_platform=[target]) print('done') # Load TFLite model @@ -65,7 +90,11 @@ def show_outputs(outputs): # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') exit(ret) diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_math/README.md b/examples/common_function_demos/custom_op/rknn_custom_op_math/README.md new file mode 100644 index 0000000..76e6504 --- /dev/null +++ b/examples/common_function_demos/custom_op/rknn_custom_op_math/README.md @@ -0,0 +1,3 @@ +# Custom op demo +Please refer document **Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP**, which could be found here https://github.com/rockchip-linux/rknn-toolkit/tree/master/doc + diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_math/exp.yml b/examples/common_function_demos/custom_op/rknn_custom_op_math/exp.yml index 9e91239..ca14aeb 100644 --- a/examples/common_function_demos/custom_op/rknn_custom_op_math/exp.yml +++ b/examples/common_function_demos/custom_op/rknn_custom_op_math/exp.yml @@ -1,6 +1,6 @@ name: Exp framework: tensorflow -target_platform: rk1808 +target_platform: rv1126 inputs: input: type: VX_TYPE_TENSOR diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_math/exp/makefile.linux.x64 b/examples/common_function_demos/custom_op/rknn_custom_op_math/exp/makefile.linux.x64 deleted file mode 100644 index 1b88e45..0000000 --- a/examples/common_function_demos/custom_op/rknn_custom_op_math/exp/makefile.linux.x64 +++ /dev/null @@ -1,9 +0,0 @@ -BASE_DRIVER_INCLUDE := -I/home/raul/work/python-env/rknn-package-tvenv/lib/python3.5/site-packages/rknn/simulator/LION/include -BASE_DRIVER_LIB := -L/home/raul/work/python-env/rknn-package-tvenv/lib/python3.5/site-packages/rknn/simulator/LION/lib/x64_linux -Wl,--no-as-needed -lOpenVX -OUTDIR := ./.out/x64 - -FLAGS := -fPIC - -all: - if [ ! -d $(OUTDIR) ]; then mkdir -p $(OUTDIR); else echo "$(OUTDIR) exist"; fi - $(CC) $(FLAGS) -shared $(BASE_DRIVER_INCLUDE) $(BASE_DRIVER_LIB) -o $(OUTDIR)/libexp.so rknn_kernel_exp.c \ No newline at end of file diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_math/rknn_custom_op_math.py b/examples/common_function_demos/custom_op/rknn_custom_op_math/rknn_custom_op_math.py index cb27dce..9c59087 100644 --- a/examples/common_function_demos/custom_op/rknn_custom_op_math/rknn_custom_op_math.py +++ b/examples/common_function_demos/custom_op/rknn_custom_op_math/rknn_custom_op_math.py @@ -1,4 +1,3 @@ -import cv2 import numpy as np from rknn.api import RKNN @@ -6,29 +5,55 @@ rknn = RKNN(verbose=False) + # RKNN model config. + print("--> Model config") + rknn.config(target_platform=['rv1126']) + print("done") + + # Register customer op. rknn.register_op('./truncatediv/TruncateDiv.rknnop') rknn.register_op('./exp/Exp.rknnop') - rknn.load_tensorflow(tf_pb='./custom_op_math.pb', - inputs=['input'], - outputs=['exp_0'], - input_size_list=[[1, 512]]) - rknn.build(do_quantization=False) + # Load TensorFlow model with customer op. + print("--> Load tensorflow model.") + ret = rknn.load_tensorflow(tf_pb='./custom_op_math.pb', + inputs=['input'], + outputs=['exp_0'], + input_size_list=[[1, 512]]) + if ret != 0: + print("Load TF model failed.") + rknn.release() + exit(ret) + print("done") + + # Build RKNN model. + print("--> Build RKNN model") + ret = rknn.build(do_quantization=False) + if ret != 0: + print("Build RKNN model failed.") + rknn.release() + exit(ret) + print('done') + # rknn.export_rknn('./rknn_test.rknn') # rknn.load_rknn('./rknn_test.rknn') - rknn.init_runtime('rk1808') - - print("init runtime done") + # Inference with RKNN + print("--> Init RKNN runtime.") + ret = rknn.init_runtime(target="rv1126") + if ret != 0: + print("Init runtime failed.") + rknn.release() + exit(ret) + print("done") in_data = np.full((1, 512), 50.0) in_data = in_data.astype(dtype='float32') output = rknn.inference(inputs=[in_data]) + # Show output print(output) rknn.release() - pass - diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_math/truncatediv.yml b/examples/common_function_demos/custom_op/rknn_custom_op_math/truncatediv.yml index 9f2ea80..4be98f1 100644 --- a/examples/common_function_demos/custom_op/rknn_custom_op_math/truncatediv.yml +++ b/examples/common_function_demos/custom_op/rknn_custom_op_math/truncatediv.yml @@ -1,6 +1,6 @@ name: TruncateDiv framework: tensorflow -target_platform: rk1808 +target_platform: rv1126 inputs: input0: type: VX_TYPE_TENSOR diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_math/truncatediv/makefile.linux.x64 b/examples/common_function_demos/custom_op/rknn_custom_op_math/truncatediv/makefile.linux.x64 deleted file mode 100644 index 6aa7308..0000000 --- a/examples/common_function_demos/custom_op/rknn_custom_op_math/truncatediv/makefile.linux.x64 +++ /dev/null @@ -1,9 +0,0 @@ -BASE_DRIVER_INCLUDE := -I/home/raul/work/python-env/rknn-package-tvenv/lib/python3.5/site-packages/rknn/simulator/LION/include -BASE_DRIVER_LIB := -L/home/raul/work/python-env/rknn-package-tvenv/lib/python3.5/site-packages/rknn/simulator/LION/lib/x64_linux -Wl,--no-as-needed -lOpenVX -OUTDIR := ./.out/x64 - -FLAGS := -fPIC - -all: - if [ ! -d $(OUTDIR) ]; then mkdir -p $(OUTDIR); else echo "$(OUTDIR) exist"; fi - $(CC) $(FLAGS) -shared $(BASE_DRIVER_INCLUDE) $(BASE_DRIVER_LIB) -o $(OUTDIR)/libtruncatediv.so rknn_kernel_truncatediv.c \ No newline at end of file diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_resize/README.md b/examples/common_function_demos/custom_op/rknn_custom_op_resize/README.md new file mode 100644 index 0000000..76e6504 --- /dev/null +++ b/examples/common_function_demos/custom_op/rknn_custom_op_resize/README.md @@ -0,0 +1,3 @@ +# Custom op demo +Please refer document **Rockchip_Developer_Guide_RKNN_Toolkit_Custom_OP**, which could be found here https://github.com/rockchip-linux/rknn-toolkit/tree/master/doc + diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_resize/resize_area.yml b/examples/common_function_demos/custom_op/rknn_custom_op_resize/resize_area.yml index c84ae61..c9f6a90 100644 --- a/examples/common_function_demos/custom_op/rknn_custom_op_resize/resize_area.yml +++ b/examples/common_function_demos/custom_op/rknn_custom_op_resize/resize_area.yml @@ -1,6 +1,6 @@ name: ResizeArea framework: tensorflow -target_platform: rk1808 +target_platform: rv1126 inputs: input: type: VX_TYPE_TENSOR diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_resize/resize_area/makefile.linux.x64 b/examples/common_function_demos/custom_op/rknn_custom_op_resize/resize_area/makefile.linux.x64 deleted file mode 100644 index 9ddc5a0..0000000 --- a/examples/common_function_demos/custom_op/rknn_custom_op_resize/resize_area/makefile.linux.x64 +++ /dev/null @@ -1,9 +0,0 @@ -BASE_DRIVER_INCLUDE := -I/home/raul/work/python-env/rknn-package-tvenv/lib/python3.5/site-packages/rknn/simulator/LION/include -BASE_DRIVER_LIB := -L/home/raul/work/python-env/rknn-package-tvenv/lib/python3.5/site-packages/rknn/simulator/LION/lib/x64_linux -Wl,--no-as-needed -lOpenVX -OUTDIR := ./.out/x64 - -FLAGS := -fPIC - -all: - if [ ! -d $(OUTDIR) ]; then mkdir -p $(OUTDIR); else echo "$(OUTDIR) exist"; fi - $(CC) $(FLAGS) -shared $(BASE_DRIVER_INCLUDE) $(BASE_DRIVER_LIB) -o $(OUTDIR)/libresizearea.so rknn_kernel_resizearea.c \ No newline at end of file diff --git a/examples/common_function_demos/custom_op/rknn_custom_op_resize/rknn_custom_op_resize_area.py b/examples/common_function_demos/custom_op/rknn_custom_op_resize/rknn_custom_op_resize_area.py index 578c22f..763036f 100644 --- a/examples/common_function_demos/custom_op/rknn_custom_op_resize/rknn_custom_op_resize_area.py +++ b/examples/common_function_demos/custom_op/rknn_custom_op_resize/rknn_custom_op_resize_area.py @@ -6,24 +6,57 @@ rknn = RKNN(verbose=False) + # RKNN model config + print("--> Model config") + rknn.config(target_platform=['rv1126']) + print("done") + + # Register customer op. + print("--> Register customer op.") rknn.register_op('./resize_area/ResizeArea.rknnop') + print("done") + + # Load TensorFlow model with customer op. + print("--> Load TF model.") + ret = rknn.load_tensorflow(tf_pb='./resize_area_test.pb', + inputs=['input'], + outputs=['resize_area_0'], + input_size_list=[[32, 32, 3]]) + if ret != 0: + print("Load TF model failed.") + rknn.release() + exit(-1) + print("done") + + # Build RKNN model. + print("--> Build RKNN model") + ret = rknn.build(do_quantization=False) + if ret != 0: + print("Build RKNN model failed.") + rknn.release() + exit(ret) + print("done") - rknn.load_tensorflow(tf_pb='./resize_area_test.pb', - inputs=['input'], - outputs=['resize_area_0'], - input_size_list=[[32, 32, 3]]) - rknn.build(do_quantization=False) # rknn.export_rknn('./resize_area.rknn') # rknn.load_rknn('./resize_area.rknn') - rknn.init_runtime('rk1808') + # Inference with RKNN. + print("--> Init RKNN runtime") + ret = rknn.init_runtime('rv1126') + if ret != 0: + print("Init runtime failed.") + rknn.release() + exit(ret) + print("done") img = cv2.imread('./dog_32x32.jpg') outs = rknn.inference(inputs=[img]) + # Show inference result. out_img = outs[0].astype('uint8') out_img = np.reshape(out_img, (64, 64, 3)) cv2.imwrite('./out.jpg', out_img) + rknn.release() diff --git a/examples/common_function_demos/eval_mem/README.md b/examples/common_function_demos/eval_mem/README.md new file mode 100644 index 0000000..65f2e10 --- /dev/null +++ b/examples/common_function_demos/eval_mem/README.md @@ -0,0 +1,9 @@ +# The RKNN model memory usage evaluation +## Usage +Execute command below to evaluate the memory usage of RKNN model. +``` +python eval_mem.py xxx.rknn [target] [device_id] +``` +- xxx.rknn: the RKNN model. +- target: target device, like rv1109, rv1126, rk1808 or rk3399pro. Optional. +- device_id: target device id. Optional. diff --git a/examples/common_function_demos/eval_mem/eval_mem.py b/examples/common_function_demos/eval_mem/eval_mem.py new file mode 100644 index 0000000..e5e92e3 --- /dev/null +++ b/examples/common_function_demos/eval_mem/eval_mem.py @@ -0,0 +1,53 @@ +import platform +import sys +from rknn.api import RKNN + +if __name__ == '__main__': + if len(sys.argv) not in [2, 3, 4]: + print('Usage: python {} xxx.rknn [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} mobilenet_v1.rknn rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + + # default target and device_id + target = 'rv1126' + device_id = None + if len(sys.argv) == 2: + print('Use default target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[2] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 4: + target = sys.argv[2] + device_id = sys.argv[3] + print('Set target: {}, device id: {}'.format(target, device_id)) + + rknn = RKNN() + + model_path = sys.argv[1] + + ret = rknn.load_rknn(model_path) + if ret != 0: + print('load rknn model failed') + rknn.release() + exit(ret) + + # init runtime environment + # Note: you must connect an NPU target, or this function will fail. + print('--> Init runtime environment') + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id, eval_mem=True) + if ret != 0: + print('Init runtime environment failed') + rknn.release() + exit(ret) + print('done') + + # Inference + print('--> Running model') + rknn.eval_memory() + + rknn.release() diff --git a/examples/common_function_demos/eval_perf/README.md b/examples/common_function_demos/eval_perf/README.md new file mode 100644 index 0000000..c2b0104 --- /dev/null +++ b/examples/common_function_demos/eval_perf/README.md @@ -0,0 +1,10 @@ +# The RKNN model performance evaluation +## Usage +Execute command below to evaluate the performance of RKNN model on specified target. +``` +python eval_perf.py xxx.rknn [perf_debug] [target] [device_id] +``` +- xxx.rknn: the RKNN model. +- perf_debug: if perf_debug set 0, only show total inference time; if perf_debug set 1, show the time spent on each layer. Optional. +- target: target device, like rv1109, rv1126, rk1808 or rk3399pro. Optional. +- device_id: target device id. Optional. diff --git a/examples/common_function_demos/eval_perf/eval_perf.py b/examples/common_function_demos/eval_perf/eval_perf.py new file mode 100644 index 0000000..add9863 --- /dev/null +++ b/examples/common_function_demos/eval_perf/eval_perf.py @@ -0,0 +1,60 @@ +import platform +import sys +from rknn.api import RKNN + +if __name__ == '__main__': + if len(sys.argv) not in [2, 3, 4, 5]: + print('Usage: python {} xxx.rknn [perf_debug] [target] [device_id]'.format(sys.argv[0])) + print(' if perf_debug set 0, only show total inference time;') + print(' if perf_debug set 1, show the time spent on each layer.') + print('Such as: python {} mobilenet_v1.rknn 1 rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + + rknn = RKNN() + + model_path = sys.argv[1] + perf_debug = False + + # default target and device_id + target = 'rv1126' + device_id = None + + if len(sys.argv) == 3: + perf_debug = True if sys.argv[2] == '1' else False + print('Use default target: {}'.format(target)) + elif len(sys.argv) == 4: + perf_debug = True if sys.argv[2] == '1' else False + target = sys.argv[3] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 5: + perf_debug = True if sys.argv[2] == '1' else False + target = sys.argv[3] + device_id = sys.argv[4] + print('Set target: {}, device id: {}'.format(target, device_id)) + + ret = rknn.load_rknn(model_path) + if ret != 0: + print('load rknn model failed') + rknn.release() + exit(ret) + + # init runtime environment + # Note: you must set perf_debug=True if you want to analysis time spent on each layer. + print('--> Init runtime environment') + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id, perf_debug=perf_debug) + if ret != 0: + print('Init runtime environment failed') + rknn.release() + exit(ret) + print('done') + + # Inference + print('--> Running model') + rknn.eval_perf(loop_cnt=100) + + rknn.release() diff --git a/examples/common_function_demos/export_encrypt_rknn_model/export_encrypt_rknn_model.py b/examples/common_function_demos/export_encrypt_rknn_model/export_encrypt_rknn_model.py index df9a3fd..1f283ae 100644 --- a/examples/common_function_demos/export_encrypt_rknn_model/export_encrypt_rknn_model.py +++ b/examples/common_function_demos/export_encrypt_rknn_model/export_encrypt_rknn_model.py @@ -24,6 +24,7 @@ ret = rknn.export_encrypted_rknn_model(orig_rknn, encrypt_rknn, encrypt_level) if ret != 0: print('Encrypt RKNN model failed!') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/export_rknn_precompile_model/README.md b/examples/common_function_demos/export_rknn_precompile_model/README.md index 011e0ad..f1a4c28 100644 --- a/examples/common_function_demos/export_rknn_precompile_model/README.md +++ b/examples/common_function_demos/export_rknn_precompile_model/README.md @@ -1 +1,10 @@ -RKNN Toolkit does not support exporting precompiled rknn models from Windows and MacOS via the build() interface. The precompiled model needs to be exported via the interface export_rknn_precompile_model(). This interface requires a connection to the RK1808 device. (Note that RK3399pro does not support this feature) \ No newline at end of file +# Online pre-compilation +## Usage +Execute command below to export pre-compilation RKNN model with specified target. +``` +python eval_perf xxx.rknn xxx.rknn xxx_precompile.rknn [target] [device_id] +``` +- xxx.rknn: the RKNN model path. +- xxx_precompile.rknn: the pre-compiled RKNN model path. +- target: target device, like rv1109, rv1126, rk1808 or rk3399pro. Optional, default target is `rv1126`. +- device_id: target device id. Optional. \ No newline at end of file diff --git a/examples/common_function_demos/export_rknn_precompile_model/export_rknn_precompile_model.py b/examples/common_function_demos/export_rknn_precompile_model/export_rknn_precompile_model.py index e9af6eb..3ec91bf 100644 --- a/examples/common_function_demos/export_rknn_precompile_model/export_rknn_precompile_model.py +++ b/examples/common_function_demos/export_rknn_precompile_model/export_rknn_precompile_model.py @@ -1,17 +1,32 @@ +import platform import sys +from rknn.api import RKNN if __name__ == '__main__': - if len(sys.argv) != 3: - print('Usage: python {} xxx.rknn xxx.hw.rknn'.format(sys.argv[0])) - print('Such as: python {} mobilenet_v1.rknn mobilenet_v1.hw.rknn'.format(sys.argv[0])) + if len(sys.argv) not in [3, 4, 5]: + print('Usage: python {} xxx.rknn xxx.hw.rknn [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} mobilenet_v1.rknn mobilenet_v1.hw.rknn rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) exit(1) - from rknn.api import RKNN - orig_rknn = sys.argv[1] hw_rknn = sys.argv[2] + # default target and device_id + target = 'rv1126' + device_id = None + + if len(sys.argv) == 3: + print('Use default target: {}'.format(target)) + elif len(sys.argv) == 4: + target = sys.argv[3] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 5: + target = sys.argv[3] + device_id = sys.argv[4] + print('Set target: {}, device id: {}'.format(target, device_id)) + # Create RKNN object rknn = RKNN() @@ -20,6 +35,7 @@ ret = rknn.load_rknn(orig_rknn) if ret != 0: print('Load RKNN model failed!') + rknn.release() exit(ret) print('done') @@ -28,9 +44,10 @@ # Note: you must set rknn2precompile=True when call rknn.init_runtime() # RK3399Pro with android system does not support this function. - ret = rknn.init_runtime(target='rk1808', rknn2precompile=True) + ret = rknn.init_runtime(target=target, device_id=device_id, rknn2precompile=True) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/hybrid_quantization/README.md b/examples/common_function_demos/hybrid_quantization/README.md deleted file mode 100644 index 919d1da..0000000 --- a/examples/common_function_demos/hybrid_quantization/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Usage of Hybrid Quantization -``` -1. install RKNN-Toolkit -2. execute commands below: - a. python3 step1.py - b. modify quantization config file: xxx.quantization.cfg - c. python3 step2.py - d. python3 step3.py -``` diff --git a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/README.md b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/README.md new file mode 100644 index 0000000..ca31a7c --- /dev/null +++ b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/README.md @@ -0,0 +1,71 @@ +# Example for hybrid quantization with PyTorch mnasnet0_5 + + +## Model Source +The models used in this example come from the torchvision project: +https://github.com/pytorch/vision/tree/main/torchvision/models + + +## Usage for the script + +*Usage:* +``` +# The step1 of hybrid quantization: get model structure, weight and quantization configure files +python step1.py [target] +# Modify quantization configure file +# The step2 of hybrid quantization: requantize and generate RKNN model +pyton step2.py [target] +# Inference with hybrid quantization model +python step3.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python step1.py +python step2.py +python step3.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python step1.py rk1808 +python step2.py rk1808 +python step3.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: +``` +python step1.py +python step2.py +python step3.py rv1126 c3d9b8674f4b94f6 +``` + + +## The method to modify quantization configuration file +Add {layer_name}: {quantized_dtype} to dict of customized_quantize_layers. +If no layer changed, please set {} as empty directory for customized_quantize_layers + +*Notes:* +1. The layer_name comes from quantize_parameters, please strip '@' and ':xxx'; + If layer_name contains special characters, please quote the layer name. +2. Support quantized_type: asymmetric_affine-u8, dynamic_fixed_point-i8, dynamic_fixed_point-i16, float32. +3. Please fill in according to the grammatical rules of yaml. +4. For this model, RKNN Toolkit has provided the corresponding configuration, please directly proceed to step2. + + +## Expected results + +This step3.py will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +[812]: 0.7788181304931641 +[484]: 0.029811235144734383 +[404]: 0.01403999887406826 +[833]: 0.011485863476991653 +[403]: 0.010388719849288464 +``` + +1. The label index with the highest score is 812, the corresponding label is `space shuttle`. +2. The download link for labels file: https://s3.amazonaws.com/onnx-model-zoo/synset.txt. +3. If you manually modify the quantization configuration file, the top5 obtained may be different. +4. Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/mnasnet0_5.pt b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/mnasnet0_5.pt deleted file mode 100644 index aa09e9f..0000000 Binary files a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/mnasnet0_5.pt and /dev/null differ diff --git a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step1.py b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step1.py index 89df0d7..7e3d9c5 100644 --- a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step1.py +++ b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step1.py @@ -1,13 +1,44 @@ +import sys from rknn.api import RKNN +import torch +import torchvision.models as models + + +def export_pytorch_model(): + net = models.mnasnet0_5(pretrained=True) + net.eval() + trace_model = torch.jit.trace(net, torch.Tensor(1, 3, 224, 224)) + trace_model.save('./mnasnet0_5.pt') if __name__ == '__main__': + # Default target platform + target = 'rv1126' + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) > 2: + print('Too much arguments') + print('Usage: python {} [target]'.format(sys.argv[0])) + print('Such as: python {} rv1126'.format( + sys.argv[0])) + exit(-1) + + # Export mnasnet0_5 torchscript model + export_pytorch_model() # Create RKNN object rknn = RKNN() # model config print('--> Config model') - rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[58.395, 58.395, 58.395]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.675, 116.28, 103.53]], + std_values=[[58.395, 58.395, 58.395]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load Pytorch model @@ -15,6 +46,7 @@ ret = rknn.load_pytorch(model='./mnasnet0_5.pt', input_size_list=[[3, 224, 224]]) if ret != 0: print('Load model failed!') + rknn.release() exit(ret) print('done') @@ -23,6 +55,7 @@ ret = rknn.hybrid_quantization_step1(dataset='./dataset.txt') if ret != 0: print('hybrid_quantization_step1 failed!') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step2.py b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step2.py index 17eafab..35db1d0 100644 --- a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step2.py +++ b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step2.py @@ -1,13 +1,32 @@ +import sys from rknn.api import RKNN if __name__ == '__main__': + # Default target platform + target = 'rv1126' + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) > 2: + print('Too much arguments') + print('Usage: python {} [target]'.format(sys.argv[0])) + print('Such as: python {} rv1126'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # Set model config print('--> config model') - rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[58.395, 58.395, 58.395]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.675, 116.28, 103.53]], + std_values=[[58.395, 58.395, 58.395]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Hybrid quantization step2 @@ -18,6 +37,7 @@ dataset='./dataset.txt') if ret != 0: print('hybrid_quantization_step2 failed!') + rknn.release() exit(ret) print('done') @@ -26,6 +46,7 @@ ret = rknn.export_rknn('./mnasnet0_5.rknn') if ret != 0: print('Export RKNN model failed!') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step3.py b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step3.py index d596a06..e9564d1 100644 --- a/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step3.py +++ b/examples/common_function_demos/hybrid_quantization/mnasnet0_5/step3.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -34,6 +36,26 @@ def softmax(x): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() @@ -43,6 +65,7 @@ def softmax(x): ret = rknn.load_rknn('./mnasnet0_5.rknn') if ret != 0: print('Load mnasnet0_5.rknn failed!') + rknn.release() exit(ret) print('done') @@ -52,10 +75,14 @@ def softmax(x): # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() - # ret = rknn.init_runtime(target='rk1808', device_id='1808s1') + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/README.md b/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/README.md new file mode 100644 index 0000000..d52c977 --- /dev/null +++ b/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/README.md @@ -0,0 +1,61 @@ +# Example for hybrid quantization with TensorFlow ssd_mobilenet_v2_coco_2018_03_29 + + +## Model Source +The model comes from TensorFlow's official model zoo: +https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf1_detection_zoo.md + + +## Usage for the script + +*Usage:* +``` +# The step1 of hybrid quantization: get model structure, weight and quantization configure files +python step1.py [target] +# Modify quantization configure file +# The step2 of hybrid quantization: requantize and generate RKNN model +pyton step2.py [target] +# Inference with hybrid quantization model +python step3.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python step1.py +python step2.py +python step3.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python step1.py rk1808 +python step2.py rk1808 +python step3.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: +``` +python step1.py +python step2.py +python step3.py rv1126 c3d9b8674f4b94f6 +``` + + +## The method to modify quantization configuration file +Add {layer_name}: {quantized_dtype} to dict of customized_quantize_layers. +If no layer changed, please set {} as empty directory for customized_quantize_layers + +*Notes:* +1. The layer_name comes from quantize_parameters, please strip '@' and ':xxx'; + If layer_name contains special characters, please quote the layer name. +2. Support quantized_type: asymmetric_affine-u8, dynamic_fixed_point-i8, dynamic_fixed_point-i16, float32. +3. Please fill in according to the grammatical rules of yaml. +4. For this model, RKNN Toolkit has provided the corresponding configuration, please directly proceed to step2. + + +## Expected results + +The test result should be similar to picutre `ref_detect_result.jpg`. + +- Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step1.py b/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step1.py index 821e92d..fb36b39 100644 --- a/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step1.py +++ b/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step1.py @@ -1,14 +1,33 @@ +import sys from rknn.api import RKNN if __name__ == '__main__': + # Default target platform + target = 'rv1126' + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) > 2: + print('Too much arguments') + print('Usage: python {} [target]'.format(sys.argv[0])) + print('Such as: python {} rv1126'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # Set model config print('--> Config model') - rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], - reorder_channel='0 1 2', batch_size=16) + rknn.config(mean_values=[[127.5, 127.5, 127.5]], + std_values=[[127.5, 127.5, 127.5]], + reorder_channel='0 1 2', + batch_size=16, + target_platform=[target]) print('done') # Load tensorflow model @@ -20,6 +39,7 @@ predef_file=None) if ret != 0: print('Load model failed!') + rknn.release() exit(ret) print('done') @@ -28,6 +48,7 @@ ret = rknn.hybrid_quantization_step1(dataset='./dataset.txt') if ret != 0: print('hybrid_quantization_step1 failed!') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step2.py b/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step2.py index 9b0cd6c..0d8f8a8 100644 --- a/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step2.py +++ b/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step2.py @@ -1,14 +1,33 @@ +import sys from rknn.api import RKNN if __name__ == '__main__': + # Default target platform + target = 'rv1126' + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) > 2: + print('Too much arguments') + print('Usage: python {} [target]'.format(sys.argv[0])) + print('Such as: python {} rv1126'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # Set model config print('--> Config model') - rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], - reorder_channel='0 1 2', batch_size=16) + rknn.config(mean_values=[[127.5, 127.5, 127.5]], + std_values=[[127.5, 127.5, 127.5]], + reorder_channel='0 1 2', + batch_size=16, + target_platform=[target]) print('done') # Hybrid quantization step2 @@ -19,6 +38,7 @@ dataset='./dataset.txt') if ret != 0: print('hybrid_quantization_step2 failed!') + rknn.release() exit(ret) print('done') @@ -27,6 +47,7 @@ ret = rknn.export_rknn('./ssd_mobilenet_v2.rknn') if ret != 0: print('Export RKNN model failed!') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step3.py b/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step3.py index 3a99848..a24ddf8 100644 --- a/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step3.py +++ b/examples/common_function_demos/hybrid_quantization/ssd_mobilenet_v2/step3.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -166,13 +168,32 @@ def ssd_post_process(conf_data, loc_data, imgpath, output_dir='.'): draw.rectangle([(x1, text_bottom - text_height - 2 * margin), (x1 + text_width, text_bottom)], fill=color) draw.text((x1 + margin, text_bottom - text_height - margin), display_str, fill='black', font=font) - print('write output image: {}{}_quant.jpg'.format(output_dir, name)) np.copyto(img, np.array(img_pil)) cv2.imwrite("{}{}_quant.jpg".format(output_dir, name), img) - print('write output image finished.') + print('Saved detection results to {}{}_quant.jpg'.format(output_dir, name)) if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() @@ -181,6 +202,7 @@ def ssd_post_process(conf_data, loc_data, imgpath, output_dir='.'): ret = rknn.load_rknn('./ssd_mobilenet_v2.rknn') if ret != 0: print('Load RKNN model failed') + rknn.release() exit(ret) print('done') @@ -190,15 +212,17 @@ def ssd_post_process(conf_data, loc_data, imgpath, output_dir='.'): # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') # Inference print('--> Running model') outputs = rknn.inference(inputs=[img]) + # Post process ssd_post_process(np.reshape(outputs[0], (-1)), np.reshape(outputs[1], (-1)), './dog_bike_car_300x300.jpg', './') print('done') diff --git a/examples/common_function_demos/load_quantized_model/onnx/README.md b/examples/common_function_demos/load_quantized_model/onnx/README.md index a3fe729..f616e3a 100644 --- a/examples/common_function_demos/load_quantized_model/onnx/README.md +++ b/examples/common_function_demos/load_quantized_model/onnx/README.md @@ -1,5 +1,68 @@ -注意: +# Example for quantized ONNX shufflenet-v2 -1. 该demo中的shufflenet-v2_quant.onnx 模型由 onnxruntime_v1.5.1 量化生成,目前以 onnxruntime_v1.5.1的支持为准,更高版本生成的onnx量化模型有可能无法被正常加载转为RKNN模型。 +## Model Source +Shufflenet-v2_quant.onnx was generated with onnxruntime_v1.5.1 version via the "onnxruntime_quant_e2e_user_example.py" script. +The original float model is available at [https://github.com/onnx/models/tree/main/vision/classification/shufflenet](https://github.com/onnx/models/tree/main/vision/classification/shufflenet) named ShuffleNet-v2-fp32. + +The quantization script was based on [https://github.com/microsoft/onnxruntime/blob/rel-1.5.1/onnxruntime/python/tools/quantization/E2E_example_model/e2e_user_example.py](https://github.com/microsoft/onnxruntime/blob/rel-1.5.1/onnxruntime/python/tools/quantization/E2E_example_model/e2e_user_example.py) We adjusted some std/mean value settings and included the script in this demo. + +Note: + +- The quantized ONNX model was generated using onnxruntime_v1.5.1. Using other versions of onnxruntime may result in errors in the demo. +- [https://github.com/onnx/models/tree/main/vision/classification/shufflenet](https://github.com/onnx/models/tree/main/vision/classification/shufflenet) has already provide quantized shufflenet. It's per-channel quantized, which is not support due to hardware limitation. + + + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +--> Running rknn model +shufflenet +-----TOP 5----- +[155]: 0.9880157113075256 +[154]: 0.010230629704892635 +[364]: 0.00030893823713995516 +[960]: 0.00017329865659121424 +[879]: 0.00013287267938721925 + +--> Running onnx model +shufflenet +-----TOP 5----- +[155]: 0.9878916144371033 +[154]: 0.009037788026034832 +[960]: 0.0005273366696201265 +[879]: 0.0002684167993720621 +[364]: 0.00025560680660419166 +``` + +1. The label index with the highest score is 155, the corresponding label is `Pekinese, Pekingese, Peke`. +2. The download link for labels file: https://s3.amazonaws.com/onnx-model-zoo/synset.txt +3. Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/examples/common_function_demos/load_quantized_model/onnx/onnxruntime_quant_e2e_user_example.py b/examples/common_function_demos/load_quantized_model/onnx/onnxruntime_quant_e2e_user_example.py new file mode 100644 index 0000000..724f616 --- /dev/null +++ b/examples/common_function_demos/load_quantized_model/onnx/onnxruntime_quant_e2e_user_example.py @@ -0,0 +1,76 @@ +import os +import sys +import numpy as np +import re +import abc +import subprocess +import json +from PIL import Image + +import onnx +import onnxruntime +from onnx import helper, TensorProto, numpy_helper +from onnxruntime.quantization import quantize_static, calibrate, CalibrationDataReader + + +class DataReader(CalibrationDataReader): + def __init__(self, calibration_image_folder, augmented_model_path='augmented_model.onnx'): + self.image_folder = calibration_image_folder + self.augmented_model_path = augmented_model_path + self.preprocess_flag = True + self.enum_data_dicts = [] + self.datasize = 0 + + def get_next(self): + if self.preprocess_flag: + self.preprocess_flag = False + session = onnxruntime.InferenceSession(self.augmented_model_path, None) + (_, _, height, width,) = session.get_inputs()[0].shape + nhwc_data_list = preprocess_func(self.image_folder, height, width, size_limit=0) + input_name = session.get_inputs()[0].name + self.datasize = len(nhwc_data_list) + self.enum_data_dicts = iter([{input_name: nhwc_data_list[i]} for i in range(self.datasize)]) + return next(self.enum_data_dicts, None) + + +def preprocess_func(images_folder, height, width, size_limit=0): + ''' + Loads a batch of images and preprocess them + parameter images_folder: path to folder storing images + parameter height: image height in pixels + parameter width: image width in pixels + parameter size_limit: number of images to load. Default is 0 which means all images are picked. + return: list of matrices characterizing multiple images + ''' + image_names = os.listdir(images_folder) + if size_limit > 0 and len(image_names) >= size_limit: + batch_filenames = [image_names[i] for i in range(size_limit)] + else: + batch_filenames = image_names + unconcatenated_batch_data = [] + + for image_name in batch_filenames: + image_filepath = images_folder + '/' + image_name + pillow_img = Image.new("RGB", (width, height)) + pillow_img.paste(Image.open(image_filepath).resize((width, height))) + input_data = np.float32(pillow_img) - \ + np.array([123.68, 116.78, 103.94], dtype=np.float32) + input_data = input_data/58.82 + nhwc_data = np.expand_dims(input_data, axis=0) + nchw_data = np.transpose(nhwc_data, (0, 3, 1, 2)) + unconcatenated_batch_data.append(nchw_data) + batch_data = np.concatenate(np.expand_dims(unconcatenated_batch_data, axis=0), axis=0) + return batch_data + + +def main(): + input_model_path = './shufflenet-v2-12.onnx' + output_model_path = './shufflenet-v2_quant.onnx' + calibration_dataset_path = './test_images' + dr = DataReader(calibration_dataset_path) + quantize_static(input_model_path, output_model_path, dr) + print('Calibrated and quantized model saved.') + + +if __name__ == '__main__': + main() diff --git a/examples/common_function_demos/load_quantized_model/onnx/shufflenet-v2_quant.onnx b/examples/common_function_demos/load_quantized_model/onnx/shufflenet-v2_quant.onnx index c547123..032b63c 100644 Binary files a/examples/common_function_demos/load_quantized_model/onnx/shufflenet-v2_quant.onnx and b/examples/common_function_demos/load_quantized_model/onnx/shufflenet-v2_quant.onnx differ diff --git a/examples/common_function_demos/load_quantized_model/onnx/test.py b/examples/common_function_demos/load_quantized_model/onnx/test.py index ffe8196..335e3a0 100644 --- a/examples/common_function_demos/load_quantized_model/onnx/test.py +++ b/examples/common_function_demos/load_quantized_model/onnx/test.py @@ -1,13 +1,13 @@ -import os -import time +import platform import sys +import os import numpy as np import cv2 from rknn.api import RKNN ONNX_MODEL = 'shufflenet-v2_quant.onnx' -IMG_PATH = 'dog_224x224.jpg' +IMG_PATH = './test_images/dog_224x224.jpg' RKNN_MODEL = './shufflenet-v2_quant.rknn' @@ -43,25 +43,30 @@ def readable_speed(speed): return "{:.2f} KB/s".format(speed_kbytes) -def show_progress(blocknum, blocksize, totalsize): - speed = (blocknum * blocksize) / (time.time() - start_time) - speed_str = " Speed: {}".format(readable_speed(speed)) - recv_size = blocknum * blocksize - - f = sys.stdout - progress = (recv_size / totalsize) - progress_str = "{:.2f}%".format(progress * 100) - n = round(progress * 50) - s = ('#' * n).ljust(50, '-') - f.write(progress_str.ljust(8, ' ') + '[' + s + ']' + speed_str) - f.flush() - f.write('\r\n') - - if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object - rknn = RKNN(verbose=False, verbose_file='./verbose_log.txt') + rknn = RKNN(verbose=False) if not os.path.exists(ONNX_MODEL): print('no model exist') @@ -75,6 +80,7 @@ def show_progress(blocknum, blocksize, totalsize): optimization_level=3, quantize_input_node=True, merge_dequant_layer_and_output_node=True, + target_platform=[target] ) print('done') @@ -83,6 +89,7 @@ def show_progress(blocknum, blocksize, totalsize): ret = rknn.load_onnx(model=ONNX_MODEL) if ret != 0: print('Load shufflenet failed!') + rknn.release() exit(ret) print('done') @@ -91,6 +98,7 @@ def show_progress(blocknum, blocksize, totalsize): ret = rknn.build(do_quantization=False, dataset='dataset.txt') if ret != 0: print('Build shufflenet failed!') + rknn.release() exit(ret) print('done') @@ -101,21 +109,24 @@ def show_progress(blocknum, blocksize, totalsize): ret = rknn.export_rknn(RKNN_MODEL) if ret != 0: print('Export shufflenet.rknn failed!') + rknn.release() exit(ret) print('done') - # Set inputs img = cv2.imread(IMG_PATH) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) - # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime(target='rk1808', device_id='1808') - # ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/load_quantized_model/onnx/dog_224x224.jpg b/examples/common_function_demos/load_quantized_model/onnx/test_images/dog_224x224.jpg similarity index 100% rename from examples/common_function_demos/load_quantized_model/onnx/dog_224x224.jpg rename to examples/common_function_demos/load_quantized_model/onnx/test_images/dog_224x224.jpg diff --git a/examples/common_function_demos/load_quantized_model/pytorch/README.md b/examples/common_function_demos/load_quantized_model/pytorch/README.md index d233da6..805317b 100644 --- a/examples/common_function_demos/load_quantized_model/pytorch/README.md +++ b/examples/common_function_demos/load_quantized_model/pytorch/README.md @@ -1,21 +1,87 @@ -注意: +# Example for loading quantized Pytorch model - Mobilenet_v2_quant -1. 使用该demo需要将依赖的PyTorch升级到1.9.0版本。 +## Require -2. Demo的结果看起来RKNN与PyTorch的计算结果有不小的偏差。经测试,在imagenet的子集1000张图上RKNN模型的得分更高,具体数值如下: +Pytorch == 1.9.x or 1.10.x -| 模型 | Top1精度(imagenet-1000) | -| -------------------------------------------------- | ------------------------- | -| RKNN_mobilenet_v2_i8(from_quantized_pytorch_model) | 70.0% | -| PyTorch_mobilenet_v2_i8 | 61.5% | -​ 造成这个的原因可能是PyTorch本身的量化推理实现有误差,目前他们也在持续完善模型量化功能。 -3. 由于底层驱动原因,RKNN-Toolkit1 目前只支持per_tensor量化,对应 PyTorch的 qnnpack 量化模式。如果选择 per_channel量化,也即 PyTorch的 fbgemm 量化模式,最终将无法转为RKNN模型,请用户多加留意! +## Model Source -4. 相比载入浮点模型,rknn.config里面额外将 quantize_input_node 和 merge_dequant_layer_and_output_node 参数均设为 True,前者开启后会合并输入节点与quantize_layer,后者开启后会合并输出节点与dequantize_layer,这样会使得模型在部署的时候性能及特性可以与普通RKNN量化模型保持一致。具体请参考用户手册里面的7.2章节。 +The model comes from https://pytorch.org/vision/stable/models/generated/torchvision.models.quantization.mobilenet_v2.html#torchvision.models.quantization.MobileNet_V2_QuantizedWeights. -5. 该demo在 macos 上存在异常,异常原因为pytorch依赖库异常,解析模型出错。异常复现代码: + + +## Usage for the script + +*Usage:* + +``` +python test.py [target] [device_id] +``` + +*Parameter Description:* + +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: + +``` +python test.py +``` + +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: + +``` +python test.py rk1808 +``` + +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: + +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: + +``` +rk_result: +-----TOP 5----- +[155]: 0.6007367372512817 +[154]: 0.17650733888149261 +[204]: 0.08209411054849625 +[283]: 0.028111280873417854 +[187]: 0.009626070968806744 + +pt_result: +-----TOP 5----- +[155]: 0.5076675415039062 +[154]: 0.32070720195770264 +[204]: 0.03760503977537155 +[283]: 0.027686361223459244 +[284]: 0.015007374808192253 +``` + +1. The label index with the highest score is 155, the corresponding label is `Pekinese, Pekingese, Peke`. +2. It's obvious that RKNN and Pytorch inference results are not close. We had test this RKNN model and got 70.0 acc@1(on ImagedNet-1K), which is close to 71.6 refer to torchvision document. +3. Different platforms, different versions of tools and drivers may have slightly different results. + + +## NOTICE + +1. The optimization strategy can affect the inference results of the RKNN model, and this effect will be more obvious when loading the QAT model. If the inference results of the RKNN model and the QAT model are inconsistent, you can try to set the configuration parameter **optimization_level** of **rknn.config** to 2. But lower optimization_level may slower inference speed. + +2. Attention! Due to the hardware limited, RKNN-Toolkit1 currently only supports **per_tensor** quantization, corresponding to PyTorch's **qnnpack** quantization mode. If you choose **per_channel** quantization, that is, **PyTorch's fbgemm quantization mode, it will not be able to convert to RKNN model in the end.** + +3. Compared with loading the floating-point model, rknn.config additionally sets the **quantize_input_node** and **merge_dequant_layer_and_output_node** parameters to **True**. After the former is enabled, the input node and quantize_layer will be merged, and the latter will be merged with the output node and dequantize_layer. This will make the performance and characteristics of the model when deployed consistent with the normal RKNN quantization model. For details, please refer to chapter 7.2 in the user guide. + +4. **While using QAT model to convert RKNN model, it's recommended to test on dataset instead of single data.** + +5. This demo may error on **macos**. The reason for the error is that the native function of pytorch is abnormal and the parsing model is wrong. Abnormal reproduction code: ``` list(torch.jit.load('QAT_model_path.pt').graph.nodes()) diff --git a/examples/common_function_demos/load_quantized_model/pytorch/test.py b/examples/common_function_demos/load_quantized_model/pytorch/test.py index 893dac8..97010ce 100644 --- a/examples/common_function_demos/load_quantized_model/pytorch/test.py +++ b/examples/common_function_demos/load_quantized_model/pytorch/test.py @@ -1,7 +1,8 @@ +import platform +import sys import torch import cv2 import numpy as np -import tensorflow from rknn.api import RKNN import torchvision @@ -60,13 +61,38 @@ def main(): print('*'*20) prepare_model() + + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + rknn = RKNN(verbose=False, verbose_file='./verbose_log.txt') # pre-process config print('--> Set config model') - rknn.config(quantize_input_node=True, + rknn.config( + quantize_input_node=True, merge_dequant_layer_and_output_node=True, - ) + target_platform=[target], + optimization_level=3, + ) print('done') # Load Pytorch model @@ -74,6 +100,7 @@ def main(): ret = rknn.load_pytorch(model=model_path, input_size_list=[[3, 224, 224]]) if ret != 0: print('Load Pytorch model failed!') + rknn.release() exit(ret) print('done') @@ -82,6 +109,7 @@ def main(): ret = rknn.build(do_quantization=False, dataset='dataset.txt') if ret != 0: print('Build model failed!') + rknn.release() exit(ret) print('done') @@ -90,16 +118,21 @@ def main(): ret = rknn.export_rknn('quantized_mobilenet.rknn') if ret != 0: print('Export quantized_mobilenet.rknn failed!') + rknn.release() exit(ret) print('done') # Init runtime environment print('--> Init runtime environment') - # ret = rknn.init_runtime() - ret = rknn.init_runtime(target='rk1808', device_id='1808') + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') @@ -117,7 +150,7 @@ def main(): #! NOTE: # rknn_model got 70.0 accuracy on imagenet_1000 # pt_i8 got 61.5 accuracy on imagenet_1000 - # pt_float got 61.2 accuracy on imagenet_1000 + # pt_i8 got 71.658 accuracy refer to torchvsion discription rknn.release() torch.backends.quantized.engine = 'qnnpack' diff --git a/examples/common_function_demos/load_quantized_model/tensorflow/README.md b/examples/common_function_demos/load_quantized_model/tensorflow/README.md index 398fada..6ff070b 100644 --- a/examples/common_function_demos/load_quantized_model/tensorflow/README.md +++ b/examples/common_function_demos/load_quantized_model/tensorflow/README.md @@ -1,3 +1,46 @@ -This demo shows how to load a quantized model. -Download address of inception_v3_quant_frozen.pb: +# Example for quantized TensorFlow inception_v3_quant + + +## Model Source +The model used in this example come from the TensorFlow model zoo, the download link: https://storage.googleapis.com/download.tensorflow.org/models/tflite_11_05_08/inception_v3_quant.tgz + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +[2]: 0.9897317290306091 +[408]: 0.0009118635789491236 +[795]: 0.0006728958687745035 +[974]: 0.00015886672190390527 +[352]: 0.00014724396169185638 +``` + +1. The label index with the highest score is 2, the corresponding label is `goldfish, Carassius auratus`. +2. The labels used in this model contains background, download link of labels file: https://github.com/leferrad/tensorflow-mobilenet/blob/master/imagenet/labels.txt +4. Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/examples/common_function_demos/load_quantized_model/tensorflow/test.py b/examples/common_function_demos/load_quantized_model/tensorflow/test.py index 1b41751..daf4211 100644 --- a/examples/common_function_demos/load_quantized_model/tensorflow/test.py +++ b/examples/common_function_demos/load_quantized_model/tensorflow/test.py @@ -1,3 +1,4 @@ +import platform import numpy as np import cv2 import os @@ -7,7 +8,6 @@ import traceback import time import sys -import argparse from rknn.api import RKNN PB_FILE = './inception_v3_quant_frozen.pb' @@ -64,23 +64,26 @@ def show_progress(blocknum, blocksize, totalsize): f.write('\r\n') if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument("--target", - type=str, - default='rk1808', - help="Hardware platform, current we support: rk1808, rk3399pro, rk1109, default is None") - parser.add_argument("--device-id", - type=str, - default=None, - help="Device id, when we have multi devices connected, id need be pointed.") - args = parser.parse_args() - target = args.target - device_id = args.device_id - - if target is None: - target_platform = 'rk1808' - else: - target_platform = target + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN(verbose=False) @@ -120,7 +123,7 @@ def show_progress(blocknum, blocksize, totalsize): # pre-process config print('--> Config model') rknn.config(reorder_channel='0 1 2', - target_platform=target_platform, + target_platform=[target], mean_values=[[127.5, 127.5, 127.5]], std_values=[[128, 128, 128]]) print('done') @@ -131,10 +134,10 @@ def show_progress(blocknum, blocksize, totalsize): inputs=INPUTS, outputs=OUTPUTS, input_size_list=[[INPUT_SIZE, INPUT_SIZE, 3]], - predef_file=None, - ) + predef_file=None) if ret != 0: print('Load inception_v3_quant_frozen failed!') + rknn.release() exit(ret) print('done') @@ -143,6 +146,7 @@ def show_progress(blocknum, blocksize, totalsize): ret = rknn.build(do_quantization=False) if ret != 0: print('Build inception_v3_quant_frozen.rknn failed!') + rknn.release() exit(ret) print('done') @@ -151,6 +155,7 @@ def show_progress(blocknum, blocksize, totalsize): ret = rknn.export_rknn(RKNN_MODEL_PATH) if ret != 0: print('Export inception_v3_quant_frozen.rknn failed!') + rknn.release() exit(ret) print('done') @@ -160,10 +165,14 @@ def show_progress(blocknum, blocksize, totalsize): # init runtime environment print('--> Init runtime environment') + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None ret = rknn.init_runtime(target=target, device_id=device_id) - # ret = rknn.init_runtime() if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') @@ -176,10 +185,5 @@ def show_progress(blocknum, blocksize, totalsize): show_outputs(outputs) print('done') - # perf - print('--> Begin evaluate model performance') - perf_results = rknn.eval_perf(inputs=[img]) - print('done') - rknn.release() diff --git a/examples/common_function_demos/load_quantized_model/tflite/README.md b/examples/common_function_demos/load_quantized_model/tflite/README.md new file mode 100644 index 0000000..5be6852 --- /dev/null +++ b/examples/common_function_demos/load_quantized_model/tflite/README.md @@ -0,0 +1,47 @@ +# Example for quantized tflite inception_v1_224_quant + + +## Model Source +The model used in this example come from coral's model https://raw.githubusercontent.com/google-coral/test_data/master/inception_v1_224_quant.tflite + + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +-----TOP 5----- +[156]: 0.84765625 +[155 205]: 0.0625 +[155 205]: 0.0625 +[154 284]: 0.00390625 +[154 284]: 0.00390625 +``` +1. The label index with the highest score is 156, the corresponding label is `Pekinese, Pekingese, Peke`. +2. The labels used in this model contains background, download link of labels file: https://github.com/leferrad/tensorflow-mobilenet/blob/master/imagenet/labels.txt +4. Different platforms, different versions of tools and drivers may have slightly different results. \ No newline at end of file diff --git a/examples/common_function_demos/load_quantized_model/tflite/inception_v1_224_quant.tflite b/examples/common_function_demos/load_quantized_model/tflite/inception_v1_224_quant.tflite index 54efd70..088ffa5 100644 Binary files a/examples/common_function_demos/load_quantized_model/tflite/inception_v1_224_quant.tflite and b/examples/common_function_demos/load_quantized_model/tflite/inception_v1_224_quant.tflite differ diff --git a/examples/common_function_demos/load_quantized_model/tflite/test.py b/examples/common_function_demos/load_quantized_model/tflite/test.py index 06f31c1..15778c6 100644 --- a/examples/common_function_demos/load_quantized_model/tflite/test.py +++ b/examples/common_function_demos/load_quantized_model/tflite/test.py @@ -1,14 +1,13 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN -import os - -# os.environ['NN_LAYER_DUMP'] = '1' def show_outputs(outputs): output = outputs[0][0] output_sorted = sorted(output, reverse=True) - top5_str = 'mobilenet_v1\n-----TOP 5-----\n' + top5_str = 'inception_v1\n-----TOP 5-----\n' for i in range(5): value = output_sorted[i] index = np.where(output == value) @@ -24,20 +23,44 @@ def show_outputs(outputs): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # pre-process config print('--> config model') - rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], reorder_channel='0 1 2') + rknn.config(mean_values=[[127.5, 127.5, 127.5]], + std_values=[[127.5, 127.5, 127.5]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load TFLite model print('--> Loading model') ret = rknn.load_tflite(model='./inception_v1_224_quant.tflite') if ret != 0: - print('Load mobilenet_v1 failed!') + print('Load inception_v1 failed!') + rknn.release() exit(ret) print('done') @@ -45,15 +68,17 @@ def show_outputs(outputs): print('--> Building model') ret = rknn.build(do_quantization=False, dataset='./dataset.txt', pre_compile=False) if ret != 0: - print('Build mobilenet_v1 failed!') + print('Build inception_v1 failed!') + rknn.release() exit(ret) print('done') # Export RKNN model print('--> Export RKNN model') - ret = rknn.export_rknn('./mobilenet_v1.rknn') + ret = rknn.export_rknn('./inception_v1.rknn') if ret != 0: - print('Export mobilenet_v1.rknn failed!') + print('Export inception_v1.rknn failed!') + rknn.release() exit(ret) print('done') @@ -63,9 +88,14 @@ def show_outputs(outputs): # Init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime(target='rk1808', device_id='1808') + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/model_pruning/README.md b/examples/common_function_demos/model_pruning/README.md new file mode 100644 index 0000000..7e6b626 --- /dev/null +++ b/examples/common_function_demos/model_pruning/README.md @@ -0,0 +1,52 @@ +# Example for model pruning + +1. Currently RKNN-Toolkit1 supports **structured pruning**. Assuming that there is a 4D tensor in the model calculation process, and its shape information is NCHW, if there are some values on the C (channel) that are all zero, this part can be eliminated to avoid invalid operations. In most cases, convolutions and their context-dependent network layers are relatively easy to trigger this pruning effect. If you want to achieve the effect of structured pruning on the real model, you need to make some adjustments to the training code. For more pruning-related introductions, you can refer to Pytorch tutorial https://pytorch.org/tutorials/intermediate/pruning_tutorial.html . +2. This demo builds a simple network layer and uses **torch.nn.utils.prune.ln_structured** for structured pruning. When converting the model, set **model_pruning=True** in **rknn.config** to enable it. +3. Please note that the pruning function is currently in the experimental stage. If you encounter any problems, you can contact the Rockchips-AI-Teams for feedback through https://github.com/rockchip-linux/rknn-toolkit. Thank you for your support. + + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + + +## Expected results + +The pruning log will show as follow(order may changed) +``` +I Pruning: const change detail +const name src_size pruned_size diff +@convolution_at_input.3_1_1:bias 256 192 -64 +@convolution_at_input.7_4_4:weight 16384 9024 -7360 +@convolution_at_input.2_7_7:weight 65536 48128 -17408 +@convolution_at_input.7_4_4:bias 256 188 -68 +@convolution_at_input.3_1_1:weight 6912 5184 -1728 +``` + +And the cosine similarity between RKNN and Pytorch model inference result will show like: + +``` +cos sim: 0.9999999 +``` + diff --git a/examples/common_function_demos/model_pruning/gen_conv_and_convert_with_pruning.py b/examples/common_function_demos/model_pruning/gen_conv_and_convert_with_pruning.py new file mode 100644 index 0000000..e681ebd --- /dev/null +++ b/examples/common_function_demos/model_pruning/gen_conv_and_convert_with_pruning.py @@ -0,0 +1,121 @@ +import platform +import platform +import sys +import torch +import random +from rknn.api import RKNN +from torch.nn.utils import prune +torch.manual_seed(1024) + +class ConvBlock(torch.nn.Module): + def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, bias=True): + super(ConvBlock, self).__init__() + self.conv = torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, dilation, groups=1, bias=bias) + self.bn = torch.nn.BatchNorm2d(out_channels) + self.relu = torch.nn.ReLU(inplace=True) + + def forward(self, x): + x = self.conv(x) + x = self.bn(x) + x = self.relu(x) + return x + + +class Multi_Conv(torch.nn.Module): + def __init__(self) -> None: + super().__init__() + self.conv1 = ConvBlock(3, 64, 3, 1, 1) + self.conv2 = ConvBlock(64, 64, 1, 1, 1) + self.conv3 = ConvBlock(64, 64, 2, 1, 1) + + def forward(self, x): + x = self.conv1(x) + x = self.conv2(x) + x = self.conv3(x) + return x + + +if __name__ == '__main__': + + # Generate pt model used to test + model = Multi_Conv() + for m in model.modules(): + if isinstance(m, torch.nn.Conv2d): + prune.ln_structured(m, name="weight", amount=0.5, n=2, dim=0) + prune.remove(m, 'weight') + model.eval() + fake_in = torch.randn(1, 3, 224, 224) + jt_model = torch.jit.trace(model, fake_in) + torch.jit.save(jt_model, 'Multi_Conv.pt') + + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + + rknn = RKNN(verbose=True) + + rknn.config(model_pruning=True, target_platform=[target]) + + print('--> Load pytorch model') + ret = rknn.load_pytorch(model='Multi_Conv.pt', input_size_list=[[3,224,224]]) + if ret != 0: + print("Load pytorch model failed.") + rknn.release() + exit(ret) + print('done') + + print('--> Building model') + ret = rknn.build(do_quantization=False, dataset='dataset.txt') + if ret != 0: + print("Build RKNN model failed.") + rknn.release() + exit(ret) + + print('--> Export RKNN model') + ret = rknn.export_rknn('Multi_Conv_pruning.rknn') + if ret != 0: + print("Export RKNN model failed.") + rknn.release() + exit(ret) + + # Inference with PyTorch + pt_output = model(fake_in) + + # Init RKNN runtime. + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) + if ret != 0: + print('Init runtime failed.') + rknn.release() + exit(ret) + + # Inference with RKNN + rknn_input = fake_in.numpy().transpose(0,2,3,1) # nchw -> nhwc + rknn_output = rknn.inference([rknn_input]) + + # Compare the inference results of PyTorch and RKNN. + cos_sim = torch.cosine_similarity(pt_output.reshape(1, -1), torch.tensor(rknn_output[0]).reshape(1, -1)) + print("cos sim:", cos_sim[0].detach().numpy()) + + rknn.release() + diff --git a/examples/common_function_demos/pass_through/README.md b/examples/common_function_demos/pass_through/README.md index 64e1713..17e3d0a 100644 --- a/examples/common_function_demos/pass_through/README.md +++ b/examples/common_function_demos/pass_through/README.md @@ -1,15 +1,39 @@ -# Usage of pass_through demo -## Default usage -execute comand below to run this demo, pass original data to NPU, NPU will do pre-process for input. +# Example of passing through input data + + +## Model Source +The model used in this example come from the miai-models project, download link: +https://cnbj1.fds.api.xiaomi.com/mace/miai-models/deeplab-v3-plus/deeplab-v3-plus-mobilenet-v2.pb + + +## Usage for the script + +*Usage:* ``` -python3 test.py -``` -## Pass through input -execute command below to run this demo, pass input data to NPU directly, NPU will not do pre-process again. +python test.py [pass-through] [use-rknn] [target] [device-id] ``` -python3 test.py --pass-through +*Parameter Description:* +- pass-through: whether to pass through input data. Optional parameter, the default value is `True`. If set to `1`, pass through input data, other value, pass-through will set to `False`. +- use-rknn: whether to use RKNN model directly. Optional paramter, the default value is `False`. If set to `1`, the script will load RKNN model directly, If the RKNN model does not exist, the script will throw an error and exit. +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: ``` -If this demo has been run, you can add the --load-rknn parameter to avoid model conversion again. +python test.py ``` -python3 test.py --pass-through --load-rknn +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: ``` +python test.py 1 0 rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py 1 0 rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +The test result should be similar to picutre `ref_seg_results.jpg`. + +*Note: Different platforms, different versions of tools and drivers may have slightly different results.* diff --git a/examples/common_function_demos/pass_through/test.py b/examples/common_function_demos/pass_through/test.py index 3fb7b9b..39a2c33 100644 --- a/examples/common_function_demos/pass_through/test.py +++ b/examples/common_function_demos/pass_through/test.py @@ -9,6 +9,7 @@ import time import urllib import traceback +import platform from rknn.api import RKNN @@ -117,21 +118,43 @@ def deeplabv3_post_process(img, inference_result): vis_segmentation(resized_im, seg_map) if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument("--pass-through", - dest='pass_through', - action='store_true', - help='Whether pass through input data to RKNN model.') - parser.add_argument('--load-rknn', - dest='load_rknn', - action='store_true', - help='Whether load RKNN model directly.') - args = parser.parse_args() - - pass_through = args.pass_through - - LOAD_RKNN = args.load_rknn + if len(sys.argv) not in [1, 2, 3, 4, 5]: + print('Usage: python {} [pass_through] [use_rknn] [target] [device_id]'.format( + sys.argv[0])) + print(' pass_through: 0 or 1, 0 means runtime need do preprocess, otherwise pass thourgh input data to RKNN model.') + print(' use_rknn: 0 or 1. If set to 0, need to do model conversion; otherwise, using RKNN model directly.') + print('Such as: python {} 1 0 rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + + pass_through = True + use_rknn = False + + # default target and device_id + target = 'rv1126' + device_id = None + + if len(sys.argv) == 1: + print('Use default target: {}. Need to do model conversion. Pass through input data to RKNN model.') + elif len(sys.argv) == 2: + pass_through = True if sys.argv[1] == '1' else False + print('Use default target: {}. Need to do model conversion. Pass through input data to RKNN model.') + elif len(sys.argv) == 3: + pass_through = True if sys.argv[1] == '1' else False + use_rknn = True if sys.argv[2] == '1' else False + print('Use default target: {}.'.format(target)) + elif len(sys.argv) == 4: + pass_through = True if sys.argv[1] == '1' else False + use_rknn = True if sys.argv[2] == '1' else False + target = sys.argv[3] + elif len(sys.argv) == 5: + pass_through = True if sys.argv[1] == '1' else False + use_rknn = True if sys.argv[2] == '1' else False + target = sys.argv[3] + device_id = sys.argv[4] + PB_MODEL = './deeplab-v3-plus-mobilenet-v2.pb' + RKNN_MODEL = './deeplab-v3-plus-mobilenet-v2.rknn' # Create RKNN object rknn = RKNN() @@ -148,7 +171,13 @@ def deeplabv3_post_process(img, inference_result): print(traceback.format_exc()) print('done') - if not LOAD_RKNN: + if not use_rknn: + # set config refer to pass_througn value. + rknn.config(mean_values=[[127.5, 127.5, 127.5]], + std_values=[[127.5, 127.5, 127.5]], + reorder_channel='0 1 2', + target_platform=[target]) + # Load tensorflow model print('--> Loading model') ret = rknn.load_tensorflow(tf_pb=PB_MODEL, @@ -157,38 +186,46 @@ def deeplabv3_post_process(img, inference_result): input_size_list=[[513, 513, 3]]) if ret != 0: print('load_tensorflow failed') + rknn.release() exit(ret) print('done') - # set config refer to pass_througn value. - rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], reorder_channel='0 1 2') - # Build model print('--> Building model') ret = rknn.build(do_quantization=True, dataset='./dataset.txt', pre_compile=False) if ret != 0: print('build rknn model failed') + rknn.release() exit(ret) print('done') # Export rknn model - ret = rknn.export_rknn('./deeplab-v3-plus-mobilenet-v2.rknn') + print('--> Export RKNN model') + ret = rknn.export_rknn(RKNN_MODEL) if ret != 0: print('export rknn model failed') + rknn.release() exit(ret) print('done') else: print('--> Load model') - ret = rknn.load_rknn(path='./deeplab-v3-plus-mobilenet-v2.rknn') + ret = rknn.load_rknn(RKNN_MODEL) if ret < 0: print('load model failed.') + rknn.release() + exit(ret) print('done') # init runtime print('--> init runtime') - ret = rknn.init_runtime(target='rk1808', device_id='1808') + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret < 0: print('init runtime failed') + rknn.release() exit(ret) print('done') diff --git a/examples/common_function_demos/single_channel_input/mnist/README.md b/examples/common_function_demos/single_channel_input/mnist/README.md index 828a4eb..dd4f27b 100644 --- a/examples/common_function_demos/single_channel_input/mnist/README.md +++ b/examples/common_function_demos/single_channel_input/mnist/README.md @@ -1,16 +1,68 @@ -## 单通道输入Demo +# Single channel input demo -1. 当模型的输入是单通道,即channel维度为1时,建议用户将所有量化数据集预先处理成npy格式保存。这样可以避免在读取灰度图时,因为代码实现上的差异而引起量化误差。 +## Model Source - Demo中的处理方式如下: +The mnist_cnn.pt model is trained based on pytorch example https://github.com/pytorch/examples/blob/main/mnist/main.py . Notice that the inference result could be different if training on different pytorch versions. - ```python - img = cv2.imread(jpg_data_path) - gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - gray_img = gray_img.reshape(28, 28, 1) # hw --> hwc, this is important, don't miss it - np.save(npy_data_path, gray_img) - ``` -2. 请注意,如果模型的原始输入是nchw格式的,而灰度图的没有channel维度、尺寸为 hw时,我们需要额外添加channel维度,如上文的代码中第三句代码的处理方式。 -3. 当模型的原始输入是3维度或2维的情况时,RKNN模型在量化、推理时候则不会对输入进行 hwc -> chw 的转换操作,此时无需对灰度图补充 channel 维度,数据依照原格式保存成 npy 文件即可。 \ No newline at end of file +## Usage for the script + +*Usage:* + +``` +python test.py [target] [device_id] +``` + +*Parameter Description:* + +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: + +``` +python test.py +``` + +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: + +``` +python test.py rk1808 +``` + +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example:: + +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + + +## Expected results + +The example would print the predicted digit and corresponding scores as follows: + +``` +--> RKNN result + The digit number is 1, with predicted confidence as 1.0 +(Due to different RKNN versions, confidence may be close but not the same, such as 0.9999) +--> PT result + The digit number is 1, with predicted confidence as 1.0 +``` + + + +## Notice + +If npy file is used for quantization, the npy data shape should be like **hwc** instead of **hw**. In test.py, it's done as follows code: + +``` +def prepare_data(jpg_data_path, npy_data_path, dataset_path): + img = cv2.imread(jpg_data_path) + gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + gray_img = gray_img.reshape(28, 28, 1) # hw --> hwc, this is important, don't miss it + np.save(npy_data_path, gray_img) + with open(dataset_path, 'w') as F: + F.write(npy_data_path) +``` \ No newline at end of file diff --git a/examples/common_function_demos/single_channel_input/mnist/fc_net.pt b/examples/common_function_demos/single_channel_input/mnist/fc_net.pt deleted file mode 100644 index 741cb04..0000000 Binary files a/examples/common_function_demos/single_channel_input/mnist/fc_net.pt and /dev/null differ diff --git a/examples/common_function_demos/single_channel_input/mnist/mnist_cnn.pt b/examples/common_function_demos/single_channel_input/mnist/mnist_cnn.pt new file mode 100644 index 0000000..2cad21d Binary files /dev/null and b/examples/common_function_demos/single_channel_input/mnist/mnist_cnn.pt differ diff --git a/examples/common_function_demos/single_channel_input/mnist/test.py b/examples/common_function_demos/single_channel_input/mnist/test.py index e03ac99..15ae4bd 100644 --- a/examples/common_function_demos/single_channel_input/mnist/test.py +++ b/examples/common_function_demos/single_channel_input/mnist/test.py @@ -1,10 +1,12 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN import torch -model = 'fc_net.pt' -rknn_model = 'fc_net.rknn' +model = 'mnist_cnn.pt' +rknn_model = 'mnist_cnn.rknn' input_size_list = [[1, 28, 28]] jpg_data_path = './test.jpg' @@ -13,9 +15,9 @@ def postprocess(input_data): index = input_data.argmax() - print(' The digit number is {}, with predict confident as {}'.format(index, input_data[0,index])) + print(' The digit number is {}, with predicted confidence as {}'.format(index, input_data[0,index])) -def prepace_data(jpg_data_path, npy_data_path, dataset_path): +def prepare_data(jpg_data_path, npy_data_path, dataset_path): img = cv2.imread(jpg_data_path) gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray_img = gray_img.reshape(28, 28, 1) # hw --> hwc, this is important, don't miss it @@ -24,15 +26,38 @@ def prepace_data(jpg_data_path, npy_data_path, dataset_path): F.write(npy_data_path) if __name__ == '__main__': - prepace_data(jpg_data_path, npy_data_path, dataset_path) + # Prepare input data + prepare_data(jpg_data_path, npy_data_path, dataset_path) + + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + # Create RKNN object rknn = RKNN() # pre-process config print('--> Config model') - # rknn.config(target_platform='rv1109') - rknn.config(mean_values=[[0]], - std_values=[[255]]) + rknn.config(mean_values=[[0.1307*255]], + std_values=[[0.3081*255]], + target_platform=[target]) print('done') # Load Pytorch model @@ -40,6 +65,7 @@ def prepace_data(jpg_data_path, npy_data_path, dataset_path): ret = rknn.load_pytorch(model=model, input_size_list=input_size_list) if ret != 0: print('Load Pytorch model failed!') + rknn.release() exit(ret) print('done') @@ -48,6 +74,7 @@ def prepace_data(jpg_data_path, npy_data_path, dataset_path): ret = rknn.build(do_quantization=True, dataset=dataset_path) if ret != 0: print('Build model failed!') + rknn.release() exit(ret) print('done') @@ -56,21 +83,27 @@ def prepace_data(jpg_data_path, npy_data_path, dataset_path): ret = rknn.export_rknn(rknn_model) if ret != 0: print('Export RKNN model failed!') + rknn.release() exit(ret) print('done') # Init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') # Load data input_data = np.load(npy_data_path) - # Inference + # Inference with RKNN print('--> Running model') outputs = rknn.inference(inputs=[input_data]) print('done') @@ -79,10 +112,11 @@ def prepace_data(jpg_data_path, npy_data_path, dataset_path): postprocess(torch.tensor(outputs[0])) rknn.release() + # Inference with PyTorch pt_model = torch.jit.load(model) pt_input_data = input_data.transpose(2,0,1) # hwc -> chw pt_input_data = pt_input_data.reshape(1, *pt_input_data.shape) # chw -> nchw - pt_input_data = pt_input_data/255.0 + pt_input_data = (pt_input_data/255.0 - 0.1307)/0.3081 pt_input_data = torch.tensor(pt_input_data).float() pt_result = pt_model(pt_input_data) print('--> PT result') diff --git a/examples/common_function_demos/single_channel_input/mnist/train.py b/examples/common_function_demos/single_channel_input/mnist/train.py new file mode 100644 index 0000000..371fe60 --- /dev/null +++ b/examples/common_function_demos/single_channel_input/mnist/train.py @@ -0,0 +1,143 @@ +from __future__ import print_function +import argparse +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.optim as optim +from torchvision import datasets, transforms +from torch.optim.lr_scheduler import StepLR + + +class Net(nn.Module): + def __init__(self): + super(Net, self).__init__() + self.conv1 = nn.Conv2d(1, 32, 3, 1) + self.conv2 = nn.Conv2d(32, 64, 3, 1) + self.dropout1 = nn.Dropout(0.25) + self.dropout2 = nn.Dropout(0.5) + self.fc1 = nn.Linear(9216, 128) + self.fc2 = nn.Linear(128, 10) + + def forward(self, x): + x = self.conv1(x) + x = F.relu(x) + x = self.conv2(x) + x = F.relu(x) + x = F.max_pool2d(x, 2) + x = self.dropout1(x) + x = torch.flatten(x, 1) + x = self.fc1(x) + x = F.relu(x) + x = self.dropout2(x) + x = self.fc2(x) + output = F.softmax(x, dim=1) + return output + + +def train(args, model, device, train_loader, optimizer, epoch): + model.train() + for batch_idx, (data, target) in enumerate(train_loader): + data, target = data.to(device), target.to(device) + optimizer.zero_grad() + output = model(data) + loss = F.nll_loss(output, target) + loss.backward() + optimizer.step() + if batch_idx % args.log_interval == 0: + print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( + epoch, batch_idx * len(data), len(train_loader.dataset), + 100. * batch_idx / len(train_loader), loss.item())) + if args.dry_run: + break + + +def test(model, device, test_loader): + model.eval() + test_loss = 0 + correct = 0 + with torch.no_grad(): + for data, target in test_loader: + data, target = data.to(device), target.to(device) + output = model(data) + test_loss += F.nll_loss(output, target, reduction='sum').item() # sum up batch loss + pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability + correct += pred.eq(target.view_as(pred)).sum().item() + + test_loss /= len(test_loader.dataset) + + print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format( + test_loss, correct, len(test_loader.dataset), + 100. * correct / len(test_loader.dataset))) + + +def main(): + # Training settings + parser = argparse.ArgumentParser(description='PyTorch MNIST Example') + parser.add_argument('--batch-size', type=int, default=64, metavar='N', + help='input batch size for training (default: 64)') + parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N', + help='input batch size for testing (default: 1000)') + parser.add_argument('--epochs', type=int, default=3, metavar='N', + help='number of epochs to train (default: 3)') + parser.add_argument('--lr', type=float, default=1.0, metavar='LR', + help='learning rate (default: 1.0)') + parser.add_argument('--gamma', type=float, default=0.7, metavar='M', + help='Learning rate step gamma (default: 0.7)') + parser.add_argument('--no-cuda', action='store_true', default=False, + help='disables CUDA training') + parser.add_argument('--no-mps', action='store_true', default=False, + help='disables macOS GPU training') + parser.add_argument('--dry-run', action='store_true', default=False, + help='quickly check a single pass') + parser.add_argument('--seed', type=int, default=1, metavar='S', + help='random seed (default: 1)') + parser.add_argument('--log-interval', type=int, default=10, metavar='N', + help='how many batches to wait before logging training status') + parser.add_argument('--save-model', action='store_true', default=False, + help='For Saving the current Model') + args = parser.parse_args() + use_cuda = not args.no_cuda and torch.cuda.is_available() + + torch.manual_seed(args.seed) + + if use_cuda: + device = torch.device("cuda") + else: + device = torch.device("cpu") + + train_kwargs = {'batch_size': args.batch_size} + test_kwargs = {'batch_size': args.test_batch_size} + if use_cuda: + cuda_kwargs = {'num_workers': 1, + 'pin_memory': True, + 'shuffle': True} + train_kwargs.update(cuda_kwargs) + test_kwargs.update(cuda_kwargs) + + transform=transforms.Compose([ + transforms.ToTensor(), + transforms.Normalize((0.1307,), (0.3081,)) + ]) + dataset1 = datasets.MNIST('../data', train=True, download=True, + transform=transform) + dataset2 = datasets.MNIST('../data', train=False, + transform=transform) + train_loader = torch.utils.data.DataLoader(dataset1,**train_kwargs) + test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs) + + model = Net().to(device) + optimizer = optim.Adadelta(model.parameters(), lr=args.lr) + + scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma) + for epoch in range(1, args.epochs + 1): + train(args, model, device, train_loader, optimizer, epoch) + test(model, device, test_loader) + scheduler.step() + + fake_in = torch.rand(1,1,28,28) + jit_model = torch.jit.trace(model, fake_in) + torch.jit.save(jit_model, "mnist_cnn.pt") + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/examples/darknet/yolov3/README.md b/examples/darknet/yolov3/README.md new file mode 100644 index 0000000..e5de902 --- /dev/null +++ b/examples/darknet/yolov3/README.md @@ -0,0 +1,37 @@ +# Example for Darknet YOLOV3 + + +## Model Source +The model used in this example come from the darknet official website: +https://pjreddie.com/darknet/yolo/ + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +The test result should be similar to picutre `ref_detect_results.jpg`. + +*Note: Different platforms, different versions of tools and drivers may have slightly different results.* diff --git a/examples/darknet/yolov3/ref_detect_results.jpg b/examples/darknet/yolov3/ref_detect_results.jpg new file mode 100644 index 0000000..f9d96ed Binary files /dev/null and b/examples/darknet/yolov3/ref_detect_results.jpg differ diff --git a/examples/darknet/yolov3/test.py b/examples/darknet/yolov3/test.py index 704db59..ed00bab 100644 --- a/examples/darknet/yolov3/test.py +++ b/examples/darknet/yolov3/test.py @@ -1,11 +1,9 @@ +import platform +import sys import numpy as np import cv2 import os import urllib.request -from matplotlib import gridspec -from matplotlib import pyplot as plt -from PIL import Image -from tensorflow.python.platform import gfile from rknn.api import RKNN @@ -225,6 +223,27 @@ def download_yolov3_weight(dst_path): # Download yolov3.weight download_yolov3_weight(WEIGHT_PATH) + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + # Create RKNN object rknn = RKNN() @@ -232,13 +251,17 @@ def download_yolov3_weight(dst_path): if NEED_BUILD_MODEL: # Set model config - rknn.config(reorder_channel='0 1 2', mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]]) + rknn.config(reorder_channel='0 1 2', + mean_values=[[0, 0, 0]], + std_values=[[255, 255, 255]], + target_platform=[target]) # Load darknet model print('--> Loading model') ret = rknn.load_darknet(model=MODEL_PATH, weight=WEIGHT_PATH) if ret != 0: print('Load darknet model failed!') + rknn.release() exit(ret) print('done') @@ -247,6 +270,7 @@ def download_yolov3_weight(dst_path): ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build model failed.') + rknn.release() exit(ret) print('done') @@ -255,6 +279,7 @@ def download_yolov3_weight(dst_path): ret = rknn.export_rknn(RKNN_MODEL_PATH) if ret != 0: print('Export RKNN model failed.') + rknn.release() exit(ret) print('done') else: @@ -268,7 +293,11 @@ def download_yolov3_weight(dst_path): # Init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed.') exit(ret) @@ -282,6 +311,7 @@ def download_yolov3_weight(dst_path): outputs = rknn.inference(inputs=[img]) print('done') + # Post process: get detected objects, corresponding scores and coordinates input0_data = outputs[0] input1_data = outputs[1] input2_data = outputs[2] @@ -297,12 +327,13 @@ def download_yolov3_weight(dst_path): boxes, classes, scores = yolov3_post_process(input_data) + # Draw and save detected results image = cv2.imread(im_file) if boxes is not None: draw(image, boxes, scores, classes) - cv2.imshow("results", image) - cv2.waitKeyEx(0) + cv2.imwrite("results.jpg", image) + print("The detection results have been drawn into results.jpg") rknn.release() diff --git a/examples/keras/xception/README.md b/examples/keras/xception/README.md new file mode 100644 index 0000000..74a3a0a --- /dev/null +++ b/examples/keras/xception/README.md @@ -0,0 +1,62 @@ +# Example for Keras Xception + + +## Model Source +The model used in this example come from the tensorflow keras project, download link: +https://storage.googleapis.com/tensorflow/keras-applications/xception/xception_weights_tf_dim_ordering_tf_kernels.h5 + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +[1]: 0.9990234375 +[0]: 0.0001596212387084961 +-1: 0.0 +-1: 0.0 +-1: 0.0 +``` + +1. The label index with the highest score is 1, the corresponding label is `goldfish, Carassius auratus`. +2. The download link for labels file: https://s3.amazonaws.com/onnx-model-zoo/synset.txt +3. Different platforms, different versions of tools and drivers may have slightly different results. +4. If the label index is -1, it means that the scores of other categories are all 0. + + +## Notes +- If the following error occurs when loading keras, please check the h5py version and downgrade it to a version below 3.0.0, such as 2.6.0 +``` +E Catch exception when loading keras model: ./xception.h5! +E Traceback (most recent call last): +E File "rknn/base/RKNNlib/converter/convert_keras.py", line 24, in rknn.base.RKNNlib.converter.convert_keras.convert_keras.__init__ +E File "/home/rk/ envs/rknn-test/lib/python3.6/site-packages/tensorflow/python/keras/saving/save.py", line 146, in load_model +E return hdf5_format.load_model_from_hdf5(filepath, custom_objects, compile) +E File "/home/rk/ envs/rknn-test/lib/python3.6/site-packages/tensorflow/python/keras/saving/hdf5_format.py", line 210, in load_model_from_hdf5 +E model_config = json.loads(model_config.decode('utf-8')) +E AttributeError: 'str' object has no attribute 'decode' +``` +Note: This error occurs because the current version of TensorFlow does not support h5py 3.0.0 and above. diff --git a/examples/keras/xception/test.py b/examples/keras/xception/test.py index dc18483..13d8cf7 100644 --- a/examples/keras/xception/test.py +++ b/examples/keras/xception/test.py @@ -1,3 +1,5 @@ +import platform +import sys import os import numpy as np import cv2 @@ -46,15 +48,39 @@ def show_outputs(outputs): if __name__ == '__main__': - + # Export keras xception model export_keras_model() + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + # Create RKNN object rknn = RKNN() # Set model config print('--> Config model') - rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], reorder_channel='0 1 2') + rknn.config(mean_values=[[127.5, 127.5, 127.5]], + std_values=[[127.5, 127.5, 127.5]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load Keras model @@ -62,6 +88,7 @@ def show_outputs(outputs): ret = rknn.load_keras(model=KERAS_MODEL_PATH) if ret != 0: print('Load keras model failed!') + rknn.release() exit(ret) print('done') @@ -70,6 +97,7 @@ def show_outputs(outputs): ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build model failed!') + rknn.release() exit(ret) print('done') @@ -78,27 +106,31 @@ def show_outputs(outputs): ret = rknn.export_rknn('./xception.rknn') if ret != 0: print('Export xception.rknn failed!') + rknn.release() exit(ret) print('done') - # ret = rknn.load_rknn('./xception.rknn') - # Set inputs img = cv2.imread(IMG_PATH) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() - # ret = rknn.init_runtime(target='rk1808') + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') # Inference print('--> Running model') outputs = rknn.inference(inputs=[img]) + # Get TOP5 labels` index and corresponding scores show_outputs(outputs) print('done') diff --git a/examples/mxnet/fcn_resnet101/README.md b/examples/mxnet/fcn_resnet101/README.md new file mode 100644 index 0000000..b9fc254 --- /dev/null +++ b/examples/mxnet/fcn_resnet101/README.md @@ -0,0 +1,37 @@ +# Example for MXNet fcn_resnet101_voc + + +## Model Source +The model used in this example come from the GluonCV project: +https://cv.gluon.ai/model_zoo/segmentation.html + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +The test result should be similar to picutre `ref_seg_results.jpg`. + +*Note: Different platforms, different versions of tools and drivers may have slightly different results.* diff --git a/examples/mxnet/fcn_resnet101/ref_seg_results.jpg b/examples/mxnet/fcn_resnet101/ref_seg_results.jpg new file mode 100644 index 0000000..2219cd1 Binary files /dev/null and b/examples/mxnet/fcn_resnet101/ref_seg_results.jpg differ diff --git a/examples/mxnet/fcn_resnet101/test.py b/examples/mxnet/fcn_resnet101/test.py index da3b821..1ed67da 100644 --- a/examples/mxnet/fcn_resnet101/test.py +++ b/examples/mxnet/fcn_resnet101/test.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -46,15 +48,39 @@ def decode_segmap(image, nc=21): if __name__ == '__main__': - + # Export mxnet fcn_resnet101 model export_mxnet_model() + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + # Create RKNN object rknn = RKNN() # pre-process config print('--> Config model') - rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[57.63, 57.63, 57.63]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.675, 116.28, 103.53]], + std_values=[[57.63, 57.63, 57.63]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load mxnet model @@ -65,6 +91,7 @@ def decode_segmap(image, nc=21): ret = rknn.load_mxnet(symbol, params, input_size_list) if ret != 0: print('Load mxnet model failed!') + rknn.release() exit(ret) print('done') @@ -73,6 +100,7 @@ def decode_segmap(image, nc=21): ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build model failed!') + rknn.release() exit(ret) print('done') @@ -81,6 +109,7 @@ def decode_segmap(image, nc=21): ret = rknn.export_rknn('./fcn_resnet101_voc.rknn') if ret != 0: print('Export RKNN model failed!') + rknn.release() exit(ret) print('done') @@ -90,10 +119,14 @@ def decode_segmap(image, nc=21): # init runtime environment print('--> Init runtime environment') - # ret = rknn.init_runtime(target='rk1808') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') @@ -102,14 +135,15 @@ def decode_segmap(image, nc=21): outputs = rknn.inference(inputs=[img]) print('done') + # Post process: get segmap and write to orignal image segmap = np.squeeze(np.argmax(outputs[0], axis=1)) seg_img = decode_segmap(segmap) overlapping = cv2.addWeighted(img, 1, seg_img, 0.9, 0) overlapping = cv2.cvtColor(overlapping, cv2.COLOR_RGB2BGR) - cv2.imwrite('seg_image.jpg', overlapping) - print('please open seg_image.jpg to see segmentation result.') + # Save segmentation result + print('Save segmentation result to seg_image.jpg') + cv2.imwrite('seg_image.jpg', overlapping) rknn.release() - diff --git a/examples/mxnet/resnext50/README.md b/examples/mxnet/resnext50/README.md new file mode 100644 index 0000000..ea7dd68 --- /dev/null +++ b/examples/mxnet/resnext50/README.md @@ -0,0 +1,46 @@ +# Example for MXNet resnext50_32x4d + + +## Model Source +The model used in this example come from the GluonCV project: +https://cv.gluon.ai/model_zoo/classification.html + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +812 : 0.99996233 +460 : 6.33277e-07 +525 : 5.4181595e-07 +61 : 5.0116495e-07 +628 : 2.2975814e-07 +``` + +1. The label index with the highest score is 812, the corresponding label is space shuttle. +2. The download link for labels file: https://s3.amazonaws.com/onnx-model-zoo/synset.txt +3. Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/examples/mxnet/resnext50/test.py b/examples/mxnet/resnext50/test.py index bdef2a9..0c502a6 100644 --- a/examples/mxnet/resnext50/test.py +++ b/examples/mxnet/resnext50/test.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -32,15 +34,39 @@ def softmax(x): if __name__ == '__main__': - + # Export mxnet resnext50 model export_mxnet_model() + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + # Create RKNN object rknn = RKNN() # pre-process config print('--> Config model') - rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[57.63, 57.63, 57.63]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.675, 116.28, 103.53]], + std_values=[[57.63, 57.63, 57.63]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load mxnet model @@ -51,6 +77,7 @@ def softmax(x): ret = rknn.load_mxnet(symbol, params, input_size_list) if ret != 0: print('Load mxnet model failed!') + rknn.release() exit(ret) print('done') @@ -59,6 +86,7 @@ def softmax(x): ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build model failed!') + rknn.release() exit(ret) print('done') @@ -67,6 +95,7 @@ def softmax(x): ret = rknn.export_rknn('./resnext50_32x4d.rknn') if ret != 0: print('Export RKNN model failed!') + rknn.release() exit(ret) print('done') @@ -76,16 +105,21 @@ def softmax(x): # Init runtime environment print('--> Init runtime environment') - # ret = rknn.init_runtime(target='rk1808') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') # Inference print('--> Running model') outputs = rknn.inference(inputs=[img]) + # Show the top5 predictions show_top5(outputs) print('done') diff --git a/examples/onnx/resnet50v2/README b/examples/onnx/resnet50v2/README deleted file mode 100644 index 0b60b6c..0000000 --- a/examples/onnx/resnet50v2/README +++ /dev/null @@ -1 +0,0 @@ -download model from: https://s3.amazonaws.com/onnx-model-zoo/resnet/resnet50v2/resnet50v2.onnx diff --git a/examples/onnx/resnet50v2/README.md b/examples/onnx/resnet50v2/README.md new file mode 100644 index 0000000..8ad98cf --- /dev/null +++ b/examples/onnx/resnet50v2/README.md @@ -0,0 +1,46 @@ +# Example for ONNX resnext50_32x4d + + +## Model Source +The models used in this example come from the ONNX model zoo project: +https://github.com/onnx/models/tree/main/vision/classification/resnet + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +[155]: 0.6183234453201294 +[154]: 0.3416009843349457 +[262]: 0.021962042897939682 +[152]: 0.003988372161984444 +[204]: 0.002964471932500601 +``` + +1. The label index with the highest score is 155, the corresponding label is `Pekinese, Pekingese, Peke`. +2. The download link for labels file: https://s3.amazonaws.com/onnx-model-zoo/synset.txt +3. Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/examples/onnx/resnet50v2/test.py b/examples/onnx/resnet50v2/test.py index 773999c..3311e66 100644 --- a/examples/onnx/resnet50v2/test.py +++ b/examples/onnx/resnet50v2/test.py @@ -1,3 +1,4 @@ +import platform import os import urllib import traceback @@ -59,6 +60,26 @@ def show_progress(blocknum, blocksize, totalsize): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() @@ -81,7 +102,10 @@ def show_progress(blocknum, blocksize, totalsize): # pre-process config print('--> Config model') - rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[58.82, 58.82, 58.82]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.675, 116.28, 103.53]], + std_values=[[58.82, 58.82, 58.82]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load ONNX model @@ -92,6 +116,7 @@ def show_progress(blocknum, blocksize, totalsize): outputs=['resnetv24_dense0_fwd']) if ret != 0: print('Load resnet50v2 failed!') + rknn.release() exit(ret) print('done') @@ -100,6 +125,7 @@ def show_progress(blocknum, blocksize, totalsize): ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build resnet50v2 failed!') + rknn.release() exit(ret) print('done') @@ -108,6 +134,7 @@ def show_progress(blocknum, blocksize, totalsize): ret = rknn.export_rknn(RKNN_MODEL) if ret != 0: print('Export resnet50v2.rknn failed!') + rknn.release() exit(ret) print('done') @@ -117,18 +144,25 @@ def show_progress(blocknum, blocksize, totalsize): # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') # Inference print('--> Running model') outputs = rknn.inference(inputs=[img]) + # Softmax x = outputs[0] output = np.exp(x)/np.sum(np.exp(x)) outputs = [output] + # Show the top5 predictions show_outputs(outputs) print('done') diff --git a/examples/onnx/yolov5/README.md b/examples/onnx/yolov5/README.md index aa25427..424bde2 100644 --- a/examples/onnx/yolov5/README.md +++ b/examples/onnx/yolov5/README.md @@ -1,23 +1,3 @@ -### 关于模型来源: - -1. 权重来源于https://github.com/ultralytics/yolov5 -2. 导出模型时,由于硬件限制,移除了后处理网络层 -3. 关于如何导出 .onnx 文件,请参考 https://github.com/airockchip/rknn_model_zoo/tree/main/models/vision/object_detection/yolov5-pytorch - - - -### Demo 运行步骤: - -1. 将导出的onnx模型复制到该demo目录下,执行命令: - - ``` - python test.py - ``` - - - -### 注意事项: - -1. 切换成自己训练的模型时,请注意对齐anchor,BOX_THESH,NMS_THRESH等后处理参数,否则会导致后处理解析出错。 - +# Example location change description +At present, the models of the YOLO series have been transferred to the [rknn_model_zoo](https://github.com/airockchip/rknn_model_zoo "rknn model zoo") project. Please refer to the instructions in this project to export the ONNX model, and use the scripts provided by the project to complete operations such as **model conversion**, **model evaluation**, and **deployment**. diff --git a/examples/onnx/yolov5/bus.jpg b/examples/onnx/yolov5/bus.jpg deleted file mode 100644 index d8ef30b..0000000 Binary files a/examples/onnx/yolov5/bus.jpg and /dev/null differ diff --git a/examples/onnx/yolov5/dataset.txt b/examples/onnx/yolov5/dataset.txt deleted file mode 100644 index a81b1f8..0000000 --- a/examples/onnx/yolov5/dataset.txt +++ /dev/null @@ -1 +0,0 @@ -bus.jpg diff --git a/examples/onnx/yolov5/test.py b/examples/onnx/yolov5/test.py deleted file mode 100644 index 88fa357..0000000 --- a/examples/onnx/yolov5/test.py +++ /dev/null @@ -1,311 +0,0 @@ -import os -import numpy as np -import cv2 -from rknn.api import RKNN - - -ONNX_MODEL = 'yolov5s.onnx' -RKNN_MODEL = 'yolov5s.rknn' -IMG_PATH = './bus.jpg' -DATASET = './dataset.txt' - -QUANTIZE_ON = True - -BOX_THRESH = 0.5 -NMS_THRESH = 0.6 -IMG_SIZE = (640, 640) # (width, height), such as (1280, 736) - -CLASSES = ("person", "bicycle", "car","motorbike ","aeroplane ","bus ","train","truck ","boat","traffic light", - "fire hydrant","stop sign ","parking meter","bench","bird","cat","dog ","horse ","sheep","cow","elephant", - "bear","zebra ","giraffe","backpack","umbrella","handbag","tie","suitcase","frisbee","skis","snowboard","sports ball","kite", - "baseball bat","baseball glove","skateboard","surfboard","tennis racket","bottle","wine glass","cup","fork","knife ", - "spoon","bowl","banana","apple","sandwich","orange","broccoli","carrot","hot dog","pizza ","donut","cake","chair","sofa", - "pottedplant","bed","diningtable","toilet ","tvmonitor","laptop ","mouse ","remote ","keyboard ","cell phone","microwave ", - "oven ","toaster","sink","refrigerator ","book","clock","vase","scissors ","teddy bear ","hair drier", "toothbrush ") - -def sigmoid(x): - return 1 / (1 + np.exp(-x)) - -def xywh2xyxy(x): - # Convert [x, y, w, h] to [x1, y1, x2, y2] - y = np.copy(x) - y[:, 0] = x[:, 0] - x[:, 2] / 2 # top left x - y[:, 1] = x[:, 1] - x[:, 3] / 2 # top left y - y[:, 2] = x[:, 0] + x[:, 2] / 2 # bottom right x - y[:, 3] = x[:, 1] + x[:, 3] / 2 # bottom right y - return y - -def process(input, mask, anchors): - - anchors = [anchors[i] for i in mask] - grid_h, grid_w = map(int, input.shape[0:2]) - - box_confidence = sigmoid(input[..., 4]) - box_confidence = np.expand_dims(box_confidence, axis=-1) - - box_class_probs = sigmoid(input[..., 5:]) - - box_xy = sigmoid(input[..., :2])*2 - 0.5 - - col = np.tile(np.arange(0, grid_w), grid_h).reshape(-1, grid_w) - row = np.tile(np.arange(0, grid_h).reshape(-1, 1), grid_w) - col = col.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2) - row = row.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2) - grid = np.concatenate((col, row), axis=-1) - box_xy += grid - box_xy *= (int(IMG_SIZE[1]/grid_h), int(IMG_SIZE[0]/grid_w)) - - box_wh = pow(sigmoid(input[..., 2:4])*2, 2) - box_wh = box_wh * anchors - - box = np.concatenate((box_xy, box_wh), axis=-1) - - return box, box_confidence, box_class_probs - -def filter_boxes(boxes, box_confidences, box_class_probs): - """Filter boxes with box threshold. It's a bit different with origin yolov5 post process! - - # Arguments - boxes: ndarray, boxes of objects. - box_confidences: ndarray, confidences of objects. - box_class_probs: ndarray, class_probs of objects. - - # Returns - boxes: ndarray, filtered boxes. - classes: ndarray, classes for boxes. - scores: ndarray, scores for boxes. - """ - boxes = boxes.reshape(-1, 4) - box_confidences = box_confidences.reshape(-1) - box_class_probs = box_class_probs.reshape(-1, box_class_probs.shape[-1]) - - _box_pos = np.where(box_confidences >= BOX_THRESH) - boxes = boxes[_box_pos] - box_confidences = box_confidences[_box_pos] - box_class_probs = box_class_probs[_box_pos] - - class_max_score = np.max(box_class_probs, axis=-1) - classes = np.argmax(box_class_probs, axis=-1) - _class_pos = np.where(class_max_score* box_confidences >= BOX_THRESH) - - boxes = boxes[_class_pos] - classes = classes[_class_pos] - scores = (class_max_score* box_confidences)[_class_pos] - - return boxes, classes, scores - -def nms_boxes(boxes, scores): - """Suppress non-maximal boxes. - - # Arguments - boxes: ndarray, boxes of objects. - scores: ndarray, scores of objects. - - # Returns - keep: ndarray, index of effective boxes. - """ - x = boxes[:, 0] - y = boxes[:, 1] - w = boxes[:, 2] - boxes[:, 0] - h = boxes[:, 3] - boxes[:, 1] - - areas = w * h - order = scores.argsort()[::-1] - - keep = [] - while order.size > 0: - i = order[0] - keep.append(i) - - xx1 = np.maximum(x[i], x[order[1:]]) - yy1 = np.maximum(y[i], y[order[1:]]) - xx2 = np.minimum(x[i] + w[i], x[order[1:]] + w[order[1:]]) - yy2 = np.minimum(y[i] + h[i], y[order[1:]] + h[order[1:]]) - - w1 = np.maximum(0.0, xx2 - xx1 + 0.00001) - h1 = np.maximum(0.0, yy2 - yy1 + 0.00001) - inter = w1 * h1 - - ovr = inter / (areas[i] + areas[order[1:]] - inter) - inds = np.where(ovr <= NMS_THRESH)[0] - order = order[inds + 1] - keep = np.array(keep) - return keep - - -def yolov5_post_process(input_data): - masks = [[0, 1, 2], [3, 4, 5], [6, 7, 8]] - anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45], - [59, 119], [116, 90], [156, 198], [373, 326]] - - boxes, classes, scores = [], [], [] - for input,mask in zip(input_data, masks): - b, c, s = process(input, mask, anchors) - b, c, s = filter_boxes(b, c, s) - boxes.append(b) - classes.append(c) - scores.append(s) - - boxes = np.concatenate(boxes) - boxes = xywh2xyxy(boxes) - classes = np.concatenate(classes) - scores = np.concatenate(scores) - - nboxes, nclasses, nscores = [], [], [] - for c in set(classes): - inds = np.where(classes == c) - b = boxes[inds] - c = classes[inds] - s = scores[inds] - - keep = nms_boxes(b, s) - - nboxes.append(b[keep]) - nclasses.append(c[keep]) - nscores.append(s[keep]) - - if not nclasses and not nscores: - return None, None, None - - boxes = np.concatenate(nboxes) - classes = np.concatenate(nclasses) - scores = np.concatenate(nscores) - - return boxes, classes, scores - -def draw(image, boxes, scores, classes): - """Draw the boxes on the image. - - # Argument: - image: original image. - boxes: ndarray, boxes of objects. - classes: ndarray, classes of objects. - scores: ndarray, scores of objects. - all_classes: all classes name. - """ - for box, score, cl in zip(boxes, scores, classes): - top, left, right, bottom = box - print('class: {}, score: {}'.format(CLASSES[cl], score)) - print('box coordinate left,top,right,down: [{}, {}, {}, {}]'.format(top, left, right, bottom)) - top = int(top) - left = int(left) - right = int(right) - bottom = int(bottom) - - cv2.rectangle(image, (top, left), (right, bottom), (255, 0, 0), 2) - cv2.putText(image, '{0} {1:.2f}'.format(CLASSES[cl], score), - (top, left - 6), - cv2.FONT_HERSHEY_SIMPLEX, - 0.6, (0, 0, 255), 2) - - -def letterbox(im, new_shape=(640, 640), color=(0, 0, 0)): - # Resize and pad image while meeting stride-multiple constraints - shape = im.shape[:2] # current shape [height, width] - if isinstance(new_shape, int): - new_shape = (new_shape, new_shape) - - # Scale ratio (new / old) - r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) - - # Compute padding - ratio = r, r # width, height ratios - new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) - dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding - - dw /= 2 # divide padding into 2 sides - dh /= 2 - - if shape[::-1] != new_unpad: # resize - im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR) - top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) - left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) - im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border - return im, ratio, (dw, dh) - - -if __name__ == '__main__': - - # Create RKNN object - rknn = RKNN() - - if not os.path.exists(ONNX_MODEL): - print('model not exist') - exit(-1) - - # pre-process config - print('--> Config model') - rknn.config(reorder_channel='0 1 2', - mean_values=[[0, 0, 0]], - std_values=[[255, 255, 255]], - optimization_level=3, - target_platform = 'rk1808', - output_optimize=1, - quantize_input_node=QUANTIZE_ON) - print('done') - - # Load ONNX model - print('--> Loading model') - ret = rknn.load_onnx(model=ONNX_MODEL) - if ret != 0: - print('Load yolov5 failed!') - exit(ret) - print('done') - - # Build model - print('--> Building model') - ret = rknn.build(do_quantization=QUANTIZE_ON, dataset=DATASET) - if ret != 0: - print('Build yolov5 failed!') - exit(ret) - print('done') - - # Export RKNN model - print('--> Export RKNN model') - ret = rknn.export_rknn(RKNN_MODEL) - if ret != 0: - print('Export yolov5rknn failed!') - exit(ret) - print('done') - - # init runtime environment - print('--> Init runtime environment') - ret = rknn.init_runtime() - # ret = rknn.init_runtime('rk1808', device_id='1808') - if ret != 0: - print('Init runtime environment failed') - exit(ret) - print('done') - - # Set inputs - img = cv2.imread(IMG_PATH) - img, ratio, (dw, dh) = letterbox(img, new_shape=(IMG_SIZE[1], IMG_SIZE[0])) - img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) - - # Inference - print('--> Running model') - outputs = rknn.inference(inputs=[img]) - - # post process - input0_data = outputs[0] - input1_data = outputs[1] - input2_data = outputs[2] - - input0_data = input0_data.reshape([3,-1]+list(input0_data.shape[-2:])) - input1_data = input1_data.reshape([3,-1]+list(input1_data.shape[-2:])) - input2_data = input2_data.reshape([3,-1]+list(input2_data.shape[-2:])) - - input_data = list() - input_data.append(np.transpose(input0_data, (2, 3, 0, 1))) - input_data.append(np.transpose(input1_data, (2, 3, 0, 1))) - input_data.append(np.transpose(input2_data, (2, 3, 0, 1))) - - boxes, classes, scores = yolov5_post_process(input_data) - - img_1 = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - if boxes is not None: - draw(img_1, boxes, scores, classes) - cv2.imshow("post process result", img_1) - cv2.waitKeyEx(0) - - rknn.release() diff --git a/examples/onnx/yolov5/yolov5s.onnx b/examples/onnx/yolov5/yolov5s.onnx deleted file mode 100644 index b040f21..0000000 Binary files a/examples/onnx/yolov5/yolov5s.onnx and /dev/null differ diff --git a/examples/pytorch/resnet18/README.md b/examples/pytorch/resnet18/README.md new file mode 100644 index 0000000..6aedc51 --- /dev/null +++ b/examples/pytorch/resnet18/README.md @@ -0,0 +1,46 @@ +# Example for PyTorch resnet18 + + +## Model Source +The models used in this example come from the torchvision project: +https://github.com/pytorch/vision/tree/main/torchvision/models + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +[812]: 0.9993903636932373 +[404]: 0.0004593881603796035 +[657 833]: 2.9284470656421036e-05 +[657 833]: 2.9284470656421036e-05 +[895]: 1.8508895664126612e-05 +``` + +1. The label index with the highest score is 812, the corresponding label is `space shuttle`. +2. The download link for labels file: https://s3.amazonaws.com/onnx-model-zoo/synset.txt +3. Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/examples/pytorch/resnet18/test.py b/examples/pytorch/resnet18/test.py index 1c21fa3..24a1524 100644 --- a/examples/pytorch/resnet18/test.py +++ b/examples/pytorch/resnet18/test.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -39,18 +41,42 @@ def softmax(x): if __name__ == '__main__': - + # Export resnet18 torchscript model export_pytorch_model() model = './resnet18.pt' input_size_list = [[3, 224, 224]] + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) + # Create RKNN object rknn = RKNN() # pre-process config print('--> Config model') - rknn.config(mean_values=[[123.675, 116.28, 103.53]], std_values=[[58.395, 58.395, 58.395]], reorder_channel='0 1 2') + rknn.config(mean_values=[[123.675, 116.28, 103.53]], + std_values=[[58.395, 58.395, 58.395]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load Pytorch model @@ -58,6 +84,7 @@ def softmax(x): ret = rknn.load_pytorch(model=model, input_size_list=input_size_list) if ret != 0: print('Load Pytorch model failed!') + rknn.release() exit(ret) print('done') @@ -66,6 +93,7 @@ def softmax(x): ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build model failed!') + rknn.release() exit(ret) print('done') @@ -74,26 +102,31 @@ def softmax(x): ret = rknn.export_rknn('./resnet_18.rknn') if ret != 0: print('Export resnet_18.rknn failed!') + rknn.release() exit(ret) print('done') - # ret = rknn.load_rknn('./resnet_18.rknn') - # Set inputs img = cv2.imread('./space_shuttle_224.jpg') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') # Inference print('--> Running model') outputs = rknn.inference(inputs=[img]) + # Show the top5 predictions show_outputs(softmax(np.array(outputs[0][0]))) print('done') diff --git a/examples/pytorch/yolov5/README.md b/examples/pytorch/yolov5/README.md index 2233ca5..0fd6064 100644 --- a/examples/pytorch/yolov5/README.md +++ b/examples/pytorch/yolov5/README.md @@ -1,70 +1,4 @@ -### Demo 运行步骤: +# Example location change description ---- - -1. 使用yolov5官方仓库导出模型,链接:https://github.com/ultralytics/yolov5。该demo创建时yolov5的节点的commit id为:c5360f6e7009eb4d05f14d1cc9dae0963e949213 - -2. 在yolov5工程的根目录下导出已训练好的yolov5模型,如yolov5s.torchscript.pt模型 - - ``` - python export.py --weights yolov5s.pt --img 640 --batch 1 --include torchscript - ``` - - **注意**:模型导出前需要对yolov5/models/yolo.py进行修改,具体修改步骤在后面。 - -3. 将导出的pt模型复制到该demo目录下,执行命令: - - ``` - python test.py - ``` - -4. 加载yolov5 pytorch模型需要将 rknn_toolkit版本升级至 1.7.1 - -5. 开启量化时,rknn.config中的quantize_input_node 被设置为True。若不启用,yolov5模型由于模型头部是slice算子而非常规算子,这种情况有可能导致yolov5模型的输入层没有被转为量化算子,导致RKNN模型在板端使用 RKNN C api 部署时,input_set耗时异常。该参数具体作用请参考用户手册7.2节。 - -6. 模型转换后,c代码部署可参考https://github.com/rockchip-linux/rknpu/tree/master/rknn/rknn_api/examples/rknn_yolov5_demo - - - -## yolov5模型导出需要注意的地方 - -1. yolov5官方仓库地址为 https://github.com/ultralytics/yolov5 - -3. 直接使用pt模型转为rknn模型时,需要修改 yolov5/models/yolo.py文件的后处理部分,将class Detect(nn.Module) 类的子函数forward由 - - ```python - def forward(self, x): - z = [] # inference output - for i in range(self.nl): - x[i] = self.m[i](x[i]) # conv - bs, _, ny, nx = x[i].shape # x(bs,255,20,20) to x(bs,3,20,20,85) - x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous() - - if not self.training: # inference - if self.grid[i].shape[2:4] != x[i].shape[2:4] or self.onnx_dynamic: - self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i) - - y = x[i].sigmoid() - if self.inplace: - y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i] # xy - y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh - else: # for YOLOv5 on AWS Inferentia https://github.com/ultralytics/yolov5/pull/2953 - xy = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i] # xy - wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh - y = torch.cat((xy, wh, y[..., 4:]), -1) - z.append(y.view(bs, -1, self.no)) - - return x if self.training else (torch.cat(z, 1), x) - ``` - - 修改为: - - ```python - def forward(self, x): - z = [] # inference output - for i in range(self.nl): - x[i] = self.m[i](x[i]) # conv - - return x - ``` +At present, the models of the YOLO series have been transferred to the [rknn_model_zoo](https://github.com/airockchip/rknn_model_zoo "rknn model zoo") project. Please refer to the instructions in this project to export the TorchScript model, and use the scripts provided by the project to complete operations such as **model conversion**, **model evaluation**, and **deployment**. diff --git a/examples/pytorch/yolov5/bus.jpg b/examples/pytorch/yolov5/bus.jpg deleted file mode 100644 index d8ef30b..0000000 Binary files a/examples/pytorch/yolov5/bus.jpg and /dev/null differ diff --git a/examples/pytorch/yolov5/dataset.txt b/examples/pytorch/yolov5/dataset.txt deleted file mode 100644 index a81b1f8..0000000 --- a/examples/pytorch/yolov5/dataset.txt +++ /dev/null @@ -1 +0,0 @@ -bus.jpg diff --git a/examples/pytorch/yolov5/test.py b/examples/pytorch/yolov5/test.py deleted file mode 100644 index 8c57244..0000000 --- a/examples/pytorch/yolov5/test.py +++ /dev/null @@ -1,315 +0,0 @@ -import os -import numpy as np -import cv2 -from rknn.api import RKNN - - -PT_MODEL = 'yolov5s.torchscript.pt' -RKNN_MODEL = 'yolov5s.rknn' -IMG_PATH = 'bus.jpg' -DATASET = './dataset.txt' - -QUANTIZE_ON = False - -BOX_THRESH = 0.5 -NMS_THRESH = 0.6 -IMG_SIZE = (640, 640) # (width, height), such as (1280, 736) - -CLASSES = ("person", "bicycle", "car","motorbike ","aeroplane ","bus ","train","truck ","boat","traffic light", - "fire hydrant","stop sign ","parking meter","bench","bird","cat","dog ","horse ","sheep","cow","elephant", - "bear","zebra ","giraffe","backpack","umbrella","handbag","tie","suitcase","frisbee","skis","snowboard","sports ball","kite", - "baseball bat","baseball glove","skateboard","surfboard","tennis racket","bottle","wine glass","cup","fork","knife ", - "spoon","bowl","banana","apple","sandwich","orange","broccoli","carrot","hot dog","pizza ","donut","cake","chair","sofa", - "pottedplant","bed","diningtable","toilet ","tvmonitor","laptop ","mouse ","remote ","keyboard ","cell phone","microwave ", - "oven ","toaster","sink","refrigerator ","book","clock","vase","scissors ","teddy bear ","hair drier", "toothbrush ") - -def sigmoid(x): - return 1 / (1 + np.exp(-x)) - -def xywh2xyxy(x): - # Convert [x, y, w, h] to [x1, y1, x2, y2] - y = np.copy(x) - y[:, 0] = x[:, 0] - x[:, 2] / 2 # top left x - y[:, 1] = x[:, 1] - x[:, 3] / 2 # top left y - y[:, 2] = x[:, 0] + x[:, 2] / 2 # bottom right x - y[:, 3] = x[:, 1] + x[:, 3] / 2 # bottom right y - return y - -def process(input, mask, anchors): - - anchors = [anchors[i] for i in mask] - grid_h, grid_w = map(int, input.shape[0:2]) - - box_confidence = sigmoid(input[..., 4]) - box_confidence = np.expand_dims(box_confidence, axis=-1) - - box_class_probs = sigmoid(input[..., 5:]) - - box_xy = sigmoid(input[..., :2])*2 - 0.5 - - col = np.tile(np.arange(0, grid_w), grid_h).reshape(-1, grid_w) - row = np.tile(np.arange(0, grid_h).reshape(-1, 1), grid_w) - col = col.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2) - row = row.reshape(grid_h, grid_w, 1, 1).repeat(3, axis=-2) - grid = np.concatenate((col, row), axis=-1) - box_xy += grid - box_xy *= (int(IMG_SIZE[1]/grid_h), int(IMG_SIZE[0]/grid_w)) - - box_wh = pow(sigmoid(input[..., 2:4])*2, 2) - box_wh = box_wh * anchors - - box = np.concatenate((box_xy, box_wh), axis=-1) - - return box, box_confidence, box_class_probs - -def filter_boxes(boxes, box_confidences, box_class_probs): - """Filter boxes with box threshold. It's a bit different with origin yolov5 post process! - - # Arguments - boxes: ndarray, boxes of objects. - box_confidences: ndarray, confidences of objects. - box_class_probs: ndarray, class_probs of objects. - - # Returns - boxes: ndarray, filtered boxes. - classes: ndarray, classes for boxes. - scores: ndarray, scores for boxes. - """ - boxes = boxes.reshape(-1, 4) - box_confidences = box_confidences.reshape(-1) - box_class_probs = box_class_probs.reshape(-1, box_class_probs.shape[-1]) - - _box_pos = np.where(box_confidences >= BOX_THRESH) - boxes = boxes[_box_pos] - box_confidences = box_confidences[_box_pos] - box_class_probs = box_class_probs[_box_pos] - - class_max_score = np.max(box_class_probs, axis=-1) - classes = np.argmax(box_class_probs, axis=-1) - _class_pos = np.where(class_max_score* box_confidences >= BOX_THRESH) - - boxes = boxes[_class_pos] - classes = classes[_class_pos] - scores = (class_max_score* box_confidences)[_class_pos] - - return boxes, classes, scores - -def nms_boxes(boxes, scores): - """Suppress non-maximal boxes. - - # Arguments - boxes: ndarray, boxes of objects. - scores: ndarray, scores of objects. - - # Returns - keep: ndarray, index of effective boxes. - """ - x = boxes[:, 0] - y = boxes[:, 1] - w = boxes[:, 2] - boxes[:, 0] - h = boxes[:, 3] - boxes[:, 1] - - areas = w * h - order = scores.argsort()[::-1] - - keep = [] - while order.size > 0: - i = order[0] - keep.append(i) - - xx1 = np.maximum(x[i], x[order[1:]]) - yy1 = np.maximum(y[i], y[order[1:]]) - xx2 = np.minimum(x[i] + w[i], x[order[1:]] + w[order[1:]]) - yy2 = np.minimum(y[i] + h[i], y[order[1:]] + h[order[1:]]) - - w1 = np.maximum(0.0, xx2 - xx1 + 0.00001) - h1 = np.maximum(0.0, yy2 - yy1 + 0.00001) - inter = w1 * h1 - - ovr = inter / (areas[i] + areas[order[1:]] - inter) - inds = np.where(ovr <= NMS_THRESH)[0] - order = order[inds + 1] - keep = np.array(keep) - return keep - - -def yolov5_post_process(input_data): - masks = [[0, 1, 2], [3, 4, 5], [6, 7, 8]] - anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45], - [59, 119], [116, 90], [156, 198], [373, 326]] - - boxes, classes, scores = [], [], [] - for input,mask in zip(input_data, masks): - b, c, s = process(input, mask, anchors) - b, c, s = filter_boxes(b, c, s) - boxes.append(b) - classes.append(c) - scores.append(s) - - boxes = np.concatenate(boxes) - boxes = xywh2xyxy(boxes) - classes = np.concatenate(classes) - scores = np.concatenate(scores) - - nboxes, nclasses, nscores = [], [], [] - for c in set(classes): - inds = np.where(classes == c) - b = boxes[inds] - c = classes[inds] - s = scores[inds] - - keep = nms_boxes(b, s) - - nboxes.append(b[keep]) - nclasses.append(c[keep]) - nscores.append(s[keep]) - - if not nclasses and not nscores: - return None, None, None - - boxes = np.concatenate(nboxes) - classes = np.concatenate(nclasses) - scores = np.concatenate(nscores) - - return boxes, classes, scores - -def draw(image, boxes, scores, classes): - """Draw the boxes on the image. - # Argument: - image: original image. - boxes: ndarray, boxes of objects. - classes: ndarray, classes of objects. - scores: ndarray, scores of objects. - all_classes: all classes name. - """ - for box, score, cl in zip(boxes, scores, classes): - left, top, right, bottom = box - print('class: {}, score: {}'.format(CLASSES[cl], score)) - print('box coordinate left,top,right,bottom: [{}, {}, {}, {}]'.format(left, top, right, bottom)) - left = int(left) - top = int(top) - right = int(right) - bottom = int(bottom) - - cv2.rectangle(image, (left, top), (right, bottom), (255, 0, 0), 2) - cv2.putText(image, '{0} {1:.2f}'.format(CLASSES[cl], score), - (left, top - 6), - cv2.FONT_HERSHEY_SIMPLEX, - 0.6, (0, 0, 255), 2) - - -def letterbox(im, new_shape=(640, 640), color=(0, 0, 0)): - # Resize and pad image while meeting stride-multiple constraints - shape = im.shape[:2] # current shape [height, width] - if isinstance(new_shape, int): - new_shape = (new_shape, new_shape) - - # Scale ratio (new / old) - r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) - - # Compute padding - ratio = r, r # width, height ratios - new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) - dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding - - dw /= 2 # divide padding into 2 sides - dh /= 2 - - if shape[::-1] != new_unpad: # resize - im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR) - top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) - left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) - im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border - return im, ratio, (dw, dh) - - -if __name__ == '__main__': - - # Create RKNN object - rknn = RKNN(verbose=False) - - if not os.path.exists(PT_MODEL): - print('model not exist') - exit(-1) - - _force_builtin_perm = False - # pre-process config - print('--> Config model') - rknn.config( - reorder_channel='0 1 2', - mean_values=[[0, 0, 0]], - std_values=[[255, 255, 255]], - optimization_level=3, - target_platform = 'rk1808', - # target_platform='rv1109', - quantize_input_node= QUANTIZE_ON, - output_optimize=1, - force_builtin_perm=_force_builtin_perm) - print('done') - - # Load ONNX model - print('--> Loading model') - ret = rknn.load_pytorch(model=PT_MODEL, input_size_list=[[3,IMG_SIZE[1], IMG_SIZE[0]]]) - if ret != 0: - print('Load yolov5 failed!') - exit(ret) - print('done') - - # Build model - print('--> Building model') - ret = rknn.build(do_quantization=QUANTIZE_ON, dataset=DATASET, pre_compile=False) - if ret != 0: - print('Build yolov5 failed!') - exit(ret) - print('done') - - # Export RKNN model - print('--> Export RKNN model') - ret = rknn.export_rknn(RKNN_MODEL) - if ret != 0: - print('Export yolov5rknn failed!') - exit(ret) - print('done') - - # init runtime environment - print('--> Init runtime environment') - ret = rknn.init_runtime() - # ret = rknn.init_runtime('rv1109', device_id='1109') - # ret = rknn.init_runtime('rk1808', device_id='1808') - if ret != 0: - print('Init runtime environment failed') - exit(ret) - print('done') - - # Set inputs - img = cv2.imread(IMG_PATH) - img, ratio, (dw, dh) = letterbox(img, new_shape=(IMG_SIZE[1], IMG_SIZE[0])) - img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) - - # Inference - print('--> Running model') - outputs = rknn.inference(inputs=[img], inputs_pass_through=[0 if not _force_builtin_perm else 1]) - - # post process - input0_data = outputs[0] - input1_data = outputs[1] - input2_data = outputs[2] - - input0_data = input0_data.reshape([3,-1]+list(input0_data.shape[-2:])) - input1_data = input1_data.reshape([3,-1]+list(input1_data.shape[-2:])) - input2_data = input2_data.reshape([3,-1]+list(input2_data.shape[-2:])) - - input_data = list() - input_data.append(np.transpose(input0_data, (2, 3, 0, 1))) - input_data.append(np.transpose(input1_data, (2, 3, 0, 1))) - input_data.append(np.transpose(input2_data, (2, 3, 0, 1))) - - boxes, classes, scores = yolov5_post_process(input_data) - - img_1 = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) - if boxes is not None: - draw(img_1, boxes, scores, classes) - cv2.imshow("post process result", img_1) - cv2.waitKeyEx(0) - - rknn.release() diff --git a/examples/rknn_convert/README.md b/examples/rknn_convert/README.md index e43037e..1d44a62 100644 --- a/examples/rknn_convert/README.md +++ b/examples/rknn_convert/README.md @@ -1,31 +1,5 @@ -## 环境准备 +# Example change description -安装rknn-toolkit +1. For the normal model conversion using the **Python API**, you can refer to the conversion process of other sample codes. +2. In addition, RKNN-Toolkit also supports model conversion with **less coding** and **more convenient verification functions** by writing yaml configuration files. For more details, please refer to the [rknn_model_zoo](https://github.com/airockchip/rknn_model_zoo "rknn model zoo") project to learn how to write your own model configuration file, using a unified model conversion script to complete the RKNN model **conversion and evaluation** task. -## 模型转换 - -``` -python rknn_convert models/face_detection out_rknn False -``` - -第1个参数是要转换的原始模型的路径(可以直接填目录,但该目录需要包含`model_config.yml`文件) - -第2个参数是转换后模型输出目录 - -第3个参数是是否开启预编译(加速模型加载时间) - - -## 添加模型 - -参考models下的目录,其中 - -- tensorflow可以参考tensorflow/mobilenet-ssd -- caffe模型可以参考caffe/mobilenet_v2 -- onnx模型可以参考onnx/mobilenet_v2 -- tflite模型可以参考tflite/mobilenet_v1 - -需要包括以下文件 - -- 模型原始文件 -- model_config.yml模型的配置文件 -- 量化的dataset.txt和量化图片 diff --git a/examples/rknn_convert/models/caffe/mobilenet_v2/README b/examples/rknn_convert/models/caffe/mobilenet_v2/README deleted file mode 100644 index bc58027..0000000 --- a/examples/rknn_convert/models/caffe/mobilenet_v2/README +++ /dev/null @@ -1 +0,0 @@ -caffe模型文件, 量化的dataset.txt和量化图片在examples/caffe/mobilenet_v2/目录下 diff --git a/examples/rknn_convert/models/caffe/mobilenet_v2/model_config.yml b/examples/rknn_convert/models/caffe/mobilenet_v2/model_config.yml deleted file mode 100644 index a751fb6..0000000 --- a/examples/rknn_convert/models/caffe/mobilenet_v2/model_config.yml +++ /dev/null @@ -1,15 +0,0 @@ -project-name: mobilenet_v2 -models: - mobilenet_v2: - platform: caffe - prototxt_file_path: ../../../../caffe/mobilenet_v2/mobilenet_v2.prototxt - caffemodel_file_path: ../../../../caffe/mobilenet_v2/mobilenet_v2.caffemodel - quantize: true - source: text - dataset: ../../../../caffe/mobilenet_v2/dataset.txt - configs: - quantized_dtype: asymmetric_quantized-u8 - batch_size: 1 - mean_values: [[103.94, 116.78, 123.68]] - std_values: [[58.82, 58.82, 58.82]] - reorder_channel: 2 1 0 diff --git a/examples/rknn_convert/models/tensorflow/mobilenet-ssd/README b/examples/rknn_convert/models/tensorflow/mobilenet-ssd/README deleted file mode 100644 index 8aad1e1..0000000 --- a/examples/rknn_convert/models/tensorflow/mobilenet-ssd/README +++ /dev/null @@ -1 +0,0 @@ -TensorFlow模型文件, 量化的dataset.txt和量化图片在examples/tensorflow/ssd_mobilenet_v1/目录下 diff --git a/examples/rknn_convert/models/tensorflow/mobilenet-ssd/model_config.yml b/examples/rknn_convert/models/tensorflow/mobilenet-ssd/model_config.yml deleted file mode 100644 index 57d0465..0000000 --- a/examples/rknn_convert/models/tensorflow/mobilenet-ssd/model_config.yml +++ /dev/null @@ -1,22 +0,0 @@ -project-name: mobilenet-ssd -models: - mobilenet-ssd: - platform: tensorflow - model_file_path: ../../../../tensorflow/ssd_mobilenet_v1/ssd_mobilenet_v1_coco_2017_11_17.pb - subgraphs: - inputs: - - FeatureExtractor/MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/mul_1 - input-size-list: - - 300,300,3 - outputs: - - concat - - concat_1 - quantize: true - source: text - dataset: ../../../../tensorflow/ssd_mobilenet_v1/dataset.txt - configs: - quantized_dtype: asymmetric_quantized-u8 - batch_size: 1 - mean_values: [[127.5, 127.5, 127.5]] - std_values: [[127.5, 127.5, 127.5]] - reorder_channel: 0 1 2 diff --git a/examples/rknn_convert/models/tflite/mobilenet_v1/README b/examples/rknn_convert/models/tflite/mobilenet_v1/README deleted file mode 100644 index 6cd6fb2..0000000 --- a/examples/rknn_convert/models/tflite/mobilenet_v1/README +++ /dev/null @@ -1 +0,0 @@ -tflite模型文件, 量化的dataset.txt和量化图片在examples/tflite/mobilenet_v1/目录下 diff --git a/examples/rknn_convert/models/tflite/mobilenet_v1/model_config.yml b/examples/rknn_convert/models/tflite/mobilenet_v1/model_config.yml deleted file mode 100644 index 85f5e05..0000000 --- a/examples/rknn_convert/models/tflite/mobilenet_v1/model_config.yml +++ /dev/null @@ -1,14 +0,0 @@ -project-name: mobilenet_v1 -models: - mobilenet_v1: - platform: tflite - model_file_path: ../../../../tflite/mobilenet_v1/mobilenet_v1.tflite - quantize: true - source: text - dataset: ../../../../tflite/mobilenet_v1/dataset.txt - configs: - quantized_dtype: asymmetric_quantized-u8 - batch_size: 1 - mean_values: [[127.5, 127.5, 127.5]] - std_values: [[127.5, 127.5, 127.5]] - reorder_channel: 0 1 2 diff --git a/examples/rknn_convert/rknn_convert.py b/examples/rknn_convert/rknn_convert.py deleted file mode 100644 index fbaf9aa..0000000 --- a/examples/rknn_convert/rknn_convert.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys - -#import yaml -import ruamel.yaml -from rknn.api import RKNN - -yaml = ruamel.yaml.YAML(typ='rt') - -def parse_model_config(yaml_config_file): - with open(yaml_config_file) as f: - yaml_config = f.read() - model_configs = yaml.load(yaml_config) - return model_configs - - -def convert_model(model_path, out_path, pre_compile): - if os.path.isfile(model_path): - yaml_config_file = model_path - model_path = os.path.dirname(yaml_config_file) - else: - yaml_config_file = os.path.join(model_path, 'model_config.yml') - if not os.path.exists(yaml_config_file): - print('model config {} not exist!'.format(yaml_config_file)) - exit(-1) - - model_configs = parse_model_config(yaml_config_file) - - exported_rknn_model_path_list = [] - - for model_name in model_configs['models']: - model = model_configs['models'][model_name] - - rknn = RKNN() - - rknn.config(**model['configs']) - - print('--> Loading model...') - if model['platform'] == 'tensorflow': - model_file_path = os.path.join(model_path, model['model_file_path']) - input_size_list = [] - for input_size_str in model['subgraphs']['input-size-list']: - input_size = list(map(int, input_size_str.split(','))) - input_size_list.append(input_size) - pass - rknn.load_tensorflow(tf_pb=model_file_path, - inputs=model['subgraphs']['inputs'], - outputs=model['subgraphs']['outputs'], - input_size_list=input_size_list) - elif model['platform'] == 'tflite': - model_file_path = os.path.join(model_path, model['model_file_path']) - rknn.load_tflite(model=model_file_path) - elif model['platform'] == 'caffe': - prototxt_file_path = os.path.join(model_path,model['prototxt_file_path']) - caffemodel_file_path = os.path.join(model_path,model['caffemodel_file_path']) - rknn.load_caffe(model=prototxt_file_path, proto='caffe', blobs=caffemodel_file_path) - elif model['platform'] == 'onnx': - model_file_path = os.path.join(model_path, model['model_file_path']) - rknn.load_onnx(model=model_file_path) - else: - print("platform %s not support!" % (model['platform'])) - print('done') - - if model['quantize']: - dataset_path = os.path.join(model_path, model['dataset']) - else: - dataset_path = './dataset' - - print('--> Build RKNN model...') - rknn.build(do_quantization=model['quantize'], dataset=dataset_path, pre_compile=pre_compile) - print('done') - - export_rknn_model_path = "%s.rknn" % (os.path.join(out_path, model_name)) - print('--> Export RKNN model to: {}'.format(export_rknn_model_path)) - rknn.export_rknn(export_path=export_rknn_model_path) - exported_rknn_model_path_list.append(export_rknn_model_path) - print('done') - - rknn.release() - - return exported_rknn_model_path_list - - -if __name__ == '__main__': - model_path = sys.argv[1] - out_path = sys.argv[2] - pre_compile = sys.argv[3] in ['true', '1', 'True'] - - convert_model(model_path, out_path, pre_compile) diff --git a/examples/tensorflow/ssd_mobilenet_v1/README.md b/examples/tensorflow/ssd_mobilenet_v1/README.md new file mode 100644 index 0000000..51b6acc --- /dev/null +++ b/examples/tensorflow/ssd_mobilenet_v1/README.md @@ -0,0 +1,38 @@ +# Example for TensorFlow ssd_mobilenet_v1_coco + + +## Model Source +The model comes from TensorFlow's official model zoo: +https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf1_detection_zoo.md + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +The test result should be similar to picutre `ref_detect_results.jpg`. + +- Different platforms, different versions of tools and drivers may have slightly different results. +- The color of the detected object box is random. diff --git a/examples/tensorflow/ssd_mobilenet_v1/ref_detect_results.jpg b/examples/tensorflow/ssd_mobilenet_v1/ref_detect_results.jpg new file mode 100644 index 0000000..4c2b4f9 Binary files /dev/null and b/examples/tensorflow/ssd_mobilenet_v1/ref_detect_results.jpg differ diff --git a/examples/tensorflow/ssd_mobilenet_v1/ssd_mobilenet_v1_coco_2017_11_17.pb b/examples/tensorflow/ssd_mobilenet_v1/ssd_mobilenet_v1_coco_2018_01_28.pb similarity index 99% rename from examples/tensorflow/ssd_mobilenet_v1/ssd_mobilenet_v1_coco_2017_11_17.pb rename to examples/tensorflow/ssd_mobilenet_v1/ssd_mobilenet_v1_coco_2018_01_28.pb index 92189ed..d11874e 100644 Binary files a/examples/tensorflow/ssd_mobilenet_v1/ssd_mobilenet_v1_coco_2017_11_17.pb and b/examples/tensorflow/ssd_mobilenet_v1/ssd_mobilenet_v1_coco_2018_01_28.pb differ diff --git a/examples/tensorflow/ssd_mobilenet_v1/test.py b/examples/tensorflow/ssd_mobilenet_v1/test.py index b560a8e..c9c1471 100644 --- a/examples/tensorflow/ssd_mobilenet_v1/test.py +++ b/examples/tensorflow/ssd_mobilenet_v1/test.py @@ -1,5 +1,7 @@ import numpy as np +import platform +import sys import re import math import random @@ -23,7 +25,7 @@ def expit(x): def unexpit(y): - return -1.0 * math.log((1.0 / y) - 1.0); + return -1.0 * math.log((1.0 / y) - 1.0) def CalculateOverlap(xmin0, ymin0, xmax0, ymax0, xmin1, ymin1, xmax1, ymax1): @@ -56,23 +58,47 @@ def load_box_priors(): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # Config for Model Input PreProcess print('--> Config model') - rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], reorder_channel='0 1 2') + rknn.config(mean_values=[[127.5, 127.5, 127.5]], + std_values=[[127.5, 127.5, 127.5]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') - # Load TensorFlow Model + # Load TensorFlow Model (Download from http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2018_01_28.tar.gz) print('--> Loading model') - ret = rknn.load_tensorflow(tf_pb='./ssd_mobilenet_v1_coco_2017_11_17.pb', + ret = rknn.load_tensorflow(tf_pb='./ssd_mobilenet_v1_coco_2018_01_28.pb', inputs=['FeatureExtractor/MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/mul_1'], outputs=['concat', 'concat_1'], input_size_list=[[INPUT_SIZE, INPUT_SIZE, 3]]) if ret != 0: print('Load model failed!') + rknn.release() exit(ret) print('done') @@ -81,6 +107,7 @@ def load_box_priors(): ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build model failed!') + rknn.release() exit(ret) print('done') @@ -89,12 +116,10 @@ def load_box_priors(): rknn.export_rknn('./ssd_mobilenet_v1_coco.rknn') if ret != 0: print('Export RKNN model failed!') + rknn.release() exit(ret) print('done') - # Direct Load RKNN Model - # rknn.load_rknn('./ssd_mobilenet_v1_coco.rknn') - # Set inputs orig_img = cv2.imread('./road.bmp') img = cv2.cvtColor(orig_img, cv2.COLOR_BGR2RGB) @@ -102,9 +127,14 @@ def load_box_priors(): # init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') @@ -128,7 +158,7 @@ def load_box_priors(): # Skip the first catch-all class. for j in range(1, NUM_CLASSES): - score = expit(outputClasses[0][i][j]); + score = expit(outputClasses[0][i][j]) if score > topClassScore: topClassScoreIndex = j @@ -203,12 +233,8 @@ def load_box_priors(): cv2.rectangle(orig_img, (int(xmin), int(ymin)), (int(xmax), int(ymax)), (random.random()*255, random.random()*255, random.random()*255), 3) - cv2.imwrite("out.jpg", orig_img) - - # Evaluate Perf on Simulator - print('--> Evaluate model performance') - rknn.eval_perf(inputs=[img], is_print=True) - print('done') + cv2.imwrite("results.jpg", orig_img) + print("The detection results have been saved to results.jpg") # Release RKNN Context rknn.release() diff --git a/examples/tflite/mobilenet_v1/README.md b/examples/tflite/mobilenet_v1/README.md new file mode 100644 index 0000000..3098e98 --- /dev/null +++ b/examples/tflite/mobilenet_v1/README.md @@ -0,0 +1,46 @@ +# Example for TFLite mobilenet_v1 + + +## Model Source +The model used in this example come from the TensorFlow Lite offical model zoo: +https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet_v1.md + + +## Usage for the script + +*Usage:* +``` +python test.py [target] [device_id] +``` +*Parameter Description:* +- target: target platform. Optional parameter, the default value is `rv1126`, you can fill in `rk1806`, `rk1808`, `rk3399pro`, `rv1109`, `rv1126`. +- device_id: Device ID, when multiple devices are connected, this parameter is used to distinguish them. Optional parameter, default value is None. + +If the target device is `RV1109` or `RV1126`, you can directly execute the following command to run the example: +``` +python test.py +``` +If the target device is RK1806, RK1808 or RK3399Pro, you can execute the following command to run the example: +``` +python test.py rk1808 +``` +If you connect multiple devices, you need to specify the device ID, please refer to the following command to run the example: +``` +python test.py rv1126 c3d9b8674f4b94f6 +``` + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +[156]: 0.8515625 +[155]: 0.091796875 +[205]: 0.0135955810546875 +[284]: 0.0064697265625 +[194 260]: 0.002239227294921875 +``` + +1. The label index with the highest score is 156, the corresponding label is `Pekinese, Pekingese, Peke`. +2. The labels used in this model contains background, download link of labels file: https://github.com/leferrad/tensorflow-mobilenet/blob/master/imagenet/labels.txt +3. Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/examples/tflite/mobilenet_v1/test.py b/examples/tflite/mobilenet_v1/test.py index 11d7293..0f18874 100644 --- a/examples/tflite/mobilenet_v1/test.py +++ b/examples/tflite/mobilenet_v1/test.py @@ -1,3 +1,5 @@ +import platform +import sys import numpy as np import cv2 from rknn.api import RKNN @@ -22,13 +24,36 @@ def show_outputs(outputs): if __name__ == '__main__': + # Default target and device_id + target = 'rv1126' + device_id = None + + # Parameters check + if len(sys.argv) == 1: + print("Using default target rv1126") + elif len(sys.argv) == 2: + target = sys.argv[1] + print('Set target: {}'.format(target)) + elif len(sys.argv) == 3: + target = sys.argv[1] + device_id = sys.argv[2] + print('Set target: {}, device_id: {}'.format(target, device_id)) + elif len(sys.argv) > 3: + print('Too much arguments') + print('Usage: python {} [target] [device_id]'.format(sys.argv[0])) + print('Such as: python {} rv1126 c3d9b8674f4b94f6'.format( + sys.argv[0])) + exit(-1) # Create RKNN object rknn = RKNN() # pre-process config print('--> config model') - rknn.config(mean_values=[[127.5, 127.5, 127.5]], std_values=[[127.5, 127.5, 127.5]], reorder_channel='0 1 2') + rknn.config(mean_values=[[127.5, 127.5, 127.5]], + std_values=[[127.5, 127.5, 127.5]], + reorder_channel='0 1 2', + target_platform=[target]) print('done') # Load TFLite model @@ -36,14 +61,16 @@ def show_outputs(outputs): ret = rknn.load_tflite(model='./mobilenet_v1.tflite') if ret != 0: print('Load mobilenet_v1 failed!') + rknn.release() exit(ret) print('done') # Build model print('--> Building model') - ret = rknn.build(do_quantization=True, dataset='./dataset.txt', pre_compile=False) + ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build mobilenet_v1 failed!') + rknn.release() exit(ret) print('done') @@ -52,6 +79,7 @@ def show_outputs(outputs): ret = rknn.export_rknn('./mobilenet_v1.rknn') if ret != 0: print('Export mobilenet_v1.rknn failed!') + rknn.release() exit(ret) print('done') @@ -61,9 +89,14 @@ def show_outputs(outputs): # Init runtime environment print('--> Init runtime environment') - ret = rknn.init_runtime() + if target.lower() == 'rk3399pro' and platform.machine() == 'aarch64': + print('Run demo on RK3399Pro, using default NPU.') + target = None + device_id = None + ret = rknn.init_runtime(target=target, device_id=device_id) if ret != 0: print('Init runtime environment failed') + rknn.release() exit(ret) print('done') @@ -73,10 +106,5 @@ def show_outputs(outputs): show_outputs(outputs) print('done') - # perf - print('--> Evaluate model performance') - perf_results = rknn.eval_perf(inputs=[img]) - print('done') - rknn.release() diff --git a/packages/README.md b/packages/README.md index 6e16e91..92cd8b1 100644 --- a/packages/README.md +++ b/packages/README.md @@ -3,21 +3,21 @@ Prior to version 1.3.0, all wheel packages of rknn-toolkit were placed in this d Since version 1.3.0, because some wheel packages are larger than 100MB and cannot be uploaded directly to github, you need to go to the releases page to download. # Download You can download from releases page: https://github.com/rockchip-linux/rknn-toolkit/releases -- All wheel packages are in compressed file: [rknn-toolkit-v1.7.3-packages.tar.gz](https://github.com/rockchip-linux/rknn-toolkit/releases/download/v1.7.3/rknn-toolkit-v1.7.3-packages.tar.gz "rknn-toolkit-v1.7.3-packages.tar.gz") or [rknn-toolkit-v1.7.3-packages.zip](https://github.com/rockchip-linux/rknn-toolkit/releases/download/v1.7.3/rknn-toolkit-v1.7.3-packages.zip "rknn-toolkit-v1.7.3-packages.zip ") -- All examples, docs and platform-tools are in compressed file: [Source code(zip)](https://github.com/rockchip-linux/rknn-toolkit/archive/v1.7.3.zip "Source code(zip)") or [Source code(tar.gz)](https://github.com/rockchip-linux/rknn-toolkit/archive/v1.7.3.tar.gz "Source code(tar.gz)") +- All wheel packages are in compressed file: [rknn-toolkit-v1.7.5-packages.tar.gz](https://github.com/rockchip-linux/rknn-toolkit/releases/download/v1.7.5/rknn-toolkit-v1.7.5-packages.tar.gz "rknn-toolkit-v1.7.5-packages.tar.gz") or [rknn-toolkit-v1.7.5-packages.zip](https://github.com/rockchip-linux/rknn-toolkit/releases/download/v1.7.5/rknn-toolkit-v1.7.5-packages.zip "rknn-toolkit-v1.7.5-packages.zip ") +- All examples, docs and platform-tools are in compressed file: [Source code(zip)](https://github.com/rockchip-linux/rknn-toolkit/archive/v1.7.5.zip "Source code(zip)") or [Source code(tar.gz)](https://github.com/rockchip-linux/rknn-toolkit/archive/v1.7.5.tar.gz "Source code(tar.gz)") # Checksums ## MD5 ``` -7d672e911c26af34112bbfcfed86aef7 rknn_toolkit-1.7.3-cp35-cp35m-linux_aarch64.whl -e751a1c2782879dedbe3904448e07105 rknn_toolkit-1.7.3-cp36-cp36m-linux_x86_64.whl -20db420731b4976b15b0fbddef9984e3 rknn_toolkit-1.7.3-cp36-cp36m-macosx_10_15_x86_64.whl -1ebba11b78766cd320a470bb397578cb rknn_toolkit-1.7.3-cp36-cp36m-win_amd64.whl -0cdd9c288a748bcef84848fd5dc12d80 rknn_toolkit-1.7.3-cp37-cp37m-linux_aarch64.whl -f06e1f88864c5a4759e4258cb536c38d rknn_toolkit-1.7.3-cp37-cp37m-macosx_10_15_x86_64.whl -8e5c63a241b809b78ca65d226344d0eb rknn_toolkit-1.7.3-cp38-cp38-linux_x86_64.whl +055ea6bc3b82cd437ebe645076c66960 rknn_toolkit-1.7.5-cp35-cp35m-linux_aarch64.whl +dec84a1226a22914e9912f1ce61cad64 rknn_toolkit-1.7.5-cp36-cp36m-linux_x86_64.whl +3a0f2d0cadb58e60f26fe039394205ab rknn_toolkit-1.7.5-cp36-cp36m-macosx_10_15_x86_64.whl +af96a8ab4cffa1037d41deb155e3d92e rknn_toolkit-1.7.5-cp36-cp36m-win_amd64.whl +4511b18f5a3127fb7375c2dddf597641 rknn_toolkit-1.7.5-cp37-cp37m-linux_aarch64.whl +8873a605594264125aa33bdaf2fc08b3 rknn_toolkit-1.7.5-cp37-cp37m-macosx_10_15_x86_64.whl +da4cd1a1968f9e9aa5414a67598f5374 rknn_toolkit-1.7.5-cp38-cp38-linux_x86_64.whl -a24f157407e16bc255fc387404eb2030 rknn-toolkit-v1.7.3-packages.tar.gz -8dbeeecb06b9201b9f464909ad8d9544 rknn-toolkit-v1.7.3-packages.zip +0818a331d3bba755036cfee296bdad31 rknn-toolkit-v1.7.5-packages.tar.gz +f5de735b9b733d74f97db5cce46c2c70 rknn-toolkit-v1.7.5-packages.zip ``` diff --git a/packages/packages.md5sum b/packages/packages.md5sum index 2ec1db4..659852d 100644 --- a/packages/packages.md5sum +++ b/packages/packages.md5sum @@ -1,7 +1,7 @@ -7d672e911c26af34112bbfcfed86aef7 rknn_toolkit-1.7.3-cp35-cp35m-linux_aarch64.whl -e751a1c2782879dedbe3904448e07105 rknn_toolkit-1.7.3-cp36-cp36m-linux_x86_64.whl -20db420731b4976b15b0fbddef9984e3 rknn_toolkit-1.7.3-cp36-cp36m-macosx_10_15_x86_64.whl -1ebba11b78766cd320a470bb397578cb rknn_toolkit-1.7.3-cp36-cp36m-win_amd64.whl -0cdd9c288a748bcef84848fd5dc12d80 rknn_toolkit-1.7.3-cp37-cp37m-linux_aarch64.whl -f06e1f88864c5a4759e4258cb536c38d rknn_toolkit-1.7.3-cp37-cp37m-macosx_10_15_x86_64.whl -8e5c63a241b809b78ca65d226344d0eb rknn_toolkit-1.7.3-cp38-cp38-linux_x86_64.whl +055ea6bc3b82cd437ebe645076c66960 rknn_toolkit-1.7.5-cp35-cp35m-linux_aarch64.whl +dec84a1226a22914e9912f1ce61cad64 rknn_toolkit-1.7.5-cp36-cp36m-linux_x86_64.whl +3a0f2d0cadb58e60f26fe039394205ab rknn_toolkit-1.7.5-cp36-cp36m-macosx_10_15_x86_64.whl +af96a8ab4cffa1037d41deb155e3d92e rknn_toolkit-1.7.5-cp36-cp36m-win_amd64.whl +4511b18f5a3127fb7375c2dddf597641 rknn_toolkit-1.7.5-cp37-cp37m-linux_aarch64.whl +8873a605594264125aa33bdaf2fc08b3 rknn_toolkit-1.7.5-cp37-cp37m-macosx_10_15_x86_64.whl +da4cd1a1968f9e9aa5414a67598f5374 rknn_toolkit-1.7.5-cp38-cp38-linux_x86_64.whl diff --git a/packages/requirements-cpu-ubuntu20.04_py38.txt b/packages/requirements-cpu-ubuntu20.04_py38.txt index 7047f85..5f0b286 100644 --- a/packages/requirements-cpu-ubuntu20.04_py38.txt +++ b/packages/requirements-cpu-ubuntu20.04_py38.txt @@ -1,4 +1,4 @@ tensorflow==2.2.0 -torch==1.9.0 -torchvision==0.10.0 +torch==1.10.0 +torchvision==0.11.0 mxnet==1.5.0 diff --git a/packages/requirements-cpu.txt b/packages/requirements-cpu.txt index 4a88f6b..e4f36dc 100644 --- a/packages/requirements-cpu.txt +++ b/packages/requirements-cpu.txt @@ -1,4 +1,4 @@ tensorflow==1.14.0 -torch==1.9.0 -torchvision==0.10.0 +torch==1.10.0 +torchvision==0.11.0 mxnet==1.5.0 diff --git a/packages/requirements-gpu.txt b/packages/requirements-gpu.txt index c485884..5a22976 100644 --- a/packages/requirements-gpu.txt +++ b/packages/requirements-gpu.txt @@ -1,4 +1,4 @@ tensorflow-gpu==1.14.0 -torch==1.9.0 -torchvision==0.10.0 +torch==1.10.0 +torchvision==0.11.0 mxnet-cu101==1.5.0 diff --git a/rknn-toolkit-lite/examples/inference_with_lite/README.md b/rknn-toolkit-lite/examples/inference_with_lite/README.md new file mode 100644 index 0000000..7163ae5 --- /dev/null +++ b/rknn-toolkit-lite/examples/inference_with_lite/README.md @@ -0,0 +1,39 @@ +# Example of model inference with RKNN Toolkit Lite + + +## Model Source + +The models used in this example come from the torchvision project: +https://github.com/pytorch/vision/tree/main/torchvision/models + +For model conversion, please refer to the following example: +https://github.com/rockchip-linux/rknn-toolkit/tree/master/examples/pytorch/resnet18 + + +## Usage for the script + +*Usage:* +``` +python test.py +``` + +- If run this example on a PC, please connect a RK1808 development board. +- If there are multiple devices, please modify the script to specify `device_id` in the `init_runtime` interface. +- If run the example on(or with) rv1109/1126, please adjust the `model` and `target` in script. + + +## Expected results + +This example will print the TOP5 labels and corresponding scores of the test image classification results. For example, the inference results of this example are as follows: +``` +-----TOP 5----- +[812]: 0.9994382262229919 +[404]: 0.00040962465573102236 +[657]: 3.284523336333223e-05 +[833]: 2.928587309725117e-05 +[895]: 1.850978151196614e-05 +``` + +1. The label index with the highest score is 812, the corresponding label is `space shuttle`. +2. The download link for labels file: https://s3.amazonaws.com/onnx-model-zoo/synset.txt +3. Different platforms, different versions of tools and drivers may have slightly different results. diff --git a/rknn-toolkit-lite/examples/inference_with_lite/resnet_18.rknn b/rknn-toolkit-lite/examples/inference_with_lite/resnet18_rk180x.rknn similarity index 100% rename from rknn-toolkit-lite/examples/inference_with_lite/resnet_18.rknn rename to rknn-toolkit-lite/examples/inference_with_lite/resnet18_rk180x.rknn diff --git a/rknn-toolkit-lite/examples/inference_with_lite/resnet18_rv1109_rv1126.rknn b/rknn-toolkit-lite/examples/inference_with_lite/resnet18_rv1109_rv1126.rknn new file mode 100644 index 0000000..5e26d1c Binary files /dev/null and b/rknn-toolkit-lite/examples/inference_with_lite/resnet18_rv1109_rv1126.rknn differ diff --git a/rknn-toolkit-lite/examples/inference_with_lite/test.py b/rknn-toolkit-lite/examples/inference_with_lite/test.py index aea8149..d22ae64 100644 --- a/rknn-toolkit-lite/examples/inference_with_lite/test.py +++ b/rknn-toolkit-lite/examples/inference_with_lite/test.py @@ -29,9 +29,20 @@ def show_top5(result): if __name__ == '__main__': rknn_lite = RKNNLite() + if platform.machine() == 'aarch64': + target = None + model = './resnet18_rk180x.rknn' + elif platform.machine() == 'armv7l': + target = None + model = './resnet18_rv1109_rv1126.rknn' + else: + print('Please run on PC. The default device is RK1808, if not, please specify the target and model path in script: test.py.') + target = 'rk1808' + model = './resnet18_rk180x.rknn' + # load RKNN model print('--> Load RKNN model') - ret = rknn_lite.load_rknn('./resnet_18.rknn') + ret = rknn_lite.load_rknn(model) if ret != 0: print('Load RKNN model failed') exit(ret) @@ -42,11 +53,6 @@ def show_top5(result): # init runtime environment print('--> Init runtime environment') - # run on RK3399Pro/RK1808 with Debian OS, do not need specify target. - if platform.machine() == 'aarch64': - target = None - else: - target = 'rk1808' ret = rknn_lite.init_runtime(target=target) if ret != 0: print('Init runtime environment failed') diff --git a/rknn-toolkit-lite/packages/packages.md5sum b/rknn-toolkit-lite/packages/packages.md5sum index c95ebf1..9b48efa 100644 --- a/rknn-toolkit-lite/packages/packages.md5sum +++ b/rknn-toolkit-lite/packages/packages.md5sum @@ -1,8 +1,13 @@ -4b50d8966908e80567843c3623e33d46 rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_aarch64.whl -dc669361506646104e823d569055b849 rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_x86_64.whl -15a26aad303769f8f2f38f5888529a57 rknn_toolkit_lite-1.7.3-cp36-cp36m-macosx_10_15_x86_64.whl -cd490d13dc1e40e24ab76100a9b82ced rknn_toolkit_lite-1.7.3-cp36-cp36m-win_amd64.whl -17f10789ec42fdc687c3c02ef6dc1141 rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_aarch64.whl -030a09ed522620aa6dfb4ccac578518b rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_armv7l.whl -079aaf9c2c39b2c2a6858688ed733973 rknn_toolkit_lite-1.7.3-cp37-cp37m-macosx_10_15_x86_64.whl -b1b32a4e8803dd9303ab1a72ae8deccf rknn_toolkit_lite-1.7.3-cp38-cp38-linux_x86_64.whl +7adbd9698c7b528413d0ba73b591c83f rknn_toolkit_lite-1.7.5-cp310-cp310-linux_aarch64.whl +3457be77486bcd70c66213f46ce223e3 rknn_toolkit_lite-1.7.5-cp35-cp35m-linux_aarch64.whl +5d1ed1ac6dff669be03578ce39787eea rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_aarch64.whl +2f15ccb2c4140a436d5dfbc8e9544630 rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_armv7l.whl +210fe992928bd57ff638d346e394a5f2 rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_x86_64.whl +16b13b9b710b90f2de10c820180f1c51 rknn_toolkit_lite-1.7.5-cp36-cp36m-macosx_10_15_x86_64.whl +27012b2aa02b78a3720bf9d34e5a42cf rknn_toolkit_lite-1.7.5-cp36-cp36m-win_amd64.whl +90d1f4c19552837a60e7d713c8b86e01 rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_aarch64.whl +0dbfe4e8fc4a50c95d5f8114e379bce5 rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_armv7l.whl +82e046302a2527bec6ebbd957446e8e6 rknn_toolkit_lite-1.7.5-cp37-cp37m-macosx_10_15_x86_64.whl +efe50cbb488c49f4953ff156caef6d07 rknn_toolkit_lite-1.7.5-cp38-cp38-linux_aarch64.whl +59f3f1df13bad289daadab276684c8df rknn_toolkit_lite-1.7.5-cp38-cp38-linux_x86_64.whl +63868f54eae2c98da69679abf4710881 rknn_toolkit_lite-1.7.5-cp39-cp39-linux_aarch64.whl diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_aarch64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_aarch64.whl deleted file mode 100644 index b78cb77..0000000 Binary files a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_aarch64.whl and /dev/null differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_aarch64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_aarch64.whl deleted file mode 100644 index 529298a..0000000 Binary files a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_aarch64.whl and /dev/null differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_armv7l.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_armv7l.whl deleted file mode 100644 index ab2c760..0000000 Binary files a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-linux_armv7l.whl and /dev/null differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp310-cp310-linux_aarch64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp310-cp310-linux_aarch64.whl new file mode 100644 index 0000000..7c5fd8d Binary files /dev/null and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp310-cp310-linux_aarch64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp35-cp35m-linux_aarch64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp35-cp35m-linux_aarch64.whl new file mode 100644 index 0000000..9ef0575 Binary files /dev/null and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp35-cp35m-linux_aarch64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_aarch64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_aarch64.whl new file mode 100644 index 0000000..538800b Binary files /dev/null and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_aarch64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_armv7l.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_armv7l.whl new file mode 100644 index 0000000..b2395dc Binary files /dev/null and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_armv7l.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_x86_64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_x86_64.whl similarity index 96% rename from rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_x86_64.whl rename to rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_x86_64.whl index cdc8951..3ce58a9 100644 Binary files a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-linux_x86_64.whl and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-linux_x86_64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-macosx_10_15_x86_64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-macosx_10_15_x86_64.whl similarity index 76% rename from rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-macosx_10_15_x86_64.whl rename to rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-macosx_10_15_x86_64.whl index c5f52bc..c75797a 100644 Binary files a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-macosx_10_15_x86_64.whl and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-macosx_10_15_x86_64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-win_amd64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-win_amd64.whl similarity index 83% rename from rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-win_amd64.whl rename to rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-win_amd64.whl index dcd58a4..c4cca40 100644 Binary files a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp36-cp36m-win_amd64.whl and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp36-cp36m-win_amd64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_aarch64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_aarch64.whl new file mode 100644 index 0000000..f386b88 Binary files /dev/null and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_aarch64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_armv7l.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_armv7l.whl new file mode 100644 index 0000000..e7891c3 Binary files /dev/null and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-linux_armv7l.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-macosx_10_15_x86_64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-macosx_10_15_x86_64.whl similarity index 72% rename from rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-macosx_10_15_x86_64.whl rename to rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-macosx_10_15_x86_64.whl index 8093f64..e7bd2c7 100644 Binary files a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp37-cp37m-macosx_10_15_x86_64.whl and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp37-cp37m-macosx_10_15_x86_64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp38-cp38-linux_aarch64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp38-cp38-linux_aarch64.whl new file mode 100644 index 0000000..5d977d1 Binary files /dev/null and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp38-cp38-linux_aarch64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp38-cp38-linux_x86_64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp38-cp38-linux_x86_64.whl similarity index 96% rename from rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp38-cp38-linux_x86_64.whl rename to rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp38-cp38-linux_x86_64.whl index 7546f94..cf0926a 100644 Binary files a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.3-cp38-cp38-linux_x86_64.whl and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp38-cp38-linux_x86_64.whl differ diff --git a/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp39-cp39-linux_aarch64.whl b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp39-cp39-linux_aarch64.whl new file mode 100644 index 0000000..4414942 Binary files /dev/null and b/rknn-toolkit-lite/packages/rknn_toolkit_lite-1.7.5-cp39-cp39-linux_aarch64.whl differ