RKNN 모델 학습 변환 배포

1. 배경

사람 수 세는 모바일 버전을 만들었지만 데이터 세트가 충분하지 않고 하드웨어에 다른 장치를 장착해야 하기 때문에 실제 환경에서 구현할 수 없는 것은 분명합니다. 그래서 Android 산업용 컴퓨터를 사용하지만 추론은 속도는 매우 느리고 500ms에 가깝습니다. 3568 산업용 컴퓨터 등과 같은 CPU를 변경하는 것이 좋습니다. 속도도 약 150ms이지만 Firefly 관련 문서를 찾았습니다 . Rockchip , NPU를 사용하여 계산을 할 수 있습니다. 시작하겠습니다. .

2. NPU를 먼저 빠르게 경험해보세요.

ROC-RK3568-PC 보드는 하위 플래그쉽이며 3588 성능은 더 높을 것이며 현재 개발을 위해 3568을 사용합니다.

rknn-toolkit은 주로 필요한 라이브러리 주소 rknpu 에 해당하는 RK1808/RK1806/RV1109/RV1126용 이므로 이를 무시하고 다음 도구를 사용하십시오 .

rknn-toolkit2는 주로 필요한 라이브러리 주소 rknpu2 에 해당하는 RK3566/RK3568/RK3588/RK3588S/RV1103/RV1106용입니다 .

사용 지침은 NPU 사용을 참조할 수 있습니다 .

  1. rknpu2를 다운받아 so 라이브러리를 해당 디렉토리에 임포트합니다. 이것은 단순히 NPU 기능을 테스트하기 위한 것입니다.나중에 Android용 프로젝트의 jnilib 하위에 배치됩니다 .
adb root && adb remount
adb push rknpu2_1.4.0/runtime/RK356X/Android/librknn_api/arm64-v8a/* /vendor/lib64
adb push rknpu2_1.4.0/runtime/RK356X/Android/librknn_api/arm64-v8a/* /vendor/lib
  1. 데모를 ROC-RK3568-PC에 넣고 다음과 같이 데모를 실행합니다.
:/ # cd /data/rknn_ssd_demo_Android/    (Linux 系统使用 rknn_ssd_demo_Linux 即可)
:/data/rknn_ssd_demo_Android # chmod 777 rknn_ssd_demo
:/data/rknn_ssd_demo_Android # export LD_LIBRARY_PATH=./lib
:/data/rknn_ssd_demo_Android # ./rknn_ssd_demo model/RK356X/ssd_inception_v2.rknn model/road.bmp (Linux 为 bus.jpg)
Loading model ...
rknn_init ...
model input num: 1, output num: 2
input tensors:
  index=0, name=Preprocessor/sub:0, n_dims=4, dims=[1, 300, 300, 3], n_elems=270000, size=270000, fmt=NHWC, type=UINT8, qnt_type=AFFINE, zp=0, scale=0.007812
output tensors:
  index=0, name=concat:0, n_dims=4, dims=[1, 1917, 1, 4], n_elems=7668, size=30672, fmt=NHWC, type=FP32, qnt_type=AFFINE, zp=53, scale=0.089455
  index=1, name=concat_1:0, n_dims=4, dims=[1, 1917, 91, 1], n_elems=174447, size=697788, fmt=NHWC, type=FP32, qnt_type=AFFINE, zp=53, scale=0.143593
rknn_run
loadLabelName
ssd - loadLabelName ./model/coco_labels_list.txt
loadBoxPriors
person @ (13 125 59 212) 0.984696
person @ (110 119 152 197) 0.969119
bicycle @ (171 165 278 234) 0.969119
person @ (206 113 256 216) 0.964519
car @ (146 133 216 170) 0.959264
person @ (49 133 58 156) 0.606060
person @ (83 134 92 158) 0.606060
person @ (96 135 106 162) 0.464163

이것으로 경험을 마칩니다. 다음으로 모델 변환 환경이 설정됩니다.

3. RKNN 모델 변환

  1. rknn-toolkit2 다운로드 ,
    RKNN-Toolkit2의 현재 버전은 Ubuntu 시스템에 적합합니다. Docker를 사용하는 것이 좋습니다. 이중 시스템을 설치했으며 전환이 불편합니다. Ubuntu 18.04 python 3.6 / Ubuntu 20.04 python 3.8 이어야 합니다
    . 하나만 선택할 수 있습니다. 하나만 선택할 수 있습니다. 하나만 선택할 수 있습니다.
  2. 시스템을 설치한 후 18.04를 예로 들어 필요한 Python 환경을 설치합니다.
#Python3.6
cat doc/requirements_cp36-1.3.0.txt
numpy==1.16.6
onnx==1.7.0
onnxoptimizer==0.1.0
onnxruntime==1.6.0
tensorflow==1.14.0
tensorboard==1.14.0
protobuf==3.12.0
torch==1.6.0
torchvision==0.7.0
psutil==5.6.2
ruamel.yaml==0.15.81
scipy==1.2.1
tqdm==4.27.0
requests==2.21.0
opencv-python==4.4.0.46
PuLP==2.4
scikit_image==0.17.2
# if install bfloat16 failed, please install numpy manually first. "pip install numpy==1.16.6"
bfloat16==1.1
flatbuffers==1.12
  1. Python3.6을 예로 들어 시스템에 동시에 여러 버전의 Python 환경이 있을 수 있으므로 virtualenv를 사용하여 Python 환경을 관리하는 것이 좋습니다.
# 1)安装virtualenv 环境、Python3.6 和 pip3
sudo apt-get install virtualenv \
sudo apt-get install python3 python3-dev python3-pip
# 2)安装相关依赖
sudo apt-get install libxslt1-dev zlib1g zlib1g-dev libglib2.0-0 libsm6 \
libgl1-mesa-glx libprotobuf-dev gcc
# 3)使用 virtualenv 管理 Python 环境并安装 Python 依赖,Python3.6用requirements_cp36-1.3.0.txt
virtualenv -p /usr/bin/python3 venv
source venv/bin/activate
pip3 install -r doc/requirements_cp36-*.txt
# 4)安装 RKNN-Toolkit2,如rknn_toolkit2-1.3.0_11912b58-cp36-cp36m-linux_x86_64.whl
sudo pip3 install packages/rknn_toolkit2*cp36*.whl
# 5)检查RKNN-Toolkit2是否安装成功,可按ctrl+d组合键退出
(venv) firefly@T-chip:~/rknn-toolkit2$ python3
>>> from rknn.api import RKNN
>>>
  1. 나는 yolov5 모델을 사용하고, 변환을 위해 rknn -toolkit2 사용하지 않는다. 입력 및 출력 데모와 비교하여 일관성을 유지할 수 있습니다. 아래 그림과 같이 왼쪽이 지원되는 변환 모델 구조이고, 오른쪽이 공식 yolov5 이므로 오른쪽이 아닌 왼쪽을 가져와야 합니다. 모델 구조를 잘 이해하고 출력을 올바르게 처리할 수 있는 경우가 아니면 .


  2. airockchip 수정 yolov5 모델 교육, 헤드 데이터 세트 , 체중을 사용하여 그가 제공한 yolov5s_relu.pt를 사용할 수도 있습니다 .
  3. onnx 모델 내보내기
导出模型时 python export.py --rknpu {rk_platform} 即可导出优化模型
(rk_platform支持 rk1808, rv1109, rv1126, rk3399pro, rk3566, rk3568, rk3588, rv1103, rv1106)
  1. 모델 변환 참조 rknn_model_zoo/models/CV/object_detection/yolo/RKNN_model_convert
  2. 추론 테스트 참조 rknn_model_zoo/models/CV/object_detection/yolo/RKNN_python_demo

4. Android에서 RKNN 모델 사용

방법 1. rknn_yolov5_android_apk_demo 사용 이미지 입력 ​​시 데이터 처리에 해당 rga 라이브러리가 부족하여 내 보드의 기본 드라이버를 Lenovo에서 수정해야 합니다.

방법 2. RK356X NPU Demo를 사용하여 위의 데모와 비교 이미지 입력은 direct_texture로 처리한 데이터만 사용 후처리 기능만 수정하면 됨 rknn_yolo_demo 참조 , 시그모이드 처리를 사용하지 않음을 알 수 있음 .

static int process_i8(int8_t *input, int *anchor, int grid_h, int grid_w, int height,
           int width, int stride,
           std::vector<float> &boxes, std::vector<float> &boxScores, std::vector<int> &classId,
           float threshold, int32_t zp, float scale) {
    int validCount = 0;
    int grid_len = grid_h * grid_w;
    float thres = threshold;
    auto thres_i8 = qnt_f32_to_affine(thres, zp, scale);
    // puts("==================================");
    // printf("threash %f\n", thres);
    // printf("thres_i8 %u\n", thres_i8);
    // printf("scale %f\n", scale);
    // printf("zp %d\n", zp);
    // puts("==================================");

    //printf("it goes here: file %s, at line %d\n", __FILE__, __LINE__);
    for (int a = 0; a < 3; a++) {
        for (int i = 0; i < grid_h; i++) {

            for (int j = 0; j < grid_w; j++) {

                int8_t box_confidence = input[(YOLOV5_PROP_BOX_SIZE * a + 4) * grid_len +
                                              i * grid_w + j];
                //printf("The box confidence in i8: %d\n", box_confidence);
                if (box_confidence >= thres_i8) {
                    // printf("box_conf %u, thres_i8 %u\n", box_confidence, thres_i8);
                    int offset = (YOLOV5_PROP_BOX_SIZE * a) * grid_len + i * grid_w + j;
                    int8_t *in_ptr = input + offset;

                    int8_t maxClassProbs = in_ptr[5 * grid_len];
                    int maxClassId = 0;
                    for (int k = 1; k < YOLOV5_OBJ_CLASS_NUM; ++k) {
                        int8_t prob = in_ptr[(5 + k) * grid_len];
                        if (prob > maxClassProbs) {
                            maxClassId = k;
                            maxClassProbs = prob;
                        }
                    }

                    float box_conf_f32 = deqnt_affine_to_f32(box_confidence, zp, scale);
                    float class_prob_f32 = deqnt_affine_to_f32(maxClassProbs, zp, scale);
                    float limit_score = box_conf_f32 * class_prob_f32;
//                    LOGI("limit score: %f\n", limit_score);
                    if (limit_score > YOLOV5_CONF_THRESHOLD) {
                        float box_x, box_y, box_w, box_h;

                        box_x = deqnt_affine_to_f32(*in_ptr, zp, scale) * 2.0 - 0.5;
                        box_y = deqnt_affine_to_f32(in_ptr[grid_len], zp, scale) * 2.0 - 0.5;
                        box_w = deqnt_affine_to_f32(in_ptr[2 * grid_len], zp, scale) * 2.0;
                        box_h = deqnt_affine_to_f32(in_ptr[3 * grid_len], zp, scale) * 2.0;
                        box_w = box_w * box_w;
                        box_h = box_h * box_h;

                        box_x = (box_x + j) * (float) stride;
                        box_y = (box_y + i) * (float) stride;
                        box_w *= (float) anchor[a * 2];
                        box_h *= (float) anchor[a * 2 + 1];
                        box_x -= (box_w / 2.0);
                        box_y -= (box_h / 2.0);

                        boxes.push_back(box_x);
                        boxes.push_back(box_y);
                        boxes.push_back(box_w);
                        boxes.push_back(box_h);
                        boxScores.push_back(box_conf_f32 * class_prob_f32);
                        classId.push_back(maxClassId);
                        validCount++;
                    }
                }
            }
        }
    }
    return validCount;
}

발생한 문제

  1. rknn-toolkit2/examples/onnx/yolov5/ 이 변환을 사용할 수도 있지만 YOLO 모델은 일련의 training-export-conversion-test 패키지가 포함되어 있기 때문에 rknn_model_zoo 를 사용하여 변환하는 것이 가장 좋습니다.
  2. 추론 결과의 흐릿한 화면 문제는 시그모이드 함수에 의해 발생합니다. 모델 결과에 시그모이드 처리가 없고 귀하의 테스트 방법이 사용되기 때문에 위의 8단계를 확인하고 관련 기능을 제거할 수 있습니다.
  3. 모델 변환을 할 때 rknn-server를 시작해야 합니다.자세한 내용은 rknpu2/rknn_server_proxy를 참조하십시오.
  4. 카메라 데이터를 입력으로 비트맵 및 cv Mat로 직접 변환하려고 시도하지만 효과가 없고 실패합니다.

요약하다

모든 것을 시도하십시오 .

다른 AI 라이브러리.
TensorflowLite
Tencent TNN
Xiaomi Mace
Ali MNN
컴퓨터 비전 학습 비디오, Beijing University of Posts and Telecommunications의 Lu Peng이 가르치는
컴퓨터 비전 및 딥 러닝을 적극 권장합니다.

추천

출처blog.csdn.net/weixin_43141131/article/details/128407827