RKNN-Toolkit 使用手册

0x00 说明

本文档中RKNN-SDK 位于 ~/rk1808_linux_v1.00_20181227/

RKNN-Toolkit 和 RKNN demo 包位于 ~/rk1808_linux_v1.00_20181227/external/rknpu/

其中 rknn 文件夹为 RKNN demo,用于生成可在开发板上运行的可执行文件,rknn-toolkit 用于将其他模型转换成 rknn 模型并在 PC 上进行性能测试。

0x01 环境配置

OS: Ubuntu 16.04 x64 以上

Python: 3.5/3.6

Tensorflow: >= 1.11.0

使用 Anaconda3 安装: Anaconda3-2019.03-Linux-x86_64.sh

安装 ADB

apt install android-tools-adb

安装后配置:

由于 conda 镜像中处理 Tensorflow 1.11.0 依赖时会降低其他库的版本,这里使用 Tensorflow 1.13.1。

conda install python=3.7
conda install tensorflow=1.13.1
conda install opencv=3.4.1
pip install ~/rk1808_linux_v1.00_20181227/external/rknpu/rknn-toolkit/packages/rknn_toolkit-0.9.8-cp36-cp36m-linux_x86_64.whl

0x02 转换模型

转换模型使用 RKNN-Toolkit,SDK 中提供了三种基于 MobileNet 的转换工具,位于 ~/rk1808_linux_v1.00_20181227/external/rknpu/rknn-toolkit/example 目录下,本文档以使用 mobilenet-ssd 转换 Tensorflow 的 .pb 模型为例。

进入 mobilenet-ssd 目录下,运行 ssd.py

cd ~/rk1808_linux_v1.00_20181227/external/rknpu/rknn-toolkit/example/mobilenet-ssd
python ssd.py

转换成功后输出如下:

--> Loading model
done
--> Building model
done
--> Init runtime environment
done
--> Running model
done
inference resule:  [array([[ 0.89453125,  0.18859863, -3.0390625 , ..., -0.0308075 ,
        -2.4863281 , -0.10644531]], dtype=float32), array([[  2.4785156,  -4.7382812,  -7.9335938, ..., -10.0859375,
         -9.625    , -10.4140625]], dtype=float32)]
========================================================================
                               Performance
========================================================================
Layer Id    Name                                         Time(us)
0           convolution.relu.pooling.layer2_3            1005
1           activation.layer_3                           510
2           convolution.relu.pooling.layer2_2            774
3           activation.layer_3                           510
''''''
91          fullyconnected.relu.layer_3                  17
92          tensor.ranspose_3                            4
93          tensor.ranspose_3                            5
Total Time(us): 165830
FPS(800MHz): 6.03
========================================================================

转换其他模型:

修改 ssd.pyrknn.load_tensorflowtf_pb.pb 模型文件的路径;input 为模型输入节点;output 为模型输出节点;input_size_list 为输入节点对应的图片尺寸和通道数。

rknn.config 方法中 channel_mean_value 为模型均值;reorder_channel 为通道顺序,0 1 2 为 RGB,2 1 0 为 BGR。

rknn.build 方法中 do_quantization 为生成 rknn 模型是否进行量化的控制参数,dataset 为进行量化时使用的图片,建议大于 200 张。

如果将 do_quantization 设置为 True,根据情况(可能报错)需要在 rknn.config 方法中添加参数 batch_sizeepochs,如果性能足够可以设置 batch_size=200,epochs=1,如果显存不足可以设置为 batch_size=1,epochs=200

rknn.export_rknn 方法用于设置 rknn 模型输出路径及文件名称。

rknn.export_rknn 方法后面的代码可以对导出的 rknn 模型进行性能评估。

注意:如果在性能评估或检测时发生检测出目标数量过多的情况,请检查 rknn_inference 方法输出的数组元素顺序是否需要调换,例如:

outputs = rknn.inference(inputs=[img])
predoctions = outputs[1].reshape((1, NUM_RESULTS, 4))
outputClasses = outputs[0].reshape((1, NUM_RESULTS, NUM_CLASSES))

其中 predictions 在 SDK 提供的模型中使用 outputs[0] 中的值,而在自行转换的模型中需要使用 outputs[1],的值,outputClasses 同理。

如果在转换模型时发现了这个问题,在 demo 的 main.cc 中也需要修改 outputs 数组顺序,例如:

postProcessSSD((float *)(outputs[1].buf), (float *)(outputs[0].buf). orig_img.cols, orig_img.rows, &detect_result_group);

如果出现了上述错误,应尝试将这段代码修改为:

postProcessSSD((float *)(outputs[0].buf), (float *)(outputs[1].buf). orig_img.cols, orig_img.rows, &detect_result_group);

0x03 在开发板上运行 demo

SDK 中提供了三种基于 MobileNet 的 demo

位于 ~/rk1808_linux_v1.00_20181227/external/rknpu/rknn/examples 目录下,本文档以调用由 MobileNet-SSD Tensorflow pb 模型转换的 rknn 模型使用 rknn_ssd_demo 对 road.bmp 进行目标检测为例。

road.bmp

过程如下:

进入 demo 目录,建立 build 文件夹

cd ~/rk1808_linux_v1.00_20181227/external/rknpu/rknn/examples/rknn_ssd_demo
mkdir build
cd build

编译

cmake ..
make
make install
cd ..

此时 demo 目录下应出现 install 文件夹,如果没有请检查环境是否符合要求

将生成的 rknn 模型放入 install/rknn_ssd_demo 文件夹

例如生成的 rknn 模型位于 ~/rk1808_linux_v1.00_20181227/external/rknpu/rknn-toolkit/examples/mobilenet-ssd

模型名称为 ssd_mobilenet_v1_coco.rknn

cp ../../../rknn-toolkit/example/mobilenet-ssd/ssd_mobilenet_v1_coco.rknn ./install/rknn_ssd_demo

测试 adb 连接

adb devices

如果返回类似如下的数据,则连接成功,否则请检查设备与开发机的连接

List of devices attached
0123456789ABCDEF    device

在设备中建立 /userdata/rknn_ssd_demo 目录并将 install 下的 rknn_ssd_demo 文件夹 push 进创建的目录中

adb shell mkdir /userdata/rknn_ssd_demo
adb push ./install/rknn_ssd_demo/* /userdata/rknn_ssd_demo

进入设备终端并进行检测

adb shell
cd /userdata/rknn_ssd_demo
./rknn_ssd_demo ssd_mobilenet_v1_coco.rknn road.bmp

检测成功后输出如下:

Loading model ...
model input num: 1, output num: 2
input tensors:
index=0 name = n_dims=4 dims=[1 3 300 300] n_elems=270000 size=540000 fmt=0 type=1 qnt_type=0 fl=-84 zp=-1311164756 scale=0.000000
output tensors:
index=0 name = n_dims=4 dims=[1 1917 1 4] n_elems=7668 size=15336 fmt=0 type=1 qnt_type=0 fl=-84 zp=-1311164756 scale=0.000000
index=1 name = n_dims=3 dims=[0 1 1917 91] n_elems=174447 size=348894 fmt=0 type=1 qnt_type=0 fl=-84 zp=-1311164756 scale=0.000000
rknn_run
loadLabelName
ssd - loadLabelNameloadBoxPriors
ValidCount: 25
person @ (15 127 55 209) 0.984575
bicycle @ (170 158 283 233) @ 0.958382
person @ (107 119 152 192) 0.948155
car @ (148 134 215 173) 0.930078
person @ (207 112 256 218) 0.838812
person @ (50 135 58 158) 0.470782
person @ (83 133 92 156) 0.433082

退出设备终端并将检测后生成的 out.jpg 拉回本地

exit
adb pull /userdata/rknn_ssd_demo/out.jpg ./

out.png

0x04 自动化脚本

该部分中所有操作均在 demo 目录下进行

在设备中检测

建立 adb_run_rknn_ssd 文件,并写入如下命令,用于在开发机中直接导入设备终端的命令。

cd /userdata/rknn_ssd_demo
./rknn_ssd_demo ssd_mobilenet_v1_coco.rknn road.bmp
exit

在设备中执行检测并将 out.jpg 拉到本地

$ adb shell < adb_run_rknn_ssd && \
> adb pull /userdata/rknn_ssd_demo/out.jpg ./

重新编译代码,在设备中执行检测,并将 out.jpg 拉到本地

cd build/ && \
    rm -rf * && \
    cmake .. && \
    make && \
    make install && \
    cd .. && \
    adb shell mkdir rknn_ssd_demo && \
    adb push ./install/rknn_ssd_demo/* /userdata/rknn_ssd_demo/ && \
    adb shell < adb_run_rknn_ssd && \
    adb pull /userdata/rknn_ssd_demo/out.jpg ./
LICENSED UNDER CC BY-NC-SA 4.0
Comment