当前位置:   article > 正文

RK3588部署自写手写数字识别模型_rk3588 mnist

rk3588 mnist

大致流程-------------------------------------------------------------------------------------------------------

首先搭建好rknn_toolkit环境

-->

转化为rknn模型---------------------------------------------------------------------------------

1:进入docker

sudo docker run -t -i --privileged -v /dev/bus/usb:/dev/bus/usb \

 -v /home/warren/RK_NPU_SDK_1.3.0/rknn-toolkit2-1.3.0/examples:/rknn_toolkit \

 rknn-toolkit2:1.3.0-cp36 /bin/bash

3:复制一个resnet50v2并命名为MNIST

4:准备好如下文件

5:test.py

  1. import os
  2. import urllib
  3. import traceback
  4. import time
  5. import sys
  6. import numpy as np
  7. import cv2
  8. from rknn.api import RKNN
  9. ONNX_MODEL = 'model.onnx'
  10. RKNN_MODEL = 'model.rknn'
  11. if __name__ == '__main__':
  12.     # Create RKNN object
  13.     rknn = RKNN()
  14.     # pre-process config
  15.     print('--> Config model')
  16.     rknn.config(target_platform='rk3588')
  17.     print('done')
  18.     # Load ONNX model
  19.     print('--> Loading model')
  20.     ret = rknn.load_onnx(model=ONNX_MODEL)
  21.     if ret != 0:
  22.         print('Load model failed!')
  23.         exit(ret)
  24.     print('done')
  25.     # Build model
  26.     print('--> Building model')
  27.     ret = rknn.build(do_quantization=False)
  28.     if ret != 0:
  29.         print('Build model failed!')
  30.         exit(ret)
  31.     print('done')
  32.     # Export RKNN model
  33.     print('--> Export RKNN model')
  34.     ret = rknn.export_rknn(RKNN_MODEL)
  35.     if ret != 0:
  36.         print('Export resnet50v2.rknn failed!')
  37.         exit(ret)
  38.     print('done')
  39.     # Set inputs
  40.     with open("./data/MNIST/raw/train-images-idx3-ubyte","rb") as f:
  41.         file=f.read()
  42.         num=100
  43.         i = 16+784*num
  44.         image1 = [int(str(item).encode('ascii'),16) for item in file[i:i+784]]
  45.         input_data = np.array(image1,dtype=np.float32).reshape(1,28,28,1)
  46.     #save the image
  47.     image1_np = np.array(image1,dtype=np.uint8).reshape(28,28,1)
  48.     file_name = "test.jpg"
  49.     cv2.imwrite(file_name,image1_np)
  50.     # init runtime environment
  51.     print('--> Init runtime environment')
  52.     ret = rknn.init_runtime()
  53.     if ret != 0:
  54.         print('Init runtime environment failed')
  55.         exit(ret)
  56.     print('done')
  57.     # Inference
  58.     print('--> Running model')
  59.     outputs = rknn.inference(inputs=input_data)
  60.     x = outputs[0]
  61.     output = np.exp(x)/np.sum(np.exp(x))
  62.     outputs = np.argmax([output])
  63.     print("----------outputs----------",outputs)
  64.     print('done')
  65.     rknn.release()

6:生成后目录结构

RKNPU板端--------------------------------------------------------------------------------------------

目录结构

build-linux_RK3588.sh

  1. #!/bin/bash
  2. set -e
  3. TARGET_SOC="rk3588"
  4. export TOOL_CHAIN=/home/warren/Downloads/gcc-buildroot-9.3.0-2020.03-x86_64_aarch64-rockchip-linux-gnu
  5. # for aarch64
  6. GCC_COMPILER=/home/warren/Downloads/gcc-buildroot-9.3.0-2020.03-x86_64_aarch64-rockchip-linux-gnu/bin/aarch64-rockchip-linux-gnu
  7. export LD_LIBRARY_PATH=${TOOL_CHAIN}/lib64:$LD_LIBRARY_PATH
  8. export CC=${GCC_COMPILER}-gcc
  9. export CXX=${GCC_COMPILER}-g++
  10. ROOT_PWD=$( cd "$( dirname $0 )" && cd -P "$( dirname "$SOURCE" )" && pwd )
  11. # build
  12. BUILD_DIR=${ROOT_PWD}/build/build_linux_aarch64
  13. if [[ ! -d "${BUILD_DIR}" ]]; then
  14.   mkdir -p ${BUILD_DIR}
  15. fi
  16. cd ${BUILD_DIR}
  17. cmake ../.. \
  18.     -DTARGET_SOC=${TARGET_SOC} \
  19.     -DCMAKE_C_COMPILER=${GCC_COMPILER}-gcc \
  20.     -DCMAKE_CXX_COMPILER=${GCC_COMPILER}-g++
  21. make -j4
  22. make install
  23. cd -

main.cc

  1. /*-------------------------------------------
  2.                 Includes
  3. -------------------------------------------*/
  4. #include <stdio.h>
  5. #include <stdint.h>
  6. #include <stdlib.h>
  7. #include <fstream>
  8. #include <iostream>
  9. #include <sys/time.h>
  10. #include "opencv2/core/core.hpp"
  11. #include "opencv2/imgproc.hpp"
  12. #include "opencv2/imgcodecs.hpp"
  13. #include "rknn_api.h"
  14. using namespace std;
  15. using namespace cv;
  16. const int MODEL_IN_WIDTH = 28;
  17. const int MODEL_IN_HEIGHT = 28;
  18. const int MODEL_CHANNEL = 1;
  19. int ret=0;
  20. int loop_count=8000;
  21. /*-------------------------------------------
  22.                   Functions
  23. -------------------------------------------*/
  24. static inline int64_t getCurrentTimeUs()
  25. {
  26.     struct timeval tv;
  27.     gettimeofday(&tv, NULL);
  28.     return tv.tv_sec * 1000000 + tv.tv_usec;
  29. }
  30. static void dump_tensor_attr(rknn_tensor_attr* attr)  //dump tensor message
  31. {
  32.   printf("  index=%d, name=%s, n_dims=%d, dims=[%d, %d, %d, %d], n_elems=%d, size=%d, fmt=%s, type=%s, qnt_type=%s, "
  33.          "zp=%d, scale=%f\n",
  34.          attr->index, attr->name, attr->n_dims, attr->dims[0], attr->dims[1], attr->dims[2], attr->dims[3],
  35.          attr->n_elems, attr->size, get_format_string(attr->fmt), get_type_string(attr->type),
  36.          get_qnt_type_string(attr->qnt_type), attr->zp, attr->scale);
  37. }
  38. static unsigned char *load_model(const char *filename, int *model_size) //load model
  39. {
  40.     FILE *fp = fopen(filename, "rb");
  41.     if(fp == nullptr) {
  42.         printf("fopen %s fail!\n", filename);
  43.         return NULL;
  44.     }
  45.     fseek(fp, 0, SEEK_END);
  46.     int model_len = ftell(fp);
  47.     unsigned char *model = (unsigned char*)malloc(model_len);
  48.     fseek(fp, 0, SEEK_SET);
  49.     if(model_len != fread(model, 1, model_len, fp)) {
  50.         printf("fread %s fail!\n", filename);
  51.         free(model);
  52.         return NULL;
  53.     }
  54.     *model_size = model_len;
  55.     if(fp) {
  56.         fclose(fp);
  57.     }
  58.     return model;
  59. }
  60. void Bubble_sort(float *buffer)
  61. {
  62.     float temp=0;
  63.     for(int i = 0; i < 10; i++){
  64.         for(int j=0;j<10-i-1;j++){
  65.             if(buffer[j]>buffer[j+1]){
  66.                 temp=buffer[j];
  67.                 buffer[j]=buffer[j+1];
  68.                 buffer[j+1]=temp;
  69.             }
  70.         }
  71.     }
  72. }
  73. void Load_data(int num,unsigned char * input_image)
  74. {
  75.     int j=16+784*num;
  76.     FILE *file = fopen("./model/data/MNIST/raw/train-images-idx3-ubyte", "rb");
  77.     if (file == NULL) {
  78.         printf("can't open the file!\n");
  79.     }
  80.     fseek(file,j,SEEK_SET);
  81.     fread(input_image,sizeof(char),784,file);
  82. /*      for(int i=0;i<MODEL_IN_WIDTH;i++){
  83.         for(int j=0;j<MODEL_IN_WIDTH;j++){
  84.             printf("%4d",input_image[i*28+j]);
  85.         }
  86.         printf("\n");
  87.     }  */
  88.     fclose(file);
  89. }
  90. void Array_change(float input_aray[1][MODEL_IN_WIDTH][MODEL_IN_HEIGHT][MODEL_CHANNEL],unsigned char *input_image)
  91. {
  92.    int index=0;
  93.     for (int i = 0; i < 1; i++) {
  94.         for (int j = 0; j < MODEL_IN_WIDTH; j++) {
  95.             for (int k = 0; k < MODEL_IN_HEIGHT; k++) {
  96.                 for (int l = 0; l < MODEL_CHANNEL; l++) {
  97.                     input_aray[i][j][k][l] = (float)input_image[index++];
  98.                     if(input_aray[i][j][k][l]==0){
  99.                     }
  100.                 }
  101.             }
  102.         }
  103.     }
  104. }
  105. void print_Array(int num,float *buffer)
  106. {
  107.     for(int i =0;i<num;i++){
  108.         printf("%f\n",buffer[i]);
  109.     }
  110. }
  111. void get_tensor_message(rknn_context ctx,rknn_tensor_attr *attrs,uint32_t num,int io)
  112. {
  113.     for (int i = 0; i < num; i++) {
  114.         attrs[i].index = i;
  115.         if(io==1){
  116.         ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(attrs[i]), sizeof(rknn_tensor_attr));
  117.         }
  118.         else{
  119.             ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(attrs[i]), sizeof(rknn_tensor_attr));
  120.         }
  121.         if (ret != RKNN_SUCC) {
  122.             printf("rknn_query fail! ret=%d\n", ret);
  123.         }
  124.         dump_tensor_attr(&(attrs[i]));
  125.     }
  126. }
  127. /*-------------------------------------------
  128.                   Main Function
  129. -------------------------------------------*/
  130. int main(int argc, char** argv)
  131. {
  132.     int64_t time_sum[loop_count]={};
  133.     int64_t sum=0;
  134.     int num =-1;
  135.        
  136.     rknn_context ctx;
  137.     int model_len = 0;
  138.     unsigned char *model;
  139.     rknn_output outputs[1];
  140.     rknn_input inputs[1];
  141.     const char *model_path = argv[1];
  142.     if (argc != 2)
  143.     {
  144.         printf("Usage: %s <rknn model>  \n", argv[0]);
  145.         return -1;
  146.     }
  147.     // Load RKNN Model
  148.     printf("-------------load rknn model\n");
  149.     model = load_model(model_path, &model_len);
  150.     ret = rknn_init(&ctx, model, model_len, RKNN_FLAG_COLLECT_PERF_MASK, NULL);
  151.     //ret = rknn_init(&ctx, model, model_len, 0, NULL);
  152.     if(ret < 0) {
  153.         printf("rknn_init fail! ret=%d\n", ret);
  154.         return -1;
  155.     }
  156.     printf("--------------done\n");
  157.     // Get Model Input and Output Info
  158.     rknn_input_output_num io_num;
  159.     ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
  160.     if (ret != RKNN_SUCC) {
  161.         printf("rknn_query fail! ret=%d\n", ret);
  162.         return -1;
  163.     }
  164.     printf("model input num: %d, output num: %d\n", io_num.n_input, io_num.n_output);
  165.     //get input tensor message
  166.     printf("input tensors:\n");
  167.     rknn_tensor_attr input_attrs[io_num.n_input];
  168.     memset(input_attrs, 0, sizeof(input_attrs));
  169.     get_tensor_message(ctx,input_attrs,io_num.n_input,1);
  170.    
  171.     //get output tensor message
  172.     printf("output tensors:\n");
  173.     rknn_tensor_attr output_attrs[io_num.n_output];
  174.     memset(output_attrs, 0, sizeof(output_attrs));
  175.     get_tensor_message(ctx,output_attrs,io_num.n_output,0);
  176.     for(int i=0;i<loop_count;i++){
  177.         num++;
  178.         printf("-------------------------------------loop %d \n",i);
  179.         //load data
  180.         unsigned char input_image[784]={};
  181.         float input_aray[1][MODEL_IN_WIDTH][MODEL_IN_HEIGHT][MODEL_CHANNEL]={};
  182.         Load_data(num,input_image);
  183.         Array_change(input_aray,input_image);
  184.         // Set Input Data
  185.         memset(inputs, 0, sizeof(inputs));
  186.         inputs[0].index = 0;
  187.         inputs[0].type = RKNN_TENSOR_FLOAT32;
  188.         inputs[0].size = 28*28*4;
  189.         inputs[0].fmt = RKNN_TENSOR_NHWC;
  190.         inputs[0].buf = input_aray;
  191.         ret = rknn_inputs_set(ctx, 1, inputs);
  192.         if(ret < 0) {
  193.             printf("rknn_input_set fail! ret=%d\n", ret);
  194.             return -1;
  195.         }
  196.         // Run
  197.         printf("--------------rknn_run\n");
  198.         int64_t start_us = getCurrentTimeUs();
  199.         ret = rknn_run(ctx, nullptr);
  200.         if(ret < 0) {
  201.             printf("rknn_run fail! ret=%d\n", ret);
  202.             return -1;
  203.         }
  204.         time_sum[i] = getCurrentTimeUs() - start_us;
  205.         sum = sum+time_sum[i];
  206.         printf(": Elapse Time = %.2fms sum %.2f \n", time_sum[i] / 1000.f,sum / 1000.f);
  207. /*         _rknn_perf_detail perf_run_detail;
  208.         ret = rknn_query(ctx, RKNN_QUERY_PERF_DETAIL, &perf_run_detail, sizeof(perf_run_detail));
  209.         printf("---------the detail of time is %s %d\n",perf_run_detail.perf_data,perf_run_detail.data_len);
  210.         rknn_perf_run perf_run;
  211.         ret = rknn_query(ctx, RKNN_QUERY_PERF_RUN, &perf_run, sizeof(perf_run));
  212.         printf("---------the sum of time is %d us\n",perf_run.run_duration);  */
  213.         // Get Output
  214.         memset(outputs, 0, sizeof(outputs));
  215.         outputs[0].want_float = 1;
  216.         ret = rknn_outputs_get(ctx, 1, outputs, NULL);
  217.         if(ret < 0) {
  218.             printf("rknn_outputs_get fail! ret=%d\n", ret);
  219.             return -1;
  220.         }
  221.         // Post Process
  222.         float *buffer = (float *)outputs[0].buf;
  223.         float buffer_copy[]={};
  224.         for(int i=0;i<10;i++){
  225.             buffer_copy[i]=buffer[i];      
  226.         }
  227.         Bubble_sort(buffer);
  228.         for(int i =0;i<10;i++){
  229.             if(buffer_copy[i]==buffer[9]){
  230.                 printf("----------the pic value is %d \n",i);
  231.             }
  232.         }
  233.        
  234.     }
  235.     // Release rknn_outputs
  236.     ret=rknn_outputs_release(ctx, 1, outputs);
  237.     if(ret < 0) {
  238.         printf("rknn_outputs_release fail! ret=%d\n", ret);
  239.         return -1;
  240.     }
  241.     printf("--------- loop time : %d average time is %.2f ms\n",loop_count,(sum / 1000.f)/loop_count);
  242.     // Release
  243.     if(ctx >= 0) {
  244.         rknn_destroy(ctx);
  245.     }
  246.     if(model) {
  247.         free(model);
  248.     }
  249.      
  250.     return 0;
  251. }

结果打印

 

sudo cat /sys/kernel/debug/rknpu/load 查看npu利用率

uint8

fp16

  

  

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/854451
推荐阅读
相关标签
  

闽ICP备14008679号