Browse Source

[rknn toolkit2 version update] Update to version 1.2.0

pull/53/head
Jie 4 years ago
parent
commit
58fb25e1e3
  1. 17
      README.md
  2. 261
      doc/RKNNToolKit2_OP_Support-1.1.0.md
  3. 240
      doc/RKNNToolKit2_OP_Support-1.2.0.md
  4. 337
      doc/RRKNNToolKit2_API_Difference_With_Toolkit1-1.2.0.md
  5. BIN
      doc/Rockchip_Quick_Start_RKNN_Toolkit2_CN-1.1.0.pdf
  6. BIN
      doc/Rockchip_Quick_Start_RKNN_Toolkit2_CN-1.2.0.pdf
  7. BIN
      doc/Rockchip_Quick_Start_RKNN_Toolkit2_EN-1.1.0.pdf
  8. BIN
      doc/Rockchip_Quick_Start_RKNN_Toolkit2_EN-1.2.0.pdf
  9. BIN
      doc/Rockchip_User_Guide_RKNN_Toolkit2_CN-1.1.0.pdf
  10. BIN
      doc/Rockchip_User_Guide_RKNN_Toolkit2_CN-1.2.0.pdf
  11. BIN
      doc/Rockchip_User_Guide_RKNN_Toolkit2_EN-1.1.0.pdf
  12. BIN
      doc/Rockchip_User_Guide_RKNN_Toolkit2_EN-1.2.0.pdf
  13. 16
      doc/changelog-1.2.0.txt
  14. 4
      doc/requirements_cp36-1.2.0.txt
  15. 21
      examples/caffe/mobilenet_v2/dataset.txt
  16. 0
      examples/caffe/mobilenet_v2/dog_224x224.jpg
  17. BIN
      examples/caffe/mobilenet_v2/goldfish_224x224.jpg
  18. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00000665.JPEG
  19. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00001123.JPEG
  20. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00001129.JPEG
  21. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00001284.JPEG
  22. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00003026.JPEG
  23. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00005276.JPEG
  24. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00006178.JPEG
  25. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00007829.JPEG
  26. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00009338.JPEG
  27. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00010420.JPEG
  28. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00011240.JPEG
  29. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00011878.JPEG
  30. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00012037.JPEG
  31. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00012351.JPEG
  32. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00012470.JPEG
  33. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00020169.JPEG
  34. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00020173.JPEG
  35. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00021224.JPEG
  36. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00024249.JPEG
  37. BIN
      examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00025601.JPEG
  38. 27
      examples/caffe/mobilenet_v2/test.py
  39. 110
      examples/caffe/vgg-ssd/test.py
  40. 27
      examples/darknet/yolov3_416x416/test.py
  41. 17
      examples/functions/accuracy_analysis/test.py
  42. 21
      examples/functions/batch_size/test.py
  43. 1
      examples/functions/board_test/dataset.txt
  44. BIN
      examples/functions/board_test/dog_224x224.jpg
  45. 106
      examples/functions/board_test/test.py
  46. 15
      examples/functions/hybrid_quant/step1.py
  47. 19
      examples/functions/hybrid_quant/step2.py
  48. 23
      examples/functions/mmse/test.py
  49. 18
      examples/functions/multi_input_test/test.py
  50. 18
      examples/onnx/resnet50v2/test.py
  51. BIN
      examples/onnx/yolov5/bus.jpg
  52. 2
      examples/onnx/yolov5/dataset.txt
  53. BIN
      examples/onnx/yolov5/dog_bike_car_640x640.jpg
  54. 521
      examples/onnx/yolov5/test.py
  55. BIN
      examples/onnx/yolov5/yolov5s.onnx
  56. 23
      examples/pytorch/resnet18/test.py
  57. 86
      examples/pytorch/resnet18_export_onnx/test.py
  58. BIN
      examples/pytorch/resnet18_qat/resnet18_i8.pt
  59. BIN
      examples/pytorch/resnet18_qat/space_shuttle_224.jpg
  60. 103
      examples/pytorch/resnet18_qat/test.py
  61. 0
      examples/tensorflow/inception_v3_qat/README.md
  62. 0
      examples/tensorflow/inception_v3_qat/goldfish_299x299.jpg
  63. 29
      examples/tensorflow/inception_v3_qat/test.py
  64. 54
      examples/tensorflow/ssd_mobilenet_v1/test.py
  65. 20
      examples/tflite/mobilenet_v1/test.py
  66. BIN
      examples/tflite/mobilenet_v1_qat/dog_224x224.jpg
  67. 0
      examples/tflite/mobilenet_v1_qat/mobilenet_v1_1.0_224_quant.tflite
  68. 24
      examples/tflite/mobilenet_v1_qat/test.py
  69. BIN
      packages/rknn_toolkit2-1.2.0_f7bb160f-cp36-cp36m-linux_x86_64.whl

17
README.md

@ -1,18 +1,27 @@ @@ -1,18 +1,27 @@
# Introduction
RKNN-Toolkit2 is a software development kit for users to perform model conversion, inference and performance evaluation on PC, RK3566, RK3568, RK3588(not support yet).
RKNN-Toolkit2 is a software development kit for users to perform model conversion, inference and performance evaluation on PC and Rockchip NPU platforms (RK3566, RK3568, RK3588, RK3588S).
RKNN-Toolkit-Lite2 provides Python programming interfaces for Rockchip NPU platform (RK3566, RK3568, RK3588, RK3588S) to help users deploy RKNN models and accelerate the implementation of AI applications.
# Download
- You can also download all packages, docker image, examples, docs and platform-tools from baidu cloud: [rknn-toolkit2-v1.1.1](https://eyun.baidu.com/s/3jJLf6V8 "rknn-toolkit2-v1.1.0"), fetch code: rknn2
- You can also download all packages, docker image, examples, docs and platform-tools from baidu cloud: [rknn-toolkit2-v1.2.0](https://eyun.baidu.com/s/3jJ4k51s), fetch code: rknn
# Notes
- Currently rknn-toolkit2 is not compatible with [rknn-toolkit](https://github.com/rockchip-linux/rknn-toolkit)
- Currently only support on Ubuntu 18.04 python 3.6
- If you have problem about RKNN-Toolkit2, it is recommended to create a issue or get answers from [Issues](https://github.com/rockchip-linux/rknn-toolkit2/issues).
- Latest version:1.1.1(belongs parent version 1.1.0)
- Latest version:1.2.0(Release version)
# Checksums
## MD5
```
5fcda062d22af0d4ee766c81b64bdf12 rknn_toolkit2-1.1.1_5c458c6-cp36-cp36m-linux_x86_64.whl
148f076c8707b066307f169975259bbb rknn_toolkit2-1.2.0_f7bb160f-cp36-cp36m-linux_x86_64.whl
fdf38d4ec4a8a0ac3c9faeba38baa908 rknn-toolkit2-1.2.0-cp36-docker.tar.gz
e4430d25066487172a4a861b04098495 rknn_toolkit_lite2-1.2.0-cp37-cp37m-linux_aarch64.whl
dd9f5509d3342b6cbc52d5814d0909d3 rknn_toolkit_lite2-1.2.0-cp39-cp39-linux_aarch64.whl
```
# Feedback and Community Suport
Two ways are followed:

261
doc/RKNNToolKit2_OP_Support-1.1.0.md

@ -1,261 +0,0 @@ @@ -1,261 +0,0 @@
# RKNNToolkit2 OPs Support
Based on RKNN Toolkit2 Version 1.1.0
## Explanation of terms:
Remarks:
Operators' specifications must meet the remarks' requirements.
Broadcast rule:
- per-layer:
shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar ==> shape(result) = (2, 3, 4, 5)
- per-channel:
shape(A) = (2, 3, 4, 5), shape(B) = (3,), ==> shape(result) = (2, 3, 4, 5)
shape(A) = (2, 3, 4, 5), shape(B) = (1,3,1,1), ==> shape(result) = (2, 3, 4, 5)
- per-element:
shape(A) = (2, 3, 4, 5), shape(B) = (2,3,4,5) ==> shape(result) = (2, 3, 4, 5)
- other:
shape(A) = (2, 3, 4, 5), shape(B) = (5,) ==> shape(result) = (2, 3, 4, 5)
## Caffe OPs supported by RKNN Toolkit2
Caffe protocols RKNN Toolkit2 uses only based on the officially modified protocol of berkeley.
The protocol based on the official revision of berkeley comes from [berkeley caffe](https://github.com/BVLC/caffe/tree/master/src/caffe/proto 'Berkeley Caffe'), commit hash is 21d0608. On this basis RKNN Toolkit2 have added some OPs.
Based on this protocol, the list of Caffe OPs supported by RKNN Toolkit2 Version 1.1.0 is as follows:
| **Operators** | **Remarks** |
| -------------------- | ----------- |
| BatchNorm |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| bn (BatchNorm + Scale) |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br /> according to https://github.com/TimoSaemann/caffe-segnet-cudnn5|
| BNLL ||
| Concat |axis: 1,2,3|
| Convolution |channel: [1, 8192]<br />kernel height/width: [1, 31]<br />stride height/width: [1, 7]<br />kernels: [1, 8184]<br />pad left/right/top/bottom: [0, 15]<br />group: 1, channel / N <br /><br />|
| ConvolutionDepthwise|channel:[1, 8192]<br />kernel height/width: [1, 8]<br />stride height/width: [1, 7]<br />kernels: 1<br />pad left/right/top/bottom: [0, 15]|
| Crop ||
| Deconvolution |channel: [1, 8192]<br />kernel height/width: [1, 31]<br />stride height/width: 2, 4, 8<br />kernels: [1, 8192]<br />pad left/right/top/bottom: [0, 15]|
| Dropout ||
| Eltwise |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element|
| Flatten ||
| InnerProduct |channel: [1, 8192]|
| LRN ||
| Normalize ||
| Permute ||
| Power ||
| Pooling | **AveragePool**:<br />channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br /><br />**GlobalAveragePool**:<br />channel: [1, 8192]<br />kernel height/width: [1, 128]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7] <br /><br />**MaxPool/GlobalMaxPool**:<br />channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br /><br />**MaxPool**: <br />auto_pad only support NOTSET,ceil_mode only support 0,unsupport dilations |
| PRelu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />slope: per-layer/channel|
| Proposal |batch: 1|
| Reduction |output dims <= 4|
| Relu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Relu6 |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Reorg ||
| Reshape ||
| Resize |bilinear; nearest|
| Reverse ||
| ROIPooling |according to https://github.com/twmht/caffe-pva-faster-rcnn|
| Scale |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Sigmoid |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Slice ||
| Softmax ||
| Split ||
| TanH |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Tile ||
| Transpose ||
| Upsample |according to https://github.com/SeanQ88/caffe_upsample and https://github.com/TimoSaemann/caffe-segnet-cudnn5|
## ONNX OPs supported by RKNN Toolkit2
The ONNX version supported by RKNN Toolkit2 is 1.1.0. According to [ONNX official instructions](https://github.com/microsoft/onnxruntime/blob/master/docs/Versioning.md 'ONNX Version Description'), the corresponding ONNX opset version is 12.
The list of ONNX OPs supported by RKNN Toolkit2 Version 1.1.0 is as follows:
| **Operators** | **Remarks** |
| ----------------------------- | ----------- |
| Add |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element|
| AveragePool |channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]|
| ArgMin ||
| ArgMax ||
| ReduceMin ||
| ReduceMax ||
| BatchNormalization |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Clip |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Concat |axis: 1,2,3|
| Conv |channel: [1, 8192]<br />kernel height/width: [1, 31]<br />stride height/width: [1, 7]<br />kernels: [1, 8184]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: 1, channel / N|
| ConvTranspose |channel: [1, 8192]<br />kernel height/width: [1, 31]<br />stride height/width: 2, 4, 8<br />kernels: [1, 8192]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: 1, channel / N|
| DepthToSpace ||
| Div |support broadcast rule: per-element/other|
| Flatten ||
| Gather ||
| Gemm |channel: [1, 8192]<br /> One input should be Const|
| GlobalAveragePool |channel: [1, 8192]<br />kernel height/width: [1, 128]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]|
| GlobalMaxPool |channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]|
| Greater |support broadcast rule: per-element/other|
| HardSigmoid ||
| LeakyRelu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Less |support broadcast rule: per-element/other|
| LpNormalization ||
| LRN ||
| MatMul |channel: [1, 8192]<br />dims: 2|
| Max |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br /> dims=4|
| MaxPool |channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br />auto_pad only support NOTSET,ceil_mode only support 0,unsupport dilations|
| MaxRoiPool ||
| MaxUnpool |unsupport pad|
| Mul |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element|
| Pad |pad value should >= 0; pad dims must be 2 when mode is reflect or edge|
| Pow ||
| PRelu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />slope support broadcast rule:: per-layer/channel|
| ReduceMean |output dims <= 4|
| ReduceSum |output dims <= 4|
| Relu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Reshape ||
| Resize |bilinear(not support tf_crop_and_resize); nearest2d|
| ReverseSequence ||
| RoiAlign |pool type: average|
| Slice ||
| Softmax ||
| SpaceToDetph ||
| Split ||
| Squeeze ||
| Tanh |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Tile ||
| Transpose ||
| Upsample (resize) ||
## Pytorch OPs supported by RKNN Toolkit2
The Pytorch version supported by RKNN Toolkit2 is 1.6.0, models generated by other versions may not support.
The list of Pytorch OPs supported by RKNN Toolkit2 Version 1.1.0 is as follows:
| **Operators** | **Remarks** |
| ------------------------- | ----------- |
| aten::_convolution |channel: [1, 8192]<br />kernel height/width: [1, 31]<br />stride height/width: [1, 7]<br />kernels: [1, 8184]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: 1, channel / N|
| aten::add |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element |
| aten::avg_pool2d |channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]|
| aten::batch_norm |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| aten::cat |axis: 1,2,3|
| aten::dropout ||
| aten::flatten ||
| aten::leaky_relu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| aten::matmul |channel: [1, 8192]<br />dims: 2|
| aten::max_pool2d |channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br />auto_pad only support NOTSET,ceil_mode only support 0,unsupport dilations|
| aten::mean |output dims <= 4|
| aten::mul |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element |
| aten::pad |pad value should >= 0; pad dims must be 2 when mode is reflect or edge|
| aten::permute ||
| aten::prelu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />slope support broadcast rule:: per-layer/channel|
| aten::relu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| aten::reshape ||
| aten::sigmoid ||
| aten::slice ||
| aten::softmax ||
| aten::squeeze ||
| aten::sum |output dims <= 4|
| aten::upsample_bilinear2d ||
| aten::upsample_nearest2d ||
| aten::view ||
## TensorFlow OPs supported by RKNN Toolkit2
The pb files (contain OPs belows) generated by TensorFlow version 1.12 - 1.15 are supported by RKNN Toolkit2. For more information on TensorFlow version compatibility, please refer to [tensorflow official instructions on OP version](https://www.tensorflow.org/guide/versions 'Tensorflow official instructions on OP version') .
The list of TensorFlow OPs supported by RKNN Toolkit2 is as follows:
| **Operators** | **Remarks** |
| ---------------------------------- | ----------- |
| AvgPool |channel: [1, 8192]<br>kernel height/width: [1, 7]<br>stride height/width: [1, 8]<br>pad left/right/top/bottom: [0, 7]|
| Concat |axis: 1,2,3|
| Conv2D |channel: [1, 8192]<br>kernel height/width: [1, 31]<br />stride height/width: [1, 7]<br />kernels: [1, 8184]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: 1, channel / N|
| DepthToSpace ||
| DepthwiseConv2d |channel:[1, 8192]<br />kernel height/width: [1, 8]<br />stride height/width: [1, 7]<br />kernels: 1<br />pad left/right/top/bottom: [0, 15]|
| Div |support broadcast rule: per-element/other|
| Dropout ||
| Flatten ||
| LeakyRelu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Less |support broadcast rule: per-element/other|
| LRN ||
| MatMul |channel: [1, 8192]<br />dims: 2|
| MaxPool |channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br />auto_pad only support NOTSET,ceil_mode only support 0,unsupport dilations|
| Mean |output dims <= 4|
| Pad |pad value should >= 0; pad dims must be 2 when mode is reflect or edge|
| Relu |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Reshape ||
| ResizeBilinear ||
| ResizeNearestNeighbor ||
| Sigmoid ||
| Slice ||
| Softmax ||
| Softplus ||
| SpaceToDepth ||
| Split ||
| Squeeze ||
| StridedSlice ||
| Tanh |channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
| Transpose ||
## TensorFlow Lite OPs supported by RKNN Toolkit2
RKNN Toolkit2 uses the TF Lite schema commits in link:
https://github.com/tensorflow/tensorflow/commits/master/tensorflow/lite/schema/schema.fbs
Commit hash: 0c4f5dfea4ceb3d7c0b46fc04828420a344f7598.
Because TF Lite schema may not compatible with each other, TF Lite models with older or newer schema may not be loaded successfully.
The list of TensorFlow Lite OPs supported by RKNN Toolkit2 is as follows:
| **Operators** | **Remarks** |
|---| ----------- |
|ADD|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element |
|AVERAGE_POOL_2D|channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]|
|CONCATENATION|axis: 1,2,3|
|CONV_2D_TRANSPOSE|channel: [1, 8192]<br />kernel height/width: [1, 31]<br />stride height/width: 2, 4, 8<br />kernels: [1, 8192]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: 1, channel / N|
|CONV_2D|channel: [1, 8192]<br />kernel height/width: [1, 31]<br />stride height/width: [1, 7]<br />kernels: [1, 8184]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: 1, channel / N|
|DEPTH_TO_SPACE||
|DEPTHWISE_CONV_2D|channel:[1, 8192]<br />kernel height/width: [1, 8]<br />stride height/width: [1, 7]<br />kernels: 1<br />pad left/right/top/bottom: [0, 15]|
|DIV|support broadcast rule: per-element/other |
|FULLY_CONNECTED|channel: [1, 8192]<br />|
|GREATER|support broadcast rule: per-element/other|
|L2_NORMALIZATION|dims: 4|
|LEAKY_RELU|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
|LESS|support broadcast rule: per-element/other|
|LOCAL_RESPONSE_NORMALIZATION||
|MAX_POOL_2D|channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br />auto_pad only support NOTSET,ceil_mode only support 0,unsupport dilations|
|MUL|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element |
|PAD|pad value should >= 0; pad dims must be 2 when mode is reflect or edge|
|PRELU|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />slope support broadcast rule:: per-layer/channel|
|RELU|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
|RESHAPE||
|RESIZE_BILINEAR||
|RESIZE_NEAREST_NEIGHBOR||
|SOFTMAX||
|SPACE_TO_DEPTH||
|SPLIT/SPLIT_V||
|SQUEEZE||
|STRIDED_SLICE||
|TANH|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
|TRANSPOSE||
## Darknet OPs supported by RKNN Toolkit2
The list of Darknet OPs supported by RKNN Toolkit2 Version 1.1.0 is as follows:
| **Operators** | **Remarks** |
|---| ----------- |
|add|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element |
|batchnormalize|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
|concat|axis: 1,2,3|
|convolutional|hannel: [1, 8192]<br />kernel height/width: [1, 31]<br />stride height/width: [1, 7]<br />kernels: [1, 8184]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: 1, channel / N|
|depthwise_convolutional|channel:[1, 8192]<br />kernel height/width: [1, 8]<br />stride height/width: [1, 7]<br />kernels: 1<br />pad left/right/top/bottom: [0, 15]|
|fullconnect|channel: [1, 8192]|
|leakyrelu|channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]|
|mish||
|pooling|**AveragePool**:<br />channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br /><br /> **GlobalAveragePool**:<br /> channel: [1, 8192]<br />kernel height/width: [1, 128]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7] <br /><br /> **MaxPool/GlobalMaxPool**:<br /> channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br />MaxPool: <br />auto_pad only support NOTSET,ceil_mode only support 0,unsupport dilations|
|route||
|shortcut||
|softmax||
|upsampling||

240
doc/RKNNToolKit2_OP_Support-1.2.0.md

@ -0,0 +1,240 @@ @@ -0,0 +1,240 @@
# RKNNToolkit2 OPs Support
## Explanation of terms:
Remarks:
Operators' specifications must meet the remarks' requirements.
Broadcast rule:
- per-layer:
shape(A) = (2, 3, 4, 5), shape(B) = (,), i.e. B is a scalar ==> shape(result) = (2, 3, 4, 5)
- per-channel:
shape(A) = (2, 3, 4, 5), shape(B) = (3,), ==> shape(result) = (2, 3, 4, 5)
shape(A) = (2, 3, 4, 5), shape(B) = (1,3,1,1), ==> shape(result) = (2, 3, 4, 5)
- per-element:
shape(A) = (2, 3, 4, 5), shape(B) = (2,3,4,5) ==> shape(result) = (2, 3, 4, 5)
- other:
shape(A) = (2, 3, 4, 5), shape(B) = (5,) ==> shape(result) = (2, 3, 4, 5)
## ONNX OPs supported by RKNN Toolkit2
According to [ONNX official instructions](https://github.com/microsoft/onnxruntime/blob/master/docs/Versioning.md 'ONNX Version Description'), the corresponding ONNX opset version is 12.
The list of ONNX OPs supported by RKNN Toolkit2 is as follows:
| **Operators** | **Remarks** |
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Add | channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element |
| AveragePool | channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7] |
| ArgMin ||
| ArgMax ||
| BatchNormalization | channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176] |
| cast | only support bool/int8/float |
| Clip | channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176] |
| Concat | axis: 1,2,3 |
| Conv | channel: unlimited <br />kernel height/width: [1, 31]<br />stride height/width: [1, 7]<br />kernels: [1, 8184]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: unlimited |
| ConvTranspose | channel: unlimited<br />kernel height/width: [1, 31]<br />stride height/width: 2, 4, 8<br />kernels: [1, 8192]<br />pad left/right/top/bottom: [0, 15]<br />dilation: [1, 31]<br />group: unlimited |
| DepthToSpace ||
| Div | support broadcast rule: per-element/other |
| Elu ||
| Exp ||
| Flatten ||
| Gather ||
| Gemm | channel: unlimited<br /> One input should be Const |
| GlobalAveragePool | channel: [1, 8192]<br />kernel height/width: [1, 343]<br /> |
| GlobalMaxPool | channel: [1, 8192]<br />kernel height/width: [1, 343]<br /> |
| Greater | support broadcast rule: per-element/other |
| HardSigmoid ||
| InstanceNormalization ||
| HardSwish ||
| LeakyRelu | channel: unlimited<br />height: [1, 8192]<br />width: [1, 8176] |
| Less | support broadcast rule: per-element/other |
| LpNormalization ||
| LRN ||
| LSTM | batchsize: 1 |
| GRU | batchsize: 1 |
| MatMul | |
| Max | channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br /> dims=4 |
| MaxPool | channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br />auto_pad only support NOTSET,ceil_mode only support 0,unsupport dilations |
| MaxRoiPool ||
| MaxUnpool | unsupport pad |
| Mul | channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element |
| Pad | pad value should >= 0; pad dims must be 2 when mode is reflect or edge |
| Pow ||
| PRelu | channel: unlimited<br />height: [1, 8192]<br />width: [1, 8176]<br />slope support broadcast rule:: per-layer/channel |
| ReduceMax ||
| ReduceMean | output dims <= 4 |
| ReduceSum | output dims <= 4 |
| ReduceMin ||
| Relu | channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176] |
| Reshape ||
| Resize | bilinear(not support tf_crop_and_resize); nearest2d |
| ReverseSequence ||
| RoiAlign | pool type: average |
| Sigmoid ||
| Slice ||
| Softmax ||
| SpaceToDetph ||
| Split ||
| Squeeze ||
| Tanh | channel: unlimited<br />height: [1, 8192]<br />width: [1, 8176] |
| Tile ||
| Transpose ||
| Upsample (resize) | coordinate_transformation_mode unsupport tf_crop_and_resize |
## Caffe OPs supported by RKNN Toolkit2
Caffe protocols RKNN Toolkit2 uses only based on the officially modified protocol of berkeley.
The protocol based on the official revision of berkeley comes from [berkeley caffe](https://github.com/BVLC/caffe/tree/master/src/caffe/proto 'Berkeley Caffe'), commit hash is 21d0608. On this basis RKNN Toolkit2 have added some OPs.
Based on this protocol, the list of Caffe OPs supported by RKNN Toolkit2 is as follows:
| **Operators** | **Remarks** |
|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| BatchNorm | same as onnx BatchNormalization |
| bn (BatchNorm + Scale) | same as onnx BatchNormalization according to https://github.com/TimoSaemann/caffe-segnet-cudnn5 |
| BNLL ||
| Concat | same as onnx Concat |
| Convolution | same as onnx Conv |
| ConvolutionDepthwise | channel:unlimited<br />kernel height/width: [1, 8]<br />stride height/width: [1, 7]<br />kernels: 1<br />pad left/right/top/bottom: [0, 15] |
| Crop ||
| Deconvolution | same as ConvTranspose |
| Dropout ||
| Eltwise | channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176]<br />support broadcast rule: per-layer/channel/element |
| Flatten ||
| HardSigmoid ||
| InnerProduct | same as onnx Gemm |
| LRN | same as onnx LRN |
| Lstm | same as onnx LSTM according to https://github.com/xmfbit/warpctc-caffe |
| Normalize ||
| Permute | same as onnx Transpose |
| Power ||
| Pooling | same as onnx pooling |
| PRelu | same as onnx PRelu |
| Proposal | batch: 1 |
| Reduction | output dims <= 4 |
| Relu | same as onnx Relu |
| Relu6 | same as onnx Clip |
| Reorg ||
| Reshape | same as onnx Reshape |
| Resize | bilinear; nearest |
| Reverse ||
| ROIPooling | same as MaxRoiPool according to https://github.com/twmht/caffe-pva-faster-rcnn |
| Scale | channel: [1, 8192]<br />height: [1, 8192]<br />width: [1, 8176] |
| Sigmoid | same as onnx Sigmoid |
| Slice | same as onnx Split |
| Softmax | same as onnx Softmax |
| Split | same as onnx Slice |
| TanH | same as onnx TanH |
| Tile | same as onnx Tile |
| Transpose | same as onnx Transpose |
| Upsample | according to https://github.com/SeanQ88/caffe_upsample and https://github.com/TimoSaemann/caffe-segnet-cudnn5 |
## Pytorch OPs supported by RKNN Toolkit2
The Pytorch version supported by RKNN Toolkit2 is >1.6.0, models generated by other versions may not support.
The list of Pytorch OPs supported by RKNN Toolkit2 is as follows:
| **Operators** | **Remarks** |
|---------------------------|------------------------------------|
| aten::_convolution | same as onnx Conv |
| aten::add | same as onnx Add |
| aten::avg_pool2d | same as onnx AveragePool |
| aten::batch_norm | same as onnx BatchNormalization |
| aten::cat | same as onnx Concat |
| aten::chunk ||
| aten::dropout ||
| aten::elu | same as onnx Elu |
| aten::flatten ||
| aten::hardswish | same as onnx HardSwish |
| aten::instance_norm | same as onnx InstanceNormalization |
| aten::layer_norm ||
| aten::leaky_relu | same as onnx LeakyRelu |
| aten::linear | same as onnx Gemm |
| aten::matmul | same as onnx MatMul |
| aten::max_pool2d | same as onnx MaxPool |
| aten::mean | output dims <= 4 |
| aten::mul | same as onnx Mul |
| aten::pad | same as onnx Pad |
| aten::permute | same as onnx Transpose |
| aten::prelu | same as onnx PRelu |
| aten::relu | same as onnx Relu |
| aten::reshape | |
| aten::sigmoid | same as onnx Sigmoid |
| aten::slice | same as onnx Slice |
| aten::split | same as onnx Split |
| aten::softmax | same as onnx Softmax |
| aten::squeeze | same as onnx Squeeze |
| aten::sum | output dims <= 4 |
| aten::tanh | same as onnx TanH |
| aten::upsample_bilinear2d | same as onnx Resize |
| aten::upsample_nearest2d | same as onnx Resize |
| aten::view | same as onnx Reshape |
## TensorFlow OPs supported by RKNN Toolkit2
The pb files (contain OPs belows) generated by TensorFlow version 1.12 - 1.15 for 1.x and 2.3 - 2.5 for 2.x are supported by RKNN Toolkit2. For more information on TensorFlow version compatibility, please refer to [tensorflow official instructions on OP version](https://www.tensorflow.org/guide/versions 'Tensorflow official instructions on OP version') .
The list of TensorFlow OPs supported by RKNN Toolkit2 is as follows:
| **Operators** | **Remarks** |
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| Add | same as onnx Add |
| AvgPool | same as onnx AveragePool |
| Concat | same as onnx Concat |
| Conv2D | same as onnx Conv |
| DepthToSpace ||
| DepthwiseConv2d | channel:unlimited<br />kernel height/width: [1, 8]<br />stride height/width: [1, 7]<br />kernels: 1<br />pad left/right/top/bottom: [0, 15] |
| Div | same as onnx Div |
| Dropout ||
| Flatten ||
| LeakyRelu | same as onnx LeakyRelu |
| Less | same as onnx Less |
| LRN ||
| MatMul | |
| MaxPool | same as onnx MaxPool |
| Mean | output dims <= 4 |
| Pad | same as onnx Pad |
| Relu | same as onnx Relu |
| Reshape ||
| ResizeBilinear ||
| ResizeNearestNeighbor ||
| Sigmoid ||
| Slice ||
| Softmax ||
| Softplus ||
| SpaceToDepth ||
| Split ||
| Squeeze ||
| StridedSlice ||
| Tanh | same as onnx TanH |
| Transpose ||
## Darknet OPs supported by RKNN Toolkit2
The list of Darknet OPs supported by RKNN Toolkit2 is as follows:
| **Operators** | **Remarks** |
|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| add | same as onnx Add |
| batchnormalize | same as onnx BatchNormalization |
| concat | same as onnx Concat |
| convolutional | same as onnx Conv |
| depthwise_convolutional | channel:unlimited<br />kernel height/width: [1, 8]<br />stride height/width: [1, 7]<br />kernels: 1<br />pad left/right/top/bottom: [0, 15] |
| fullconnect | |
| leakyrelu | same as onnx LeakyRelu |
| mish ||
| pooling | **AveragePool**:<br />channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br /><br /> **GlobalAveragePool**:<br /> channel: [1, 8192]<br />kernel height/width: [1, 128]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7] <br /> <br /> **MaxPool/GlobalMaxPool**:<br /> channel: [1, 8192]<br />kernel height/width: [1, 7]<br />stride height/width: [1, 8]<br />pad left/right/top/bottom: [0, 7]<br /><br />MaxPool: <br />auto_pad only support NOTSET,ceil_mode only support 0,unsupport dilations |
| route ||
| shortcut ||
| softmax ||
| upsampling ||

337
doc/RRKNNToolKit2_API_Difference_With_Toolkit1-1.2.0.md

@ -0,0 +1,337 @@ @@ -0,0 +1,337 @@
# RKNNToolkit2 API Difference With Toolkit1
## rknn.config
- Toolkit1:
config(batch_size=100, # abandoned
caffe_mean_file=None, # abandoned
dtype='float32', # abandoned
epochs=-1, # abandoned
force_gray=None, # abandoned
input_fitting='scale', # abandoned
input_normalization=None, # abandoned
mean_file=None, # abandoned
model_data_format='zone', # abandoned
model_quantize=None, # abandoned
optimize='Default', # abandoned
quantized_dtype='asymmetric_affine-u8',
quantized_moving_alpha=0.01, # abandoned
quantized_algorithm='normal',
quantized_divergence_nbins=1024, # abandoned
mmse_epoch=3, # abandoned
random_brightness=None, # abandoned
random_contrast=None, # abandoned
random_crop=None, # abandoned
random_flip=None, # abandoned
random_mirror=None, # abandoned
reorder_channel=None, # abandoned
restart=False, # abandoned
samples=-1, # abandoned
need_horizontal_merge=False, # abandoned
deconv_merge=True, # abandoned
conv_mul_merge=True, # abandoned
quantized_hybrid=False, # abandoned
output_optimize=0, # abandoned
remove_tensorflow_output_permute=False, # abandoned
optimization_level=3,
target_platform=None,
mean_values=None,
std_values=None,
channel_mean_value=None, # abandoned
force_builtin_perm=False, # abandoned
do_sparse_network=True, # abandoned
merge_dequant_layer_and_output_node=False, # abandoned
quantize_input_node=False, # abandoned
inputs_scale_range=None) # abandoned
- Toolkit2:
config(mean_values=None,
std_values=None,
quantized_dtype='asymmetric_quantized-8',
quantized_algorithm='normal',
quantized_method='channel', # new
target_platform=None,
quant_img_RGB2BGR=False, # new
float_dtype='float16', # new
optimization_level=3,
custom_string=None, # new
output_tensor_type=None) # new
- In addition to the above abandoned/new items, there are other differences:
quantized_dtype:
toolkit1: asymmetric_affine-u8, dynamic_fixed_point-i8, dynamic_fixed_point-i16
toolkit2: asymmetric_quantized-8
quantized_algorithm:
toolkit1: normal(default), mmse, kl_divergence, moving_average
toolkit2: normal(default), mmse
target_platform:
toolkit1: rk1808, rk3399pro, rv1109, rv1126
toolkit2: rk3566, rk3568, rk3588
## rknn.load_tensorflow
- Toolkit1:
load_tensorflow(tf_pb,
inputs,
input_size_list,
outputs,
predef_file=None, # abandoned
mean_values=None, # abandoned
std_values=None, # abandoned
size_with_batch=None) # abandoned
- Toolkit2:
load_tensorflow(tf_pb,
inputs,
input_size_list,
outputs)
- In addition to the above abandoned items, there are other differences:
inputs:
toolkit1: node list (layer name)
toolkit2: node list (operand name)
outputs:
toolkit1: node list (layer name)
toolkit2: node list (operand name)
## rknn.load_caffe
- Toolkit1:
load_caffe(model,
proto, # abandoned
blobs=None)
- Toolkit2:
load_caffe(model,
blobs=None,
input_name=None) # new
## rknn.load_keras
- Toolkit1:
load_keras(model, convert_engine='Keras')
- Toolkit2:
Not supported yet!
## rknn.load_pytorch
- Toolkit1:
load_pytorch(model,
input_size_list=None,
inputs=None, # abandoned
outputs=None, # abandoned
convert_engine='torch') # abandoned
- Toolkit2:
load_pytorch(model,
input_size_list)
## rknn.load_mxnet
- Toolkit1:
load_mxnet(symbol, params, input_size_list=None)
- Toolkit2:
Not supported yet!
## rknn.build
- Toolkit1:
build(do_quantization=True,
dataset='dataset.txt',
pre_compile=False, # abandoned
rknn_batch_size=-1)
- Toolkit2:
build(do_quantization=True,
dataset='dataset.txt',
rknn_batch_size=-1):
## rknn.direct_build
- Toolkit1:
direct_build(model_input, data_input, model_quantize=None, pre_compile=False)
- Toolkit2:
Not supported yet!
## rknn.hybrid_quantization_step1
- Toolkit1:
hybrid_quantization_step1(dataset=None)
- Toolkit2:
hybrid_quantization_step1(dataset=None,
rknn_batch_size=-1, # new
proposal=False, # new
proposal_dataset_size=1) # new
## rknn.hybrid_quantization_step2
- Toolkit1:
hybrid_quantization_step2(model_input,
data_input,
model_quantization_cfg,
dataset, # abandoned
pre_compile=False) # abandoned
- Toolkit2:
hybrid_quantization_step2(model_input,
data_input,
model_quantization_cfg)
## rknn.accuracy_analysis
- Toolkit1:
accuracy_analysis(inputs,
output_dir='./snapshot',
calc_qnt_error=True, # abandoned
target=None,
device_id=None,
dump_file_type='tensor') # abandoned
- Toolkit2:
accuracy_analysis(inputs,
output_dir='./snapshot',
target=None,
device_id=None)
## rknn.load_rknn
- Toolkit1:
load_rknn(path,
load_model_in_npu=False) # abandoned
- Toolkit2:
load_rknn(path)
## rknn.export_rknn
- Toolkit1:
export_rknn(export_path)
- Toolkit2:
export_rknn(export_path,
**kwargs) # new
## rknn.load_firmware
- Toolkit1:
load_firmware(fw_dir=None)
- Toolkit2:
Not supported yet!
## rknn.init_runtime
- Toolkit1:
init_runtime(target=None,
target_sub_class=None,
device_id=None,
perf_debug=False,
eval_mem=False,
async_mode=False,
rknn2precompile=False) # abandoned
- Toolkit2:
init_runtime(target=None,
target_sub_class=None,
device_id=None,
perf_debug=False,
eval_mem=False,
async_mode=False)
- In addition to the above abandoned items, there are other differences:
target:
toolkit1: None(simulator), RK3399Pro, RK1808
toolkit2: None(simulator), RK3566, RK3568, RK3588
## rknn.inference
- Toolkit1:
inference(inputs,
data_type=None, # abandoned
data_format=None,
inputs_pass_through=None,
get_frame_id=False)
- Toolkit2:
inference(inputs,
data_format=None,
inputs_pass_through=None,
get_frame_id=False)
## rknn.eval_perf
- Toolkit1:
eval_perf(inputs=None,
data_type=None, # abandoned
data_format=None,
is_print=True,
loop_cnt=1) # abandoned
- Toolkit2:
eval_perf(inputs=None,
data_format=None,
is_print=True)
## rknn.export_rknn_precompile_model
- Toolkit1:
export_rknn_precompile_model(export_path=None)
- Toolkit2:
Abandoned
## rknn.export_rknn_sync_model
- Toolkit1:
export_rknn_sync_model(input_model=None, sync_uids=None, output_model=None)
- Toolkit2:
Abandoned
## rknn.register_op
- Toolkit1:
register_op(op_path)
- Toolkit2:
Not supported yet
## rknn.fetch_rknn_model_config
- Toolkit1:
fetch_rknn_model_config(model_path)
- Toolkit2:
Not supported yet
## rknn.list_support_target_platform
- Toolkit1:
list_support_target_platform(rknn_model=None)
- Toolkit2:
Not supported yet

BIN
doc/Rockchip_Quick_Start_RKNN_Toolkit2_CN-1.1.0.pdf

Binary file not shown.

BIN
doc/Rockchip_Quick_Start_RKNN_Toolkit2_CN-1.2.0.pdf

Binary file not shown.

BIN
doc/Rockchip_Quick_Start_RKNN_Toolkit2_EN-1.1.0.pdf

Binary file not shown.

BIN
doc/Rockchip_Quick_Start_RKNN_Toolkit2_EN-1.2.0.pdf

Binary file not shown.

BIN
doc/Rockchip_User_Guide_RKNN_Toolkit2_CN-1.1.0.pdf

Binary file not shown.

BIN
doc/Rockchip_User_Guide_RKNN_Toolkit2_CN-1.2.0.pdf

Binary file not shown.

BIN
doc/Rockchip_User_Guide_RKNN_Toolkit2_EN-1.1.0.pdf

Binary file not shown.

BIN
doc/Rockchip_User_Guide_RKNN_Toolkit2_EN-1.2.0.pdf

Binary file not shown.

16
doc/changelog-1.1.0.txt → doc/changelog-1.2.0.txt

@ -1,4 +1,18 @@ @@ -1,4 +1,18 @@
2021-8-20
2021-1-12
版本:v1.2.0
更新内容:
1. 新功能: rk3588平台的支持; rknn模型加密支持; tensorflow/tflite/pytorch量化感知模型支持; 增加了一些新的 op 支持: InstanceNormalization, Swish, Conv1D等(详见 op support list);增加了参数量计算以及算力分析
2. examples 更新:增加了从 pytorch 转 onnx 的转换 demo:resnet18_export_onnx ;增加了pytorch量化感知模型的加载demo:resnet18_qat demo;增加了模型加密功能
3. 接口更改:移除了 config,load_caffe,load_tensorflow等接口的一些不必要的参数设置,更新了 eval_perf 接口,详细改动见Uer_Guide文档
4. 修复一些已知的bug:
1) 修复了一些模型无法转换rknn的问题
2) 修复了一些图优化bug
3) 修复了一些模型推理结果错误的问题
4) 修复了 pytorch、tflite 某些 op 转换失败的问题
5. 优化: 精度分析耗时优化; 模型转换和量化耗时优化
2021-8-12
版本:v1.1.0
更新内容:
1. 新功能: LSTM,GRU的支持;增加了accuracy_analysis对比项目;增加了一些op支持:caffe hardswish;onnx gather,reduceMax等op;更新了更全面的图优化规则。

4
doc/requirements-1.1.0.txt → doc/requirements_cp36-1.2.0.txt

@ -12,8 +12,8 @@ ruamel.yaml==0.15.81 @@ -12,8 +12,8 @@ ruamel.yaml==0.15.81
scipy==1.2.1
tqdm==4.27.0
requests==2.21.0
tflite==2.3.0
opencv-python==4.4.0.46
PuLP==2.4
scikit_image==0.17.2
bfloat16==1.1
bfloat16==1.1
flatbuffers==1.12

21
examples/caffe/mobilenet_v2/dataset.txt

@ -1 +1,20 @@ @@ -1 +1,20 @@
goldfish_224x224.jpg
./imgs/ILSVRC2012_val_00000665.JPEG
./imgs/ILSVRC2012_val_00001123.JPEG
./imgs/ILSVRC2012_val_00001129.JPEG
./imgs/ILSVRC2012_val_00001284.JPEG
./imgs/ILSVRC2012_val_00003026.JPEG
./imgs/ILSVRC2012_val_00005276.JPEG
./imgs/ILSVRC2012_val_00006178.JPEG
./imgs/ILSVRC2012_val_00007829.JPEG
./imgs/ILSVRC2012_val_00009338.JPEG
./imgs/ILSVRC2012_val_00010420.JPEG
./imgs/ILSVRC2012_val_00011878.JPEG
./imgs/ILSVRC2012_val_00011240.JPEG
./imgs/ILSVRC2012_val_00012037.JPEG
./imgs/ILSVRC2012_val_00012351.JPEG
./imgs/ILSVRC2012_val_00012470.JPEG
./imgs/ILSVRC2012_val_00020169.JPEG
./imgs/ILSVRC2012_val_00020173.JPEG
./imgs/ILSVRC2012_val_00021224.JPEG
./imgs/ILSVRC2012_val_00024249.JPEG
./imgs/ILSVRC2012_val_00025601.JPEG

0
examples/tflite/mobilenet_v1_quant/dog_224x224.jpg → examples/caffe/mobilenet_v2/dog_224x224.jpg

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

BIN
examples/caffe/mobilenet_v2/goldfish_224x224.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00000665.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00001123.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00001129.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00001284.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00003026.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00005276.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00006178.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00007829.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00009338.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00010420.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00011240.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00011878.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00012037.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00012351.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00012470.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00020169.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00020173.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00021224.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00024249.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
examples/caffe/mobilenet_v2/imgs/ILSVRC2012_val_00025601.JPEG

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

27
examples/caffe/mobilenet_v2/test.py

@ -2,6 +2,7 @@ import numpy as np @@ -2,6 +2,7 @@ import numpy as np
import cv2
from rknn.api import RKNN
def show_outputs(outputs):
np.save('./caffe_mobilenet_v2_0.npy', outputs[0])
output = outputs[0].reshape(-1)
@ -20,23 +21,23 @@ def show_outputs(outputs): @@ -20,23 +21,23 @@ def show_outputs(outputs):
top5_str += topi
print(top5_str)
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
# pre-process config
print('--> config model')
rknn = RKNN(verbose=True)
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[103.94, 116.78, 123.68], std_values=[58.82, 58.82, 58.82], quant_img_RGB2BGR=True)
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_caffe(model='./mobilenet_v2.prototxt',
proto='caffe',
blobs='./mobilenet_v2.caffemodel')
if ret != 0:
print('Load mobilenet_v2 failed! Ret = {}'.format(ret))
print('Load model failed!')
exit(ret)
print('done')
@ -44,25 +45,26 @@ if __name__ == '__main__': @@ -44,25 +45,26 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build mobilenet_v2 failed!')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn('./mobilenet_v2.rknn')
if ret != 0:
print('Export mobilenet_v2.rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
# Set inputs
img = cv2.imread('./goldfish_224x224.jpg')
img = cv2.imread('./dog_224x224.jpg')
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
@ -73,4 +75,3 @@ if __name__ == '__main__': @@ -73,4 +75,3 @@ if __name__ == '__main__':
print('done')
rknn.release()

110
examples/caffe/vgg-ssd/test.py

@ -16,18 +16,19 @@ CLASSES = ('__background__', @@ -16,18 +16,19 @@ CLASSES = ('__background__',
'cow', 'diningtable', 'dog', 'horse',
'motorbike', 'person', 'pottedplant',
'sheep', 'sofa', 'train', 'tvmonitor')
NUM_CLS = 21
CONF_THRESH = 0.5
NMS_THRESH = 0.45
def IntersectBBox(box1, box2):
if box1[0]>box2[2] or box1[2]<box2[0] or box1[1]>box2[3] or box1[3]<box2[1]:
if box1[0] > box2[2] or box1[2] < box2[0] or box1[1] > box2[3] or box1[3] < box2[1]:
return 0
else:
area1 = (box1[2] - box1[0]) * (box1[3] - box1[1])
area2 = (box2[2] - box2[0]) * (box2[3] - box2[1])
area2 = (box2[2] - box2[0]) * (box2[3] - box2[1])
xx1 = max(box1[0], box2[0])
yy1 = max(box1[1], box2[1])
@ -42,61 +43,59 @@ def IntersectBBox(box1, box2): @@ -42,61 +43,59 @@ def IntersectBBox(box1, box2):
def ssd_post_process(conf_data, loc_data):
np.save('./caffe_vgg-ssd_0.npy', loc_data)
np.save('./caffe_vgg-ssd_1.npy', conf_data)
prior_data = np.loadtxt('mbox_priorbox_97.txt', dtype = np.float32)
prior_data = np.loadtxt('mbox_priorbox_97.txt', dtype=np.float32)
prior_bboxes = prior_data[:len(loc_data)]
prior_variances = prior_data[len(loc_data):]
prior_num = int(len(loc_data) / 4) # 8732
conf_data = conf_data.reshape(-1,21)
prior_num = int(len(loc_data) / 4) # 8732
conf_data = conf_data.reshape(-1, 21)
idx_class_conf = []
bboxes = []
bboxes = []
# conf
for prior_idx in range(0,prior_num):
for prior_idx in range(0, prior_num):
max_val = np.max(conf_data[prior_idx])
max_idx = np.argmax(conf_data[prior_idx])
if max_val > CONF_THRESH and max_idx != 0:
idx_class_conf.append([prior_idx, max_idx, max_val])
#print(len(idx_class_conf))
# print(len(idx_class_conf))
# boxes
for i in range(0,prior_num):
for i in range(0, prior_num):
prior_w = prior_bboxes[4*i+2] - prior_bboxes[4*i]
prior_h = prior_bboxes[4*i+3] - prior_bboxes[4*i+1]
prior_center_x = (prior_bboxes[4*i+2] + prior_bboxes[4*i]) / 2
prior_center_y = (prior_bboxes[4*i+3] + prior_bboxes[4*i+1]) / 2
bbox_center_x = prior_variances[4*i+0] * loc_data[4*i+0] * prior_w + prior_center_x
bbox_center_y = prior_variances[4*i+1] * loc_data[4*i+1] * prior_h + prior_center_y
bbox_w = math.exp(prior_variances[4*i+2] * loc_data[4*i+2]) * prior_w
bbox_h = math.exp(prior_variances[4*i+3] * loc_data[4*i+3]) * prior_h
bbox_w = math.exp(prior_variances[4*i+2] * loc_data[4*i+2]) * prior_w
bbox_h = math.exp(prior_variances[4*i+3] * loc_data[4*i+3]) * prior_h
tmp = []
tmp.append(max(min(bbox_center_x - bbox_w / 2., 1), 0))
tmp.append(max(min(bbox_center_y - bbox_h / 2., 1), 0))
tmp.append(max(min(bbox_center_x + bbox_w / 2., 1), 0))
tmp.append(max(min(bbox_center_y + bbox_h / 2., 1), 0))
bboxes.append(tmp)
print(len(idx_class_conf))
#nms
# nms
cur_class_num = 0
idx_class_conf_ = []
for i in range(0, len(idx_class_conf)):
for i in range(0, len(idx_class_conf)):
keep = True
k = 0
while k < cur_class_num:
if keep:
ovr = IntersectBBox(bboxes[idx_class_conf[i][0]], bboxes[idx_class_conf_[k][0]])
if idx_class_conf_[k][1]==idx_class_conf[i][1] and ovr > NMS_THRESH:
if idx_class_conf_[k][2]<idx_class_conf[i][2]:
if idx_class_conf_[k][1] == idx_class_conf[i][1] and ovr > NMS_THRESH:
if idx_class_conf_[k][2] < idx_class_conf[i][2]:
idx_class_conf_.pop(k)
idx_class_conf_.append(idx_class_conf[i])
keep = False
@ -107,70 +106,70 @@ def ssd_post_process(conf_data, loc_data): @@ -107,70 +106,70 @@ def ssd_post_process(conf_data, loc_data):
if keep:
idx_class_conf_.append(idx_class_conf[i])
cur_class_num += 1
print(idx_class_conf_)
box_class_score = []
box_class_score = []
for i in range(0, len(idx_class_conf_)):
bboxes[idx_class_conf_[i][0]].append(idx_class_conf_[i][1])
bboxes[idx_class_conf_[i][0]].append(idx_class_conf_[i][2])
box_class_score.append( bboxes[idx_class_conf_[i][0]])
box_class_score.append(bboxes[idx_class_conf_[i][0]])
img = cv2.imread('./road_300x300.jpg')
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
font = ImageFont.load_default()
for i in range(0, len(box_class_score)):
x1 = int(box_class_score[i][0]*img.shape[1])
y1 = int(box_class_score[i][1]*img.shape[0])
x2 = int(box_class_score[i][2]*img.shape[1])
y2 = int(box_class_score[i][3]*img.shape[0])
color = (0, int(box_class_score[i][4]/20.0*255), 255)
draw.line([(x1, y1), (x1, y2), (x2 , y2),
(x2 , y1), (x1, y1)], width=2, fill=color)
display_str = CLASSES[box_class_score[i][4]] + ":" + str(box_class_score[i][5])
draw.line([(x1, y1), (x1, y2), (x2, y2),
(x2, y1), (x1, y1)], width=2, fill=color)
display_str = CLASSES[box_class_score[i][4]] + ":" + str(box_class_score[i][5])
display_str_height = np.ceil((1 + 2 * 0.05) * font.getsize(display_str)[1])+1
if y1 > display_str_height:
text_bottom = y1
else:
text_bottom = y1 + display_str_height
text_width, text_height = font.getsize(display_str)
margin = np.ceil(0.05 * text_height)
draw.rectangle([(x1, text_bottom-text_height-2*margin), (x1+text_width, text_bottom)],fill=color)
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)
np.copyto(img, np.array(img_pil))
cv2.imwrite("result.jpg", img)
if __name__ == '__main__':
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')
exit(-1)
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')
exit(-1)
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[103.94, 116.78, 123.68], std_values=[1, 1, 1], quant_img_RGB2BGR=True)
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_caffe(model='./deploy_rm_detection_output.prototxt',
proto='caffe',
blobs='./VGG_VOC0712_SSD_300x300_iter_120000.caffemodel')
if ret != 0:
print('Load model failed! Ret = {}'.format(ret))
print('Load model failed!')
exit(ret)
print('done')
@ -183,20 +182,21 @@ if __name__ == '__main__': @@ -183,20 +182,21 @@ if __name__ == '__main__':
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn('./deploy_rm_detection_output.rknn')
if ret != 0:
print('Export rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
# Set inputs
img = cv2.imread('./road_300x300.jpg')
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
@ -207,6 +207,8 @@ if __name__ == '__main__': @@ -207,6 +207,8 @@ if __name__ == '__main__':
outputs[0] = outputs[0].reshape((-1, 1))
outputs[1] = outputs[1].reshape((-1, 1))
np.save('./caffe_vgg-ssd_0.npy', outputs[0])
np.save('./caffe_vgg-ssd_1.npy', outputs[1])
ssd_post_process(outputs[1], outputs[0])
rknn.release()

27
examples/darknet/yolov3_416x416/test.py

@ -22,20 +22,18 @@ if __name__ == '__main__': @@ -22,20 +22,18 @@ if __name__ == '__main__':
download_yolov3_weight(WEIGHT_PATH)
# Create RKNN object
rknn = RKNN()
# pre-process config
print('--> config model')
rknn = RKNN(verbose=True)
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[0, 0, 0], std_values=[255, 255, 255])
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_darknet(model=MODEL_PATH,
weight=WEIGHT_PATH,
)
ret = rknn.load_darknet(model=MODEL_PATH, weight=WEIGHT_PATH)
if ret != 0:
print('Load yolov3 failed! Ret = {}'.format(ret))
print('Load model failed!')
exit(ret)
print('done')
@ -43,15 +41,15 @@ if __name__ == '__main__': @@ -43,15 +41,15 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset=DATASET)
if ret != 0:
print('Build yolov3 failed!')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn(RKNN_MODEL_PATH)
if ret != 0:
print('Export yolov3.rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
@ -59,10 +57,11 @@ if __name__ == '__main__': @@ -59,10 +57,11 @@ if __name__ == '__main__':
img = cv2.imread(im_file)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
@ -71,7 +70,6 @@ if __name__ == '__main__': @@ -71,7 +70,6 @@ if __name__ == '__main__':
outputs = rknn.inference(inputs=[img])
print('done')
input0_data = outputs[0]
np.save('./darknet_yolov3_416x416_0.npy', input0_data)
input1_data = outputs[1]
@ -98,4 +96,3 @@ if __name__ == '__main__': @@ -98,4 +96,3 @@ if __name__ == '__main__':
cv2.imwrite('result.jpg', image)
rknn.release()

17
examples/functions/accuracy_analysis/test.py

@ -80,15 +80,16 @@ if __name__ == '__main__': @@ -80,15 +80,16 @@ if __name__ == '__main__':
exit(-1)
print('done')
# print('--> config model')
rknn.config(mean_values=[123.68, 116.28, 103.53], std_values=[57.38, 57.38, 57.38], quantized_method='layer')
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[123.68, 116.28, 103.53], std_values=[57.38, 57.38, 57.38])
print('done')
# Load model
print('--> Loading model')
ret = rknn.load_onnx(model=ONNX_MODEL)
if ret != 0:
print('Load resnet50v2 failed!')
print('Load model failed!')
exit(ret)
print('done')
@ -96,16 +97,15 @@ if __name__ == '__main__': @@ -96,16 +97,15 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build resnet50 failed!')
print('Build model failed!')
exit(ret)
print('done')
# Snapshot model
# Accuracy analysis
print('--> Accuracy analysis')
inputs_file = ['./dog_224x224.jpg']
ret = rknn.accuracy_analysis(inputs=inputs_file, output_dir='./snapshot')
ret = rknn.accuracy_analysis(inputs=['./dog_224x224.jpg'], output_dir='./snapshot')
if ret != 0:
print('Analysis mobilenet_v1 failed!')
print('Accuracy analysis failed!')
exit(ret)
print('done')
@ -118,4 +118,3 @@ if __name__ == '__main__': @@ -118,4 +118,3 @@ if __name__ == '__main__':
show_outputs(output)
rknn.release()

21
examples/functions/batch_size/test.py

@ -30,20 +30,19 @@ def show_perfs(perfs): @@ -30,20 +30,19 @@ def show_perfs(perfs):
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[103.94, 116.78, 123.68], std_values=[58.82, 58.82, 58.82], quant_img_RGB2BGR=True)
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_caffe(model='../../caffe/mobilenet_v2/mobilenet_v2.prototxt',
proto='caffe',
blobs='../../caffe/mobilenet_v2/mobilenet_v2.caffemodel')
if ret != 0:
print('Load mobilenet_v2 failed!')
print('Load model failed!')
exit(ret)
print('done')
@ -51,15 +50,15 @@ if __name__ == '__main__': @@ -51,15 +50,15 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt', rknn_batch_size=4)
if ret != 0:
print('Build mobilenet_v2 failed!')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn('./mobilenet_v2.rknn')
if ret != 0:
print('Export mobilenet_v2.rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
@ -69,11 +68,11 @@ if __name__ == '__main__': @@ -69,11 +68,11 @@ if __name__ == '__main__':
img = np.expand_dims(img, 0)
img = np.concatenate((img, img, img, img), axis=0)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')

1
examples/functions/board_test/dataset.txt

@ -0,0 +1 @@ @@ -0,0 +1 @@
dog_224x224.jpg

BIN
examples/functions/board_test/dog_224x224.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

106
examples/functions/board_test/test.py

@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
import numpy as np
import cv2
from rknn.api import RKNN
def show_outputs(outputs):
output = outputs[0].reshape(-1)
output_sorted = sorted(output, reverse=True)
top5_str = 'mobilenet_v2\n-----TOP 5-----\n'
for i in range(5):
value = output_sorted[i]
index = np.where(output == value)
for j in range(len(index)):
if (i + j) >= 5:
break
if value > 0:
topi = '{}: {}\n'.format(index[j], value)
else:
topi = '-1: 0.0\n'
top5_str += topi
print(top5_str)
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN(verbose=True)
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[103.94, 116.78, 123.68], std_values=[58.82, 58.82, 58.82],
quant_img_RGB2BGR=True, target_platform='rk3566')
print('done')
# Load model
print('--> Loading model')
ret = rknn.load_caffe(model='./../../caffe/mobilenet_v2/mobilenet_v2.prototxt',
blobs='./../../caffe/mobilenet_v2/mobilenet_v2.caffemodel')
if ret != 0:
print('Load model failed!')
exit(ret)
print('done')
# Build model
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export rknn model')
ret = rknn.export_rknn('./mobilenet_v2.rknn')
if ret != 0:
print('Export rknn model failed!')
exit(ret)
print('done')
# Export encrypted RKNN model
print('--> Export encrypted rknn model')
ret = rknn.export_encrypted_rknn_model('./mobilenet_v2.rknn', None, 3)
# load rknn model
print('--> Load rknn model')
ret = rknn.load_rknn('./mobilenet_v2.rknn')
if ret != 0:
print('Load rknn model failed!')
exit(ret)
print('done')
# Set inputs
img = cv2.imread('./dog_224x224.jpg')
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime(target='rk3566', perf_debug=True, eval_mem=True)
if ret != 0:
print('Init runtime environment failed!')
exit(ret)
print('done')
# eval perf
print('--> Eval perf')
rknn.eval_perf(inputs=[img])
# eval perf
print('--> Eval memory')
rknn.eval_memory()
# Inference
print('--> Running model')
outputs = rknn.inference(inputs=[img])
np.save('./functions_board_test_0.npy', outputs[0])
show_outputs(outputs)
print('done')
# Accuracy analysis
print('--> Accuracy analysis')
ret = rknn.accuracy_analysis(inputs=['./dog_224x224.jpg'], output_dir='./snapshot', target='rk3566')
if ret != 0:
print('Accuracy analysis failed!')
exit(ret)
print('done')
rknn.release()

15
examples/functions/hybrid_quant/step1.py

@ -5,20 +5,19 @@ from rknn.api import RKNN @@ -5,20 +5,19 @@ from rknn.api import RKNN
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[127.5, 127.5, 127.5], std_values=[127.5, 127.5, 127.5])
print('done')
# Load tflite model
# Load model
print('--> Loading model')
ret = rknn.load_tensorflow(tf_pb='./ssd_mobilenet_v2.pb',
inputs=['FeatureExtractor/MobilenetV2/MobilenetV2/input'],
outputs=['concat_1', 'concat'],
input_size_list=[[1,300,300,3]],
predef_file=None)
input_size_list=[[1,300,300,3]])
if ret != 0:
print('Load model failed!')
exit(ret)
@ -39,11 +38,11 @@ if __name__ == '__main__': @@ -39,11 +38,11 @@ if __name__ == '__main__':
print('')
print('For example:')
print(' custom_quantize_layers:')
print(' FeatureExtractor/MobilenetV2/expanded_conv/depthwise/BatchNorm/batchnorm/add_1_rk:0: float16')
print(' Conv__344:0: float16')
print(' FeatureExtractor/MobilenetV2/expanded_conv/depthwise/Relu6:0: float16')
print('Or:')
print(' custom_quantize_layers: {')
print(' FeatureExtractor/MobilenetV2/expanded_conv/depthwise/BatchNorm/batchnorm/add_1_rk:0: float16,')
print(' Conv__344:0: float16,')
print(' FeatureExtractor/MobilenetV2/expanded_conv/depthwise/Relu6:0: float16,')
print(' }')
print('==================================================================================================')

19
examples/functions/hybrid_quant/step2.py

@ -6,7 +6,7 @@ from ssd_post_process import ssd_post_process @@ -6,7 +6,7 @@ from ssd_post_process import ssd_post_process
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# Build model
print('--> hybrid_quantization_step2')
@ -19,24 +19,30 @@ if __name__ == '__main__': @@ -19,24 +19,30 @@ if __name__ == '__main__':
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn('./ssd_mobilenet_v2.rknn')
if ret != 0:
print('Export model failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
rknn.accuracy_analysis(inputs=['./dog_bike_car_300x300.jpg'], output_dir=None)
# Accuracy analysis
print('--> Accuracy analysis')
ret = rknn.accuracy_analysis(inputs=['./dog_bike_car_300x300.jpg'], output_dir=None)
if ret != 0:
print('Accuracy analysis failed!')
exit(ret)
print('done')
# Set inputs
img = cv2.imread('./dog_bike_car_300x300.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
@ -49,4 +55,3 @@ if __name__ == '__main__': @@ -49,4 +55,3 @@ if __name__ == '__main__':
print('done')
rknn.release()

23
examples/functions/mmse/test.py

@ -2,6 +2,7 @@ import numpy as np @@ -2,6 +2,7 @@ import numpy as np
import cv2
from rknn.api import RKNN
def show_outputs(outputs):
output = outputs[0][0]
output_sorted = sorted(output, reverse=True)
@ -19,24 +20,26 @@ def show_outputs(outputs): @@ -19,24 +20,26 @@ def show_outputs(outputs):
top5_str += topi
print(top5_str)
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
rknn.config(mean_values=[128, 128, 128], std_values=[128, 128, 128], quantized_algorithm='mmse')
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[128, 128, 128], std_values=[128, 128, 128],
quantized_method='layer', quantized_algorithm='mmse')
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_tensorflow(tf_pb='mobilenet_v1.pb',
inputs=['input'],
input_size_list=[[1, 224, 224, 3]],
outputs=['MobilenetV1/Logits/SpatialSqueeze'])
if ret != 0:
print('Load mobilenet_v1 failed!')
print('Load model failed!')
exit(ret)
print('done')
@ -44,15 +47,17 @@ if __name__ == '__main__': @@ -44,15 +47,17 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build mobilenet_v1 failed!')
print('Build model failed!')
exit(ret)
print('done')
# Accuracy analysis
print('--> Accuracy analysis')
ret = rknn.accuracy_analysis(inputs=['dog_224x224.jpg'], output_dir=None)
if ret != 0:
print('Accuracy analysis failed!')
exit(ret)
print('done')
f = open('./snapshot/error_analysis.txt')
lines = f.readlines()
@ -68,11 +73,11 @@ if __name__ == '__main__': @@ -68,11 +73,11 @@ if __name__ == '__main__':
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = np.expand_dims(img, 0)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')

18
examples/functions/multi_input_test/test.py

@ -7,13 +7,13 @@ if __name__ == '__main__': @@ -7,13 +7,13 @@ if __name__ == '__main__':
# Create RKNN object
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[[127.5, 127.5, 127.5], [0, 0, 0], [0, 0, 0], [127.5]],
std_values=[[128, 128, 128], [1, 1, 1], [1, 1, 1], [128]])
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_tensorflow(tf_pb='./conv_128.pb',
inputs=['input1', 'input2', 'input3', 'input4'],
@ -33,18 +33,18 @@ if __name__ == '__main__': @@ -33,18 +33,18 @@ if __name__ == '__main__':
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn('./conv_128.rknn')
if ret != 0:
print('Export rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
@ -64,9 +64,7 @@ if __name__ == '__main__': @@ -64,9 +64,7 @@ if __name__ == '__main__':
outputs = rknn.inference(inputs=[img, input2, input3, img_gray])
np.save('./functions_multi_input_test_0.npy', outputs[0])
print('done')
outputs[0] = outputs[0].reshape((1,-1))
outputs[0] = outputs[0].reshape((1, -1))
print('inference result: ', outputs)
rknn.release()

18
examples/onnx/resnet50v2/test.py

@ -61,7 +61,7 @@ def show_progress(blocknum, blocksize, totalsize): @@ -61,7 +61,7 @@ def show_progress(blocknum, blocksize, totalsize):
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# If resnet50v2 does not exist, download it.
# Download address:
@ -79,7 +79,8 @@ if __name__ == '__main__': @@ -79,7 +79,8 @@ if __name__ == '__main__':
exit(-1)
print('done')
# print('--> config model')
# pre-process config
print('--> config model')
rknn.config(mean_values=[123.675, 116.28, 103.53], std_values=[58.82, 58.82, 58.82])
print('done')
@ -87,7 +88,7 @@ if __name__ == '__main__': @@ -87,7 +88,7 @@ if __name__ == '__main__':
print('--> Loading model')
ret = rknn.load_onnx(model=ONNX_MODEL)
if ret != 0:
print('Load resnet50v2 failed!')
print('Load model failed!')
exit(ret)
print('done')
@ -95,15 +96,15 @@ if __name__ == '__main__': @@ -95,15 +96,15 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build resnet50 failed!')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn(RKNN_MODEL)
if ret != 0:
print('Export resnet50v2.rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
@ -111,11 +112,11 @@ if __name__ == '__main__': @@ -111,11 +112,11 @@ if __name__ == '__main__':
img = cv2.imread('./dog_224x224.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
@ -130,4 +131,3 @@ if __name__ == '__main__': @@ -130,4 +131,3 @@ if __name__ == '__main__':
print('done')
rknn.release()

BIN
examples/onnx/yolov5/bus.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

2
examples/onnx/yolov5/dataset.txt

@ -1 +1 @@ @@ -1 +1 @@
dog_bike_car_640x640.jpg
bus.jpg

BIN
examples/onnx/yolov5/dog_bike_car_640x640.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 KiB

521
examples/onnx/yolov5/test.py

@ -1,301 +1,308 @@ @@ -1,301 +1,308 @@
import cv2
from PIL import Image
import os
import urllib
import traceback
import time
import sys
import numpy as np
import torch
import onnxruntime
import cv2
from rknn.api import RKNN
NUM_CLS = 80
LISTSIZE = NUM_CLS+5
SPAN = 3
OBJ_THRESH = 0.2
NMS_THRESH = 0.5
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 ")
masks = [[0,1,2], [3,4,5], [6,7,8]] #yolov5s
anchors = [[10,13],[16,30],[33,23],[30,61],[62,45],[59,119],[116,90],[156,198],[373,326]]
def letterbox_image(image, size):
iw, ih = image.size
w, h = size
scale = min(w / iw, h / ih)
nw = int(iw * scale)
nh = int(ih * scale)
image = np.array(image)
image = cv2.resize(image, (nw, nh), interpolation=cv2.INTER_LINEAR)
image = Image.fromarray(image)
new_image = Image.new('RGB', size, (128, 128, 128))
new_image.paste(image, ((w - nw) // 2, (h - nh) // 2))
return new_image
def w_bbox_iou(box1, box2, x1y1x2y2=True):
"""
计算IOU
ONNX_MODEL = 'yolov5s.onnx'
RKNN_MODEL = 'yolov5s.rknn'
IMG_PATH = './bus.jpg'
DATASET = './dataset.txt'
QUANTIZE_ON = True
BOX_THESH = 0.5
NMS_THRESH = 0.6
IMG_SIZE = 640
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_w).reshape(-1, grid_w)
row = np.tile(np.arange(0, grid_h).reshape(-1, 1), grid_h)
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/grid_h)
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.
"""
if not x1y1x2y2:
b1_x1, b1_x2 = box1[:, 0] - box1[:, 2] / 2, box1[:, 0] + box1[:, 2] / 2
b1_y1, b1_y2 = box1[:, 1] - box1[:, 3] / 2, box1[:, 1] + box1[:, 3] / 2
b2_x1, b2_x2 = box2[:, 0] - box2[:, 2] / 2, box2[:, 0] + box2[:, 2] / 2
b2_y1, b2_y2 = box2[:, 1] - box2[:, 3] / 2, box2[:, 1] + box2[:, 3] / 2
else:
b1_x1, b1_y1, b1_x2, b1_y2 = box1[:, 0], box1[:, 1], box1[:, 2], box1[:, 3]
b2_x1, b2_y1, b2_x2, b2_y2 = box2[:, 0], box2[:, 1], box2[:, 2], box2[:, 3]
inter_rect_x1 = torch.max(b1_x1, b2_x1)
inter_rect_y1 = torch.max(b1_y1, b2_y1)
inter_rect_x2 = torch.min(b1_x2, b2_x2)
inter_rect_y2 = torch.min(b1_y2, b2_y2)
inter_area = torch.clamp(inter_rect_x2 - inter_rect_x1 + 1, min=0) * \
torch.clamp(inter_rect_y2 - inter_rect_y1 + 1, min=0)
b1_area = (b1_x2 - b1_x1 + 1) * (b1_y2 - b1_y1 + 1)
b2_area = (b2_x2 - b2_x1 + 1) * (b2_y2 - b2_y1 + 1)
iou = inter_area / (b1_area + b2_area - inter_area + 1e-16)
return iou
def w_non_max_suppression(prediction, num_classes, conf_thres=0.1, nms_thres=0.4):
# 求左上角和右下角
# box_corner = prediction.new(prediction.shape)
box_corner = torch.FloatTensor(prediction.shape)
box_corner[:, :, 0] = prediction[:, :, 0] - prediction[:, :, 2] / 2
box_corner[:, :, 1] = prediction[:, :, 1] - prediction[:, :, 3] / 2
box_corner[:, :, 2] = prediction[:, :, 0] + prediction[:, :, 2] / 2
box_corner[:, :, 3] = prediction[:, :, 1] + prediction[:, :, 3] / 2
prediction[:, :, :4] = box_corner[:, :, :4]
output = [None for _ in range(len(prediction))]
for image_i, image_pred in enumerate(prediction):
# 利用置信度进行第一轮筛选
conf_mask = (image_pred[:, 4] >= conf_thres).squeeze()
image_pred = image_pred[conf_mask]
if not image_pred.size(0):
continue
# 获得种类及其置信度
class_conf, class_pred = torch.max(image_pred[:, 5:5 + num_classes], 1, keepdim=True)
# 获得的内容为(x1, y1, x2, y2, obj_conf, class_conf, class_pred)
detections = torch.cat((image_pred[:, :5], class_conf.float(), class_pred.float()), 1)
# 获得种类
unique_labels = detections[:, -1].cpu().unique()
if prediction.is_cuda:
unique_labels = unique_labels.cuda()
for c in unique_labels:
# 获得某一类初步筛选后全部的预测结果
detections_class = detections[detections[:, -1] == c]
# 按照存在物体的置信度排序
_, conf_sort_index = torch.sort(detections_class[:, 4], descending=True)
detections_class = detections_class[conf_sort_index]
# 进行非极大抑制
max_detections = []
while detections_class.size(0):
# 取出这一类置信度最高的,一步一步往下判断,判断重合程度是否大于nms_thres,如果是则去除掉
max_detections.append(detections_class[0].unsqueeze(0))
if len(detections_class) == 1:
break
ious = w_bbox_iou(max_detections[-1], detections_class[1:])
detections_class = detections_class[1:][ious < nms_thres]
# 堆叠
max_detections = torch.cat(max_detections).data
# Add max detections to outputs
output[image_i] = max_detections if output[image_i] is None else torch.cat(
(output[image_i], max_detections))
return output
def onnx_postprocess(outputs, img_size_w, img_size_h):
boxs = []
a = torch.tensor(anchors).float().view(3, -1, 2)
anchor_grid = a.clone().view(3, 1, -1, 1, 1, 2)
for index, out in enumerate(outputs):
out = torch.from_numpy(out)
batch = out.shape[1]
feature_h = out.shape[2]
feature_w = out.shape[3]
# Feature map corresponds to the original image zoom factor
stride_w = int(img_size_w / feature_w)
stride_h = int(img_size_h / feature_h)
grid_x, grid_y = np.meshgrid(np.arange(feature_w), np.arange(feature_h))
grid_x, grid_y = torch.from_numpy(np.array(grid_x)).float(), torch.from_numpy(np.array(grid_y)).float()
# cx, cy, w, h
pred_boxes = torch.FloatTensor(out[..., :4].shape)
pred_boxes[..., 0] = (torch.sigmoid(out[..., 0]) * 2.0 - 0.5 + grid_x) * stride_w # cx
pred_boxes[..., 1] = (torch.sigmoid(out[..., 1]) * 2.0 - 0.5 + grid_y) * stride_h # cy
pred_boxes[..., 2:4] = (torch.sigmoid(out[..., 2:4]) * 2) ** 2 * anchor_grid[index] # wh
pred_boxes_np = pred_boxes.numpy()
conf = torch.sigmoid(out[..., 4])
pred_cls = torch.sigmoid(out[..., 5:])
output = torch.cat((pred_boxes.view(1, -1, 4),
conf.view(1, -1, 1),
pred_cls.view(1, -1, NUM_CLS)),
-1)
boxs.append(output)
outputx = torch.cat(boxs, 1)
# NMS
batch_detections = w_non_max_suppression(outputx, NUM_CLS, conf_thres=OBJ_THRESH, nms_thres=NMS_THRESH)
return batch_detections
def clip_coords(boxes, img_shape):
# Clip bounding xyxy bounding boxes to image shape (height, width)
boxes[:, 0].clamp_(0, img_shape[1]) # x1
boxes[:, 1].clamp_(0, img_shape[0]) # y1
boxes[:, 2].clamp_(0, img_shape[1]) # x2
boxes[:, 3].clamp_(0, img_shape[0]) # y2
def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):
# Rescale coords (xyxy) from img1_shape to img0_shape
if ratio_pad is None: # calculate from img0_shape
gain = min(img1_shape[0]/img0_shape[0], img1_shape[1]/img0_shape[1]) # gain = old / new
pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2 # wh padding
else:
gain = ratio_pad[0][0]
pad = ratio_pad[1]
coords[:, [0, 2]] -= pad[0] # x padding
coords[:, [1, 3]] -= pad[1] # y padding
coords[:, :4] /= gain
clip_coords(coords, img0_shape)
return coords
def display(detections=None, image_src=None, input_size=(640, 640), line_thickness=None, text_bg_alpha=0.0):
labels = detections[..., -1]
boxs = detections[..., :4]
confs = detections[..., 4]
h, w, c = image_src.shape
boxs[:, :] = scale_coords(input_size, boxs[:, :], (h, w)).round()
tl = line_thickness or round(0.002 * (w + h) / 2) + 1
for i, box in enumerate(boxs):
x1, y1, x2, y2 = box
ratio = (y2-y1)/(x2-x1)
x1, y1, x2, y2 = int(x1.numpy()), int(y1.numpy()), int(x2.numpy()), int(y2.numpy())
np.random.seed(int(labels[i].numpy()) + 2020)
color = (np.random.randint(0, 255), 0, np.random.randint(0, 255))
cv2.rectangle(image_src, (x1, y1), (x2, y2), color, max(int((w + h) / 600), 1), cv2.LINE_AA)
label = '{0:.3f}'.format(confs[i])
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=1)[0]
c2 = x1 + t_size[0] + 3, y1 - t_size[1] - 5
if text_bg_alpha == 0.0:
cv2.rectangle(image_src, (x1 - 1, y1), c2, color, cv2.FILLED, cv2.LINE_AA)
else:
# 透明文本背景
alphaReserve = text_bg_alpha # 0:不透明 1:透明
BChannel, GChannel, RChannel = color
xMin, yMin = int(x1 - 1), int(y1 - t_size[1] - 3)
xMax, yMax = int(x1 + t_size[0]), int(y1)
image_src[yMin:yMax, xMin:xMax, 0] = image_src[yMin:yMax, xMin:xMax, 0] * alphaReserve + BChannel * (1 - alphaReserve)
image_src[yMin:yMax, xMin:xMax, 1] = image_src[yMin:yMax, xMin:xMax, 1] * alphaReserve + GChannel * (1 - alphaReserve)
image_src[yMin:yMax, xMin:xMax, 2] = image_src[yMin:yMax, xMin:xMax, 2] * alphaReserve + RChannel * (1 - alphaReserve)
cv2.putText(image_src, label, (x1 + 3, y1 - 4), 0, tl / 3, [255, 255, 255],
thickness=1, lineType=cv2.LINE_AA)
box_classes = np.argmax(box_class_probs, axis=-1)
box_class_scores = np.max(box_class_probs, axis=-1)
pos = np.where(box_confidences[..., 0] >= BOX_THESH)
boxes = boxes[pos]
classes = box_classes[pos]
scores = box_class_scores[pos]
return boxes, classes, scores
if __name__ == '__main__':
exp = 'yolov5s'
Width = 640
Height = 640
MODEL_PATH = './yolov5s.onnx'
im_file = './dog_bike_car_640x640.jpg'
RKNN_MODEL_PATH = './{}.rknn'.format(exp + '-' + str(Width) + '-' + str(Height))
DATASET = './dataset.txt'
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(verbose=True)
# pre-process config
print('--> Config model')
rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], output_tensor_type='int8')
print('done')
rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]])
# Load model
# Load ONNX model
print('--> Loading model')
ret = rknn.load_onnx(MODEL_PATH)
ret = rknn.load_onnx(model=ONNX_MODEL, outputs=['378', '439', '500'])
if ret != 0:
print('load model failed!')
print('Load model failed!')
exit(ret)
print('done')
# Build model
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset=DATASET)
ret = rknn.build(do_quantization=QUANTIZE_ON, dataset=DATASET)
if ret != 0:
print('build model failed.')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
ret = rknn.export_rknn(RKNN_MODEL_PATH)
# Export RKNN model
print('--> Export rknn model')
ret = rknn.export_rknn(RKNN_MODEL)
if ret != 0:
print('Export rknn model failed.')
print('Export rknn model failed!')
exit(ret)
print('done')
# Set inputs
image_src = Image.open('./dog_bike_car_640x640.jpg')
img = letterbox_image(image_src, (Width, Height))
img = np.array(img)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
# ret = rknn.init_runtime('rk3566')
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
# inference
print('--> inference')
start = time.time()
outputs = rknn.inference(inputs=[img])
end = time.time()
print('inference time: ', end - start)
print('done')
# Set inputs
img = cv2.imread(IMG_PATH)
# img, ratio, (dw, dh) = letterbox(img, new_shape=(IMG_SIZE, IMG_SIZE))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))
# Inference
print('--> Running model')
outputs = rknn.inference(inputs=[img])
np.save('./onnx_yolov5_0.npy', outputs[0])
np.save('./onnx_yolov5_1.npy', outputs[1])
np.save('./onnx_yolov5_2.npy', outputs[2])
print('done')
# inference process
image_src = np.array(image_src)
detections = onnx_postprocess(outputs, Width, Height)
if detections[0] is not None:
display(detections[0], image_src)
# post process
input0_data = outputs[0]
input1_data = outputs[1]
input2_data = outputs[2]
image_src = cv2.cvtColor(image_src,cv2.COLOR_BGR2RGB)
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:]))
cv2.imwrite("result.jpg", image_src)
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)))
rknn.release()
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)
# show output
# cv2.imshow("post process result", img_1)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
rknn.release()

BIN
examples/onnx/yolov5/yolov5s.onnx

Binary file not shown.

23
examples/pytorch/resnet18/test.py

@ -48,18 +48,18 @@ if __name__ == '__main__': @@ -48,18 +48,18 @@ if __name__ == '__main__':
input_size_list = [[1, 3, 224, 224]]
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[123.675, 116.28, 103.53], std_values=[58.395, 58.395, 58.395])
print('done')
# Load pytorch model
# Load model
print('--> Loading model')
ret = rknn.load_pytorch(model=model, input_size_list=input_size_list)
if ret != 0:
print('Load pytorch model failed!')
print('Load model failed!')
exit(ret)
print('done')
@ -67,29 +67,27 @@ if __name__ == '__main__': @@ -67,29 +67,27 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build pytorch failed!')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn('./resnet_18.rknn')
if ret != 0:
print('Export resnet_18.rknn failed!')
print('Export rknn model failed!')
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
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
@ -97,7 +95,6 @@ if __name__ == '__main__': @@ -97,7 +95,6 @@ if __name__ == '__main__':
print('--> Running model')
outputs = rknn.inference(inputs=[img])
np.save('./pytorch_resnet18_0.npy', outputs[0])
show_outputs(softmax(np.array(outputs[0][0])))
print('done')

86
examples/pytorch/resnet18_export_onnx/test.py

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
import torch
import torch.nn as nn
from torch.nn import functional as F
class RestNetBasicBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride):
super(RestNetBasicBlock, self).__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1)
self.bn1 = nn.BatchNorm2d(out_channels)
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride, padding=1)
self.bn2 = nn.BatchNorm2d(out_channels)
def forward(self, x):
output = self.conv1(x)
output = F.relu(self.bn1(output))
output = self.conv2(output)
output = self.bn2(output)
return F.relu(x + output)
class RestNetDownBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride):
super(RestNetDownBlock, self).__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride[0], padding=1)
self.bn1 = nn.BatchNorm2d(out_channels)
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride[1], padding=1)
self.bn2 = nn.BatchNorm2d(out_channels)
self.extra = nn.Sequential(
nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride[0], padding=0),
nn.BatchNorm2d(out_channels)
)
def forward(self, x):
extra_x = self.extra(x)
output = self.conv1(x)
out = F.relu(self.bn1(output))
out = self.conv2(out)
out = self.bn2(out)
return F.relu(extra_x + out)
class RestNet18(nn.Module):
def __init__(self):
super(RestNet18, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3)
self.bn1 = nn.BatchNorm2d(64)
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
self.layer1 = nn.Sequential(RestNetBasicBlock(64, 64, 1),
RestNetBasicBlock(64, 64, 1))
self.layer2 = nn.Sequential(RestNetDownBlock(64, 128, [2, 1]),
RestNetBasicBlock(128, 128, 1))
self.layer3 = nn.Sequential(RestNetDownBlock(128, 256, [2, 1]),
RestNetBasicBlock(256, 256, 1))
self.layer4 = nn.Sequential(RestNetDownBlock(256, 512, [2, 1]),
RestNetBasicBlock(512, 512, 1))
self.avgpool = nn.AdaptiveAvgPool2d(output_size=(1, 1))
self.fc = nn.Linear(512, 10)
def forward(self, x):
out = self.conv1(x)
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = self.avgpool(out)
out = out.reshape(x.shape[0], -1)
out = self.fc(out)
return out
if __name__ == '__main__':
# build model
model = RestNet18()
model.eval()
# export onnx (rknn-toolkit2 only support opset_version=12)
x = torch.randn((1, 3, 224, 224))
torch.onnx.export(model, x, './resnet18.onnx', opset_version=12, input_names=['input'], output_names=['output'])

BIN
examples/pytorch/resnet18_qat/resnet18_i8.pt

Binary file not shown.

BIN
examples/pytorch/resnet18_qat/space_shuttle_224.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

103
examples/pytorch/resnet18_qat/test.py

@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
import numpy as np
import cv2
from rknn.api import RKNN
import torchvision.models as models
import torch
import os
def show_outputs(output):
output_sorted = sorted(output, reverse=True)
top5_str = '\n-----TOP 5-----\n'
for i in range(5):
value = output_sorted[i]
index = np.where(output == value)
for j in range(len(index)):
if (i + j) >= 5:
break
if value > 0:
topi = '{}: {}\n'.format(index[j], value)
else:
topi = '-1: 0.0\n'
top5_str += topi
print(top5_str)
def show_perfs(perfs):
perfs = 'perfs: {}\n'.format(perfs)
print(perfs)
def softmax(x):
return np.exp(x)/sum(np.exp(x))
def torch_version():
import torch
torch_ver = torch.__version__.split('.')
torch_ver[2] = torch_ver[2].split('+')[0]
return [int(v) for v in torch_ver]
if __name__ == '__main__':
if torch_version() < [1, 9, 0]:
import torch
print("Your torch version is '{}', in order to better support the Quantization Aware Training (QAT) model,\n"
"Please update the torch version to '1.9.0' or higher!".format(torch.__version__))
exit(0)
model = './resnet18_i8.pt'
input_size_list = [[1, 3, 224, 224]]
# Create RKNN object
rknn = RKNN(verbose=True)
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[123.675, 116.28, 103.53], std_values=[58.395, 58.395, 58.395])
print('done')
# Load model
print('--> Loading model')
ret = rknn.load_pytorch(model=model, input_size_list=input_size_list)
if ret != 0:
print('Load model failed!')
exit(ret)
print('done')
# Build model
print('--> Building model')
ret = rknn.build(do_quantization=False)
if ret != 0:
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export rknn model')
ret = rknn.export_rknn('./resnet_18.rknn')
if ret != 0:
print('Export rknn model failed!')
exit(ret)
print('done')
# 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 ret != 0:
print('Init runtime environment failed!')
exit(ret)
print('done')
# Inference
print('--> Running model')
outputs = rknn.inference(inputs=[img])
np.save('./pytorch_resnet18_qat_0.npy', outputs[0])
show_outputs(softmax(np.array(outputs[0][0])))
print('done')
rknn.release()

0
examples/functions/load_quantized_model/README.md → examples/tensorflow/inception_v3_qat/README.md

0
examples/functions/load_quantized_model/goldfish_299x299.jpg → examples/tensorflow/inception_v3_qat/goldfish_299x299.jpg

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

29
examples/functions/load_quantized_model/test.py → examples/tensorflow/inception_v3_qat/test.py

@ -16,6 +16,7 @@ OUTPUTS = ['InceptionV3/Logits/SpatialSqueeze'] @@ -16,6 +16,7 @@ OUTPUTS = ['InceptionV3/Logits/SpatialSqueeze']
IMG_PATH = './goldfish_299x299.jpg'
INPUT_SIZE = 299
def show_outputs(outputs):
output = outputs[0][0]
output_sorted = sorted(output, reverse=True)
@ -62,10 +63,11 @@ def show_progress(blocknum, blocksize, totalsize): @@ -62,10 +63,11 @@ def show_progress(blocknum, blocksize, totalsize):
f.flush()
f.write('\r\n')
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# If inception_v3_quant_frozen.pb does not exist, download it.
# Download address:
@ -99,22 +101,20 @@ if __name__ == '__main__': @@ -99,22 +101,20 @@ if __name__ == '__main__':
shutil.rmtree(target_dir)
os.remove(download_file)
print('done')
# pre-process config
# Pre-process config
print('--> Config model')
rknn.config()
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_tensorflow(tf_pb=PB_FILE,
inputs=INPUTS,
outputs=OUTPUTS,
input_size_list=[[1, INPUT_SIZE, INPUT_SIZE, 3]],
predef_file=None,
mean_values=[[128]],
std_values=[[128]])
input_size_list=[[1, INPUT_SIZE, INPUT_SIZE, 3]])
if ret != 0:
print('Load inception_v3_quant_frozen failed!')
print('Load model failed!')
exit(ret)
print('done')
@ -122,15 +122,15 @@ if __name__ == '__main__': @@ -122,15 +122,15 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=False)
if ret != 0:
print('Build inception_v3_quant_frozen.rknn failed!')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn(RKNN_MODEL_PATH)
if ret != 0:
print('Export inception_v3_quant_frozen.rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
@ -138,18 +138,18 @@ if __name__ == '__main__': @@ -138,18 +138,18 @@ if __name__ == '__main__':
img = cv2.imread(IMG_PATH)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
# Inference
print('--> Running model')
outputs = rknn.inference(inputs=[img])
np.save('./functions_load_quantized_model_0.npy', outputs[0])
np.save('./tensorflow_inception_v3_qat_0.npy', outputs[0])
x = outputs[0]
output = np.exp(x)/np.sum(np.exp(x))
outputs = [output]
@ -157,4 +157,3 @@ if __name__ == '__main__': @@ -157,4 +157,3 @@ if __name__ == '__main__':
print('done')
rknn.release()

54
examples/tensorflow/ssd_mobilenet_v1/test.py

@ -21,8 +21,10 @@ W_SCALE = 5.0 @@ -21,8 +21,10 @@ W_SCALE = 5.0
def expit(x):
return 1. / (1. + math.exp(-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):
w = max(0.0, min(xmax0, xmax1) - max(xmin0, xmin1))
@ -53,44 +55,53 @@ def load_box_priors(): @@ -53,44 +55,53 @@ def load_box_priors():
return box_priors
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# Config for Model Input PreProcess
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[127.5, 127.5, 127.5], std_values=[127.5, 127.5, 127.5])
print('done')
# Load TensorFlow Model
# Load model
print('--> Loading model')
rknn.load_tensorflow(tf_pb='./ssd_mobilenet_v1_coco_2017_11_17.pb',
inputs=['FeatureExtractor/MobilenetV1/MobilenetV1/Conv2d_0/BatchNorm/batchnorm/mul_1'],
outputs=['concat', 'concat_1'],
input_size_list=[[1, INPUT_SIZE, INPUT_SIZE, 3]])
ret = rknn.load_tensorflow(tf_pb='./ssd_mobilenet_v1_coco_2017_11_17.pb',
inputs=['Preprocessor/sub'],
outputs=['concat', 'concat_1'],
input_size_list=[[1, INPUT_SIZE, INPUT_SIZE, 3]])
if ret != 0:
print('Load model failed!')
exit(ret)
print('done')
# Build Model
print('--> Building model')
rknn.build(do_quantization=True, dataset='./dataset.txt')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build model failed!')
exit(ret)
print('done')
# Export RKNN Model
rknn.export_rknn('./ssd_mobilenet_v1_coco.rknn')
# Direct Load RKNN Model
# rknn.load_rknn('./ssd_mobilenet_v1_coco.rknn')
# Export rknn model
print('--> Export rknn model')
ret = rknn.export_rknn('./ssd_mobilenet_v1_coco.rknn')
if ret != 0:
print('Export rknn model failed!')
exit(ret)
print('done')
# Set inputs
orig_img = cv2.imread('./road.bmp')
img = cv2.cvtColor(orig_img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (INPUT_SIZE, INPUT_SIZE), interpolation=cv2.INTER_CUBIC)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
@ -116,7 +127,7 @@ if __name__ == '__main__': @@ -116,7 +127,7 @@ if __name__ == '__main__':
# 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
@ -147,7 +158,7 @@ if __name__ == '__main__': @@ -147,7 +158,7 @@ if __name__ == '__main__':
predictions[0][n][1] = xmin
predictions[0][n][2] = ymax
predictions[0][n][3] = xmax
# NMS
for i in range(0, vaildCnt):
if candidateBox[0][i] == -1:
@ -175,8 +186,6 @@ if __name__ == '__main__': @@ -175,8 +186,6 @@ if __name__ == '__main__':
if iou >= 0.45:
candidateBox[0][j] = -1
# Draw result
for i in range(0, vaildCnt):
if candidateBox[0][i] == -1:
@ -191,9 +200,8 @@ if __name__ == '__main__': @@ -191,9 +200,8 @@ if __name__ == '__main__':
print("%d @ (%d, %d) (%d, %d) score=%f" % (topClassScoreIndex, xmin, ymin, xmax, ymax, topClassScore))
cv2.rectangle(orig_img, (int(xmin), int(ymin)), (int(xmax), int(ymax)),
(random.random()*255, random.random()*255, random.random()*255), 3)
(random.random()*255, random.random()*255, random.random()*255), 3)
cv2.imwrite("out.jpg", orig_img)
# Release RKNN Context
rknn.release()

20
examples/tflite/mobilenet_v1/test.py

@ -24,18 +24,18 @@ def show_outputs(outputs): @@ -24,18 +24,18 @@ def show_outputs(outputs):
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[128, 128, 128], std_values=[128, 128, 128])
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_tflite(model='mobilenet_v1_1.0_224.tflite')
if ret != 0:
print('Load mobilenet_v1 failed!')
print('Load model failed!')
exit(ret)
print('done')
@ -43,15 +43,15 @@ if __name__ == '__main__': @@ -43,15 +43,15 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=True, dataset='./dataset.txt')
if ret != 0:
print('Build mobilenet_v1 failed!')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn('./mobilenet_v1.rknn')
if ret != 0:
print('Export mobilenet_v1.rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
@ -60,11 +60,11 @@ if __name__ == '__main__': @@ -60,11 +60,11 @@ if __name__ == '__main__':
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = np.expand_dims(img, 0)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')

BIN
examples/tflite/mobilenet_v1_qat/dog_224x224.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

0
examples/tflite/mobilenet_v1_quant/mobilenet_v1_1.0_224_quant.tflite → examples/tflite/mobilenet_v1_qat/mobilenet_v1_1.0_224_quant.tflite

24
examples/tflite/mobilenet_v1_quant/test.py → examples/tflite/mobilenet_v1_qat/test.py

@ -24,18 +24,18 @@ def show_outputs(outputs): @@ -24,18 +24,18 @@ def show_outputs(outputs):
if __name__ == '__main__':
# Create RKNN object
rknn = RKNN()
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
rknn.config(mean_values=[128, 128, 128], std_values=[128, 128, 128])
# Pre-process config
print('--> Config model')
rknn.config(mean_values=[0, 0, 0], std_values=[1, 1, 1])
print('done')
# Load tensorflow model
# Load model
print('--> Loading model')
ret = rknn.load_tflite(model='mobilenet_v1_1.0_224_quant.tflite')
if ret != 0:
print('Load mobilenet_v1 failed!')
print('Load model failed!')
exit(ret)
print('done')
@ -43,15 +43,15 @@ if __name__ == '__main__': @@ -43,15 +43,15 @@ if __name__ == '__main__':
print('--> Building model')
ret = rknn.build(do_quantization=False)
if ret != 0:
print('Build mobilenet_v1 failed!')
print('Build model failed!')
exit(ret)
print('done')
# Export rknn model
print('--> Export RKNN model')
print('--> Export rknn model')
ret = rknn.export_rknn('./mobilenet_v1.rknn')
if ret != 0:
print('Export mobilenet_v1.rknn failed!')
print('Export rknn model failed!')
exit(ret)
print('done')
@ -60,18 +60,18 @@ if __name__ == '__main__': @@ -60,18 +60,18 @@ if __name__ == '__main__':
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = np.expand_dims(img, 0)
# init runtime environment
# Init runtime environment
print('--> Init runtime environment')
ret = rknn.init_runtime()
if ret != 0:
print('Init runtime environment failed')
print('Init runtime environment failed!')
exit(ret)
print('done')
# Inference
print('--> Running model')
outputs = rknn.inference(inputs=[img])
np.save('./tflite_mobilenet_v1_quant_0.npy', outputs[0])
np.save('./tflite_mobilenet_v1_qat_0.npy', outputs[0])
show_outputs(outputs)
print('done')

BIN
packages/rknn_toolkit2-1.1.1_5c458c6-cp36-cp36m-linux_x86_64.whl → packages/rknn_toolkit2-1.2.0_f7bb160f-cp36-cp36m-linux_x86_64.whl

Binary file not shown.
Loading…
Cancel
Save