YOLOv7移植经验分享

news2025/1/22 19:50:08

目录

一、背景

二、环境

2.1 服务器环境

2.2 SDK环境

2.3 docker环境

三、移植开发

3.1 模型迁移

3.2 算法迁移

四、部署


一、背景

YOLOv7在 5 FPS 到 160 FPS 范围内的速度和准确度都超过了所有已知的目标检测器,并且在 GPU V100 上 30 FPS 或更高的所有已知实时目标检测器中,具有最高的准确度 56.8% AP。

YOLOv7-E6(56 FPS V100,55.9% AP)比基于Transformer的检测器 SWIN-L Cascade-Mask R-CNN(9.2 FPS A100,53.9% AP)的速度和准确度分别高出 509% 和 2%,并且比基于卷积的检测器 ConvNeXt-XL Cascade-Mask R-CNN (8.6 FPS A100, 55.2% AP) 速度提高 551%,准确率提高 0.7%,以及 YOLOv7 的表现还优于:YOLORYOLOXScaled-YOLOv4YOLOv5、 DETRDeformable DETRDINO-5scale-R50ViT-Adapter-B和许多其他速度和准确度的目标检测算法。此外,YOLOv7基于 MS COCO 数据集上从零开始训练 ,未使用任何其他数据集或预训练的权重。

为了更好的服务客户,这里基于该算法进行提前适配,方便后续客户使用时进行参考、指导。

官方仓库:https://github.com/WongKinYiu/yolov7
模型地址:https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7x.pt

二、环境

2.1 服务器环境

SDK复现需要借助一定的开发环境,这里基于公有服务器,通过ssh方式使用,步骤如下:

  1. 申请服务器账号
  1. 借助ssh工具,登录到服务器,MobaXterm、SecureCRT等软件          
  1. 下载必要的成果物:SDK最新包+docker镜像,可以采用wget命令:

# docker镜像
wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/22/03/19/13/bmnnsdk2-bm1684-ubuntu-docker-py37.zip
#SDK
wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/22/05/31/11/bmnnsdk2_bm1684_v2.7.0_20220531patched.zip

下载好的成果物如下:      

 

2.2 SDK环境

通过上述操作,我们已经下载了必备的成果物,这里先解压SDK整包,解压后,可以通过校验MD5码,防止文件被篡改,带来一些不必要的麻烦,命令如下:

(base) xxx@bitmain-SYS-4028GR-TR2:~$unzip bmnnsdk2_bm1684_v2.7.0_20220531patched.zip
Archive:  bmnnsdk2_bm1684_v2.7.0_20220531patched.zip
   creating: bmnnsdk2_bm1684_v2.7.0_20220531patched/
  inflating: bmnnsdk2_bm1684_v2.7.0_20220531patched/bmnnsdk2.MD5
  inflating: __MACOSX/bmnnsdk2_bm1684_v2.7.0_20220531patched/._bmnnsdk2.MD5
  inflating: bmnnsdk2_bm1684_v2.7.0_20220531patched/release_version.txt
  inflating: __MACOSX/bmnnsdk2_bm1684_v2.7.0_20220531patched/._release_version.txt
  inflating: bmnnsdk2_bm1684_v2.7.0_20220531patched/bmnnsdk2-bm1684_v2.7.0.tar.gz
  inflating: __MACOSX/bmnnsdk2_bm1684_v2.7.0_20220531patched/._bmnnsdk2-bm1684_v2.7.0.tar.gz
(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2_bm1684_v2.7.0_20220531patched$cat bmnnsdk2.MD5
6ae7d9b5a8564eb66f4f820319c2d39f  ./bmnnsdk2-bm1684_v2.7.0.tar.gz
bf2c860701575909e43b964011694c8f  ./release_version.txt
(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2_bm1684_v2.7.0_20220531patched$md5sum ./*
6ae7d9b5a8564eb66f4f820319c2d39f  ./bmnnsdk2-bm1684_v2.7.0.tar.gz
7719bf8cd5d5de8388ebcddda6f2c4be  ./bmnnsdk2.MD5
bf2c860701575909e43b964011694c8f  ./release_version.txt

继续解压缩SDK真正成果物,如下:

(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2_bm1684_v2.7.0_20220531patched$tar -zxvf bmnnsdk2-bm1684_v2.7.0.tar.gz
bmnnsdk2-bm1684_v2.7.0/
bmnnsdk2-bm1684_v2.7.0/release_version.txt
......

至此,SDK包的环境已经处理完毕。

 

2.3 docker环境

经过上述操作,我们已经进入到服务器环境,并且下载好了相关成果物。为了方便复现SDK,这里直接基于官方docker镜像,不再采用自搭docker。

docker采用ubuntu-docker-py37,首先需要解压该docker压缩包,解压缩后,可以通过校验MD5码,防止文件被篡改,带来一些不必要的麻烦,命令如下:

(base) xxx@bitmain-SYS-4028GR-TR2:~$unzip bmnnsdk2-bm1684-ubuntu-docker-py37.zip
Archive:  bmnnsdk2-bm1684-ubuntu-docker-py37.zip
   creating: bmnnsdk2-bm1684-ubuntu-docker-py37/
 extracting: bmnnsdk2-bm1684-ubuntu-docker-py37/bmnnsdk2-bm1684-ubuntu.docker
 extracting: bmnnsdk2-bm1684-ubuntu-docker-py37/bmnnsdk2.MD5
 extracting: bmnnsdk2-bm1684-ubuntu-docker-py37/Dockerfile.bm1684
 extracting: bmnnsdk2-bm1684-ubuntu-docker-py37/release_version.txt
(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2-bm1684-ubuntu-docker-py37$cat bmnnsdk2.MD5
cf91eb0ff60f28e368bba1c357d2e7e5  ./Dockerfile.bm1684
c181ce60245b4fe07596d8a360944903  ./release_version.txt
105a4d5d13a41d97353fd2dab88b4802  ./bmnnsdk2-bm1684-ubuntu.docker
(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2-bm1684-ubuntu-docker-py37$md5sum ./*
105a4d5d13a41d97353fd2dab88b4802  ./bmnnsdk2-bm1684-ubuntu.docker
7b1fdecee114e6d2d82c21286e9b1a39  ./bmnnsdk2.MD5
cf91eb0ff60f28e368bba1c357d2e7e5  ./Dockerfile.bm1684
c181ce60245b4fe07596d8a360944903  ./release_version.txt

之后通过加载docker镜像,将镜像仓库加载到服务器环境,命令如下:

#装载镜像
(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2-bm1684-ubuntu-docker-py37$docker load -i bmnnsdk2-bm1684-ubuntu.docker
Loaded image: bmnnsdk2-bm1684/dev:ubuntu16.04
#查看docker镜像列表
(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2-bm1684-ubuntu-docker-py37$docker images
......
bmnnsdk2-bm1684/dev  ubuntu16.04  d034e9bec3a7 3 months ago  4.6GB

参考官方说明,SDK包中有docker运行的脚本docker_run_bmnnsdk.sh,这里为了方便识别,对脚本做了一些修改:重命名container名称等,如下(可以根据自己需要增删):

if [ -c "/dev/bm-sophon0" ]; then
  for dev in $(ls /dev/bm-sophon*);
  do
    mount_options+="--device="$dev:$dev" "
  done
  CMD="docker run \
      --name ubuntu16.0-py37-wnb \
      --network=host \
      --workdir=/workspace \
      --privileged=true \
      ${mount_options} \
      --device=/dev/bmdev-ctl:/dev/bmdev-ctl \
      -v /dev/shm --tmpfs /dev/shm:exec \
      -v $WORKSPACE:/workspace \
      -v /dev:/dev \
      -v /etc/localtime:/etc/localtime \
      -e LOCAL_USER_ID=`id -u` \
      -it $REPO/$IMAGE:$TAG \
      bash
  "
else
  CMD="docker run \
      --name ubuntu16.0-py37-wnb \
      --network=host \
      --workdir=/workspace \
      --privileged=true \
      -v $WORKSPACE:/workspace \
      -v /dev/shm --tmpfs /dev/shm:exec \
      -v /etc/localtime:/etc/localtime \
      -e LOCAL_USER_ID=`id -u` \
      -it $REPO/$IMAGE:$TAG \
      bash
  "
fi

下面创建container,采用官方脚本,容器创建后,会默认进入,命令如下:

(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2_bm1684_v2.7.0_20220531patched/bmnnsdk2-bm1684_v2.7.0$./docker_run_bmnnsdk.sh
/mnt/sdb2/xxx/bmnnsdk2_bm1684_v2.7.0_20220531patched/bmnnsdk2-bm1684_v2.7.0
/mnt/sdb2/xxx/bmnnsdk2_bm1684_v2.7.0_20220531patched/bmnnsdk2-bm1684_v2.7.0
bmnnsdk2-bm1684/dev:ubuntu16.04
docker run --name ubuntu16.0-py37-wnb --network=host --workdir=/workspace --privileged=true --device=/dev/bm-sophon0:/dev/bm-sophon0 --device=/dev/bm-sophon1:/dev/bm-sophon1 --device=/dev/bm-sophon2:/dev/bm-sophon2 --device=/dev/bm-sophon3:/dev/bm-sophon3 --device=/dev/bm-sophon4:/dev/bm-sophon4 --device=/dev/bm-sophon5:/dev/bm-sophon5 --device=/dev/bm-sophon6:/dev/bm-sophon6 --device=/dev/bm-sophon7:/dev/bm-sophon7 --device=/dev/bm-sophon8:/dev/bm-sophon8 --device=/dev/bmdev-ctl:/dev/bmdev-ctl -v /dev/shm --tmpfs /dev/shm:exec -v /mnt/sdb2/xxx/bmnnsdk2_bm1684_v2.7.0_20220531patched/bmnnsdk2-bm1684_v2.7.0:/workspace -v /dev:/dev -v /etc/localtime:/etc/localtime -e LOCAL_USER_ID=1032 -it bmnnsdk2-bm1684/dev:ubuntu16.04 bash
root@bitmain-SYS-4028GR-TR2:/workspace#

注:上述方式运行的container,在退出后,container会自动退出,为了方便反复使用,可以通过如下命令进入:

(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2_bm1684_v2.7.0_20220531patched/bmnnsdk2-bm1684_v2.7.0$docker start ubuntu16.0-py37-wnb
ubuntu16.0-py37-wnb
(base) xxx@bitmain-SYS-4028GR-TR2:~/bmnnsdk2_bm1684_v2.7.0_20220531patched/bmnnsdk2-bm1684_v2.7.0$docker exec -it ubuntu16.0-py37-wnb bash
root@bitmain-SYS-4028GR-TR2:/workspace#

至此,基本环境就搭建完毕了。

三、移植开发

常规算法移植,基本上都需要以下几个阶段:

 具体各阶段需要做的事情如下:

  1. 评测选型:根据应用场景,确定使用的产品形态,敲定模型;
  2. 模型迁移:将原始深度学习框架下训练生成的模型转换为具体硬件平台支持的模型,涉及量化、自定义算子等;
  3. 算法移植:将模型的前后处理部分进行加速接口替换,一般硬件平台都会针对一些常见的图片处理接口进行加速,比如:图片缩放、色彩空间转换等。
  4. 程序移植:移植任务管理、资源调度等算法引擎代码及逻辑处理、结果展示、数据推送等业务代码,根据具体业务相关。
  5. 测试调优:网络性能与精度测试、压力测试,基于网络编译、量化工具、多卡多芯、任务流水线等方面的深度优化。
  6. 部署联调:将算法服务打包(如Docker)部署到BM168X硬件产品上,并在实际场景中与业务平台或集成平台进行功能联调;必要时在生产环境中调整参数配置并收集数据进一步优化模型。

本次移植已确定具体算法,并且不涉及复杂的业务逻辑,只需要关注【模型迁移】、【算法移植】、【测试调优】,下面会结合具体移植实操,进行展开讲解。

3.1 模型迁移

3.1.1 fp32bmodel生成

3.1.1.1 模型准备

由于官方原生模型默认采用Eager mode(用于构建原型、训练和实验),无法与python解耦,也就是需要依赖YOLOv7源码,无法直接进行模型转换,因此,需要先通过trace进行转换。这里基于官方项目进行:

  1. 拉取官方代码仓库,安装相关依赖
  1. 下载原生模型,当前官方仅提供了第一个版本v0.1
  1. 原生转换为torchscript模型,可以直接采用官方提供的export.py,命令如下:

(yolov7) root@bitmain-SYS-4028GR-TR2:yolov7# python m models/export.py --weights yolov7.pt 
......
Export complete (10.26s). Visualize with https://github.com/lutzroeder/netron.

目录结构
root@bitmain-SYS-4028GR-TR2:/workspace/code/yolov7# tree -L 1
.
|-- LICENSE.md
|-- ......
|-- yolov7.onnx             # 转换后模型
|-- yolov7.pt               # 原模型
`-- yolov7.torchscript.pt   # 转换后模型

3.1.1.2 模型转换

下面基于yolov7.torchscript.pt进行模型迁移,采用官方原生的docker环境,通过bmnetp工具实现模型转换,主要转换代码如下:

python3 -m bmnetp \
       --net_name=yolov7 \
       --target=${platform} \
       --opt=1 \
       --cmp=true \
       --shapes="[1,3,640,640]" \
       --model=${model_dir} \
       --outdir=${output_dir} \
       --dyn=false

执行完成后,会在指定目录生成yolov7_float32_1b.bmodel,该工具相关说明可以通过python3 -m bmnetp --help查看,也可以参考官方说明。

3.1.1.3 精度回归

精度回归(这里主要验证转换前后一致性,其他用法详见工具说明)需要依赖BM1684芯片(PICE或者SOC模式均可),并且在【模型转换】时配置了--cmp=true,模型转换完成后,在指定路径下不仅会生成bmodel,还会生成input_ref_data.datoutput_ref_data.dat

工具采用官方提供的bmrt_test,该工具用法比较简单,执行时会取input_ref_data.dat数据,在BM1684上进行推理,然后比较推理结果和output_ref_data.dat差异,浮点数据差异小于1e-2(可配)即通过:

bmrt_test --context_dir=模型转换指定路径

这里采用yolov7转换后的模型做演示,如下所示,当出现cmp success +++(未报错)意味着精度回归通过:

root@bitmain-SYS-4028GR-TR2:YOLOv7_object/model# bmrt_test --context_dir=./output/YOLOv7/
......
[BMRT][bmrt_test:1038] INFO:==>comparing #0 output ...
[BMRT][bmrt_test:1043] INFO:+++ The network[yolov7] stage[0] cmp success +++
[BMRT][bmrt_test:1063] INFO:load input time(s): 0.004891
[BMRT][bmrt_test:1064] INFO:calculate  time(s): 0.084028
[BMRT][bmrt_test:1065] INFO:get output time(s): 0.007568
[BMRT][bmrt_test:1066] INFO:compare    time(s): 0.027697

至此,fp32bmodel模型迁移完成

注:最准确的做法是使用官方验证集进行精度指标统计,这里不展开介绍,待后续放到YOLOv5量化调优 介绍

3.1.2 int8 bmodel

模型量化就是将训练好的深度神经网络的权值,激活值等从高精度转化成低精度的操作过程,例如将32位浮点数转化成8位整型数int8,同时我们期望转换后的模型准确率与转化前相近。

 

针对模型量化,算能目前支持int8量化,提供一整套Qantization-Tools用于支持模型量化。模型量化相较于fp32模型转换会复杂一些,流程图如下所示:

量化流程  

3.1.2.1 量化数据集准备

Quantization-tools作为Post-Training量化工具,对已经训练好的float32网络进行量化。此过程需要一定数量的真实数据用float32网络进行推理,推理过程中会统计每层的输入输出数据范围作为量化参考,关于数据集:

  1. 如果使用一键量化接口,对于常见的CV类推理任务,设置量化图片的路径和前处理会在一键量化的过程中生成lmdb,分步量化的时候可以直接使用;
  2. 如果简单的前处理设置不能满足需求或者对于非CV类的网络输入可能是各种shape,可以自己制作lmdb。

这里采用自己制作lmdb数据集的方式,基于coco128数据进行处理,参考官方前处理(需要保持一致),主要是等比例加框处理、归一化,将数据集处理成lmdb格式的文件,命令执行如下:

root@bitmain-SYS-4028GR-TR2:YOLOv7_object/data# python3 convert_imageset.py --imageset_rootfolder ./coco128/images/train2017/ --imageset_lmdbfolder ./ --image_size  640 --bgr2rgb True --gray False
remove original lmdb file /workspace/examples/YOLOv7_object/data/data.mdb
remove original lmdb file /workspace/examples/YOLOv7_object/data/data.mdb Ok!

reading image /workspace/examples/YOLOv7_object/data/coco128/images/train2017/000000000472.jpg
original shape: (226, 640, 3)
save test.jpg done
......

root@bitmain-SYS-4028GR-TR2:YOLOv7_object/data# tree -L 1
.
|-- coco128
|-- convert_imageset.py
|-- data.mdb                 #
制作好的数据集      
`-- download_coco128.sh

为了方便查看前处理图片是否正确,防止后期出问题排查成本,可以将加框处理后图片存出后,对比查看,如下可以看出前处理正确: 

左图原图,右图预处理后

3.1.2.2 fp32umodel生成

下面需要将基于不同框架的网络转换为float32 Umodel之后进行量化,此过程中可以指定【3.1.2.1】中准备好的数据作为推理输入。 此步骤使用到的工具为ufw.tools.*_to_umodel,部分转换脚本代码如下:

python3 -m ufw.tools.pt_to_umodel \
      -m ${model_dir} \
      -s '(1,3,640,640)' \
      -d ${output_dir} \
      -D ${cali_data} \
      --cmp

转换完成后,会在指定目录下生成对应成果物,如下:

root@bitmain-SYS-4028GR-TR2:YOLOv7_object/model# ./gen_fp32umodel.sh
......
Compiling succeeded.
####################################
Converting Process Done Sucessfully
####################################
fp32umodel done

#
转换成果物目录
../data/models/int8bmodel/
|-- io_info.dat
|-- yolov7.torchscript_bmnetp.fp32umodel          # umodel参数
`-- yolov7.torchscript_bmnetp_test_fp32.prototxt  # 模型文件

3.1.2.3 int8umodel生成

通过一定次数的推理统计和计算量化参数,将float32 Umodel转化为int8 Umodel。此步骤使用到的工具为calibration_use_pb二进制工具或者其python形式接口。该步骤是算法最关键,也是最耗时的一步,后面会专门讲解如何调优,这里就不过多展开阐述。

基于上述前面制作生成的lmdb数据集、fp32umode、prototxt等成果物,进行int8umodel转换,主要包含两部分:

  1. 对输入浮点网络进行图优化,这一步在【3.1.2.2】中已包含,也可以在此处做
  2. 对浮点网络进行量化,得到int8的网络及权重文件

这里我们只进行int8的量化,不进行图优化,迭代200次,部分代码如下,工具相关参数可以通过calibration_use_pb --help查看:

calibration_use_pb  quantize \
            -model ${output_dir}/yolov7.torchscript_bmnetp_test_fp32.prototxt \
            -weights ${output_dir}/yolov7.torchscript_bmnetp.fp32umodel \
            -iterations 1 \
            -save_test_proto \
            -graph_transform \
            -accuracy_opt \
            -conv_group \
            -per_channel

相关执行过程,详见如下部分操作记录:

root@bitmain-SYS-4028GR-TR2:YOLOv7_object/model# ./gen_int8umodel.sh
......
/usr/bin/dot
I0718 10:46:52.879577  6933 cali_core.cpp:1474] used time=0 hour:25 min:22 sec
I0718 10:46:52.879654  6933 cali_core.cpp:1476] int8 calibration done.
Congratulation! Everything is OK!

成果物目录结构
../data/models/int8bmodel/
|-- io_info.dat
|-- yolov7.torchscript_bmnetp.fp32umodel
|-- yolov7.torchscript_bmnetp.fp32umodel_optimized
|-- yolov7.torchscript_bmnetp.int8umodel                      # umodel成果物
|-- yolov7.torchscript_bmnetp_deploy_fp32_unique_top.prototxt
|-- yolov7.torchscript_bmnetp_deploy_int8_unique_top.prototxt # 对应的模型文件
|-- yolov7.torchscript_bmnetp_test_fp32.prototxt
|-- yolov7.torchscript_bmnetp_test_fp32.prototxt_optimized
|-- yolov7.torchscript_bmnetp_test_fp32_unique_top.prototxt
`-- yolov7.torchscript_bmnetp_test_int8_unique_top.prototxt

 

3.1.2.4 int8bmodel生成

量化完成后部署,与float32网络部署类似。使用bmnetu工具将int8 Umodel转换成最终能部署到BM1684相关设备上能运行的int8bmodel。

编译生成int8bmodel的部分代码如下,编译成功后,会在指定目录生成对应成果物:

bmnetu \
    -model ${output_dir}/yolov7.torchscript_bmnetp_deploy_int8_unique_top.prototxt \
    -weight ${output_dir}/yolov7.torchscript_bmnetp.int8umodel \
    -target ${platform} \
    -outdir ${output_dir} \
    -cmp true

相关执行过程,详见如下部分操作记录:

root@bitmain-SYS-4028GR-TR2:YOLOv7_object/model# ./gen_int8bmodel.sh
......
============================================================
*** Store bmodel of BMCompiler...
============================================================
BMLIB Send Quit Message
Congratulation! Everything is OK!

成果物目录结构
../data/models/int8bmodel/
|-- compilation.bmodel                # bmodel成果物
|-- input_ref_data.dat
|-- io_info.dat
|-- output_ref_data.dat
|-- yolov7.torchscript_bmnetp.fp32umodel
|-- yolov7.torchscript_bmnetp.fp32umodel_optimized
|-- yolov7.torchscript_bmnetp.int8umodel
|-- yolov7.torchscript_bmnetp_deploy_fp32_unique_top.prototxt
|-- yolov7.torchscript_bmnetp_deploy_int8_unique_top.prototxt
|-- yolov7.torchscript_bmnetp_test_fp32.prototxt
|-- yolov7.torchscript_bmnetp_test_fp32.prototxt_optimized
|-- yolov7.torchscript_bmnetp_test_fp32_unique_top.prototxt
|-- yolov7.torchscript_bmnetp_test_int8_unique_top.prototxt
`-- yolov7_int8_1b.bmodel

 

3.1.2.5 精度回归

此步骤可能与量化网络一起进行多轮,通过验证量化后网络是否满足精度或者速度要求,对量化参数进行调节,然后再次量化,达到预期目标。 此步骤使用到的工具为ufw test_fp32/ufw test_int8以及可视化工具,或者多数情况下需要用户自己开发精度测试程序验证精度,这里限于篇幅不做展开,后续会在YOLOv5量化调优 中详述。

3.2 算法迁移

算法迁移部分主要的工作是使用BM1684提供的软件接口,实现原来有caffe/pytorch等框架实现的前后处理、推理等代码,也即是适应具体平台提供的软件接口替换原有不再能够使用/性能效率低下的接口,以此达到迁移前的效果。

这里参考官方源码,实现了CPP/Python版本的算法,并且在Python版本中,分别基于opencv、bmcv实现了两个版本:

.
|-- README.md
|-- cpp
|   |-- Makefile.arm
|   |-- Makefile.pcie
|   |-- bmnn_utils.h
|   |-- main.cpp
|   |-- utils.hpp
|   |-- yolov7.cpp
|   `-- yolov7.hpp
|-- python
|   |-- utils
|   |-- yolov7_bmcv_3output.py
|   |-- yolov7_opencv_3output.py
|   `-- yolov7_pytorch.py
`-- tools
    |-- convert_imageset.py
    `-- evaluate_coco.py

 

下面,基于Python bmcv版本,做简单介绍,让大家对此有个简单认知,如下是前处理中的部分代码:

padded_img_bgr = self.bmcv.vpp_resize_padding(
            img, self.input_shape[2], self.input_shape[3], attr)

padded_img_rgb = sail.BMImage(self.handle, self.input_shape[2], self.input_shape[3],
                              sail.Format.FORMAT_RGB_PLANAR, padded_img_bgr.dtype())

self.bmcv.vpp_resize(padded_img_bgr, padded_img_rgb,
                     self.input_shape[2], self.input_shape[3])

该前处理主要实现了以下几个操作:

  1. letterbox:该步骤采用bmcv.vpp_resize_padding接口,替换掉原opencv中resizecopyMakeBorder
  1. BGR->RGB:该步骤采用bmcv.vpp_resize接口,替换掉原opencv中cvtColor

以点带面,其余涉及到的环节,比如:加载模型、模型推理等,如果不支持(一般都不支持),均需要进行相关接口替换。

四、部署

该步一般需要结合特定业务进行算法封装、部署、测试等,如下是采用量化后模型推理后的可视化结果:

左图官方,右图量化

基于coco2017val测试集,mAP@0.5相较于官方仅下降3.9个百分点:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python基于OCR深度学习实现商品配料表识别

1、概述 当前人民和国家对食品安全十分重视,但商家为了保证食品长时间储存,味道鲜美,在食品中添加超量或对人有严重危害得食品添加剂,严重危害到人民的安全,我们以方便面为例,一包方便面最多可有25种食品添…

十年开发老手,深度解析企业用人标准为何越来越高?!

涛哥作为一个10多年的开发老手,经历过很多场面试,也面试过很多人,这么多年下来,切身体会到企业的用人标准越来越高,企业对开发工程师的要求也越来越"过分"。所以涛哥今天就借此机会,我们一起来分…

如何制定有效的项目计划,提高团队执行力

项目风险来源有很多,项目日程紧张,导致质量下降风险上升;甲方变更,管理者对变动控制不足;项目太大。 虽然从来不可能完全消除项目风险,但可以将危害减到最小。 一、确认项目计划 项目计划是一个项目启动…

SpringBoot读取properties中配置的List集合

实体类 Data NoArgsConstructor AllArgsConstructor Accessors(chain true) public class Person {private String name;private String age;private String content; } Component//将该类交由Spring管理 ConfigurationProperties(prefix "project") //自定义.pro…

【附源码】计算机毕业设计JAVA演唱会购票系统

【附源码】计算机毕业设计JAVA演唱会购票系统 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JAVA myba…

听我一句劝好吗?放下那些老掉牙的性能优化笔记吧!又不是没有新的,跟不上时代的学了也没法直接用呀!

性能概述 公司投入人力物力成本开发出的程序,如果出现程序瘫痪、界面停顿、抖动、响应迟缓等问题,会大大降低用户体验,损失大量用户。对于上述问题,都是需要性能调优来解决的问题。 程序性能主要表现在代码的执行速度、软件系统…

数据结构之快速排序(重点)

快速排序 算法所需 一个基准点 左边是比其小的数,右边是比其大的数 先使所指的元素作为基准元素low 用一个piviot存储49 然后进行比遍历操作 就是high向左移动(high–),到第一个比piviot小的元素进行一个data[low]data[high] 然后进行low,找…

基于最低水平面的三维装箱问题的启发式算法

⭐️ 前言 小编之前写过一篇博文:求解三维装箱问题的启发式深度优先搜索算法(python),详述了基于空间选择的三维装箱算法。本文考虑了一个事实:在某些情况下,我们在摆放物品时,总是优先选择较低的平面,基于…

LIN通讯

LIN通讯 一、LIN通讯的背景与意义 随着汽车电子的发展,汽车上的电子零件正在逐渐地增加。而电子零件的增加也导致更多的设备(传感器、执行器、电子控制器)需要加入汽车的局部网络,这些零件的增加还会带来配线的增加,…

java-springboot基于机器学习得心脏病预测系统 的设计与实现-计算机毕业设计

项目介绍 基于机器学习得心脏病预测系统通过对机器学习心脏病数据大数据分析统计系统的建设以实现机器学习心脏病数据分析统计功能。通过对心脏疾病变化市场的充分研究,结合自身技术储备情况,设计并开发了一套基于SpringBoot后台框架、Mybaits数据库映射…

web课程设计网页规划与设计---公司网站(5页 带下拉菜单)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材,DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 公司官网网站 | 企业官网 | 酒店官网 | 等网站的设计与制 | HTML期末大学生网页设计作业,Web大学生网页 HTML:结构 CSS&#…

动态规划算法学习二:最长公共子序列

文章目录前言一、问题描述二、DP实现1、最优子结构性质*****2、状态表示*****3、状态递归方程*****4、计算最优值*****5、代码实现:输出最长公共子序列6、代码实现:输出最优解前言 一、问题描述 列举X的所有子序列,然后检查它是否也是Y的子序…

Java设计模式很难吗,这篇带你熟悉设计模式

3.1 概述 可以发现,设计模式好像都是类似的。越看越感觉都着不多。其实都是类似面向接口编程的一种体现,只不过侧重点不一样或者说要体现的结果不一样。 3.2 使用场景 问题一:应对可能变化的对象实现 方案:间接创建 模式&…

pycharm远程连接服务器

遇到的问题: 在服务器上配环境 流程: 先安装anaconda(去其官网下载个脚本文件到服务器上,然后启动脚本即可) bash Anaconda3-5.3.1-Linux-x86_64.sh然后创建 python环境 conda create -n pytorch python3.10去pyt…

【Linux】搞懂进程地址空间

文章目录1、从程序地址空间开始1.1 在C/C中看到的地址实际是?1.2 感性理解虚拟地址空间2、进程地址空间2.1 进程地址空间是怎样被描述的?2.2 进程地址空间和内存的关系2.3 为什么需要进程地址空间?1、从程序地址空间开始 1.1 在C/C中看到的地…

并发:线程状态

java的线程状态分为六种 新建 NEW 当一个线程对象被创建,但是还没有调用start方法时处于新建状态 此时未与操作系统底层线程关联 可运行 RUNNABLE 调用了start方法,就会由新建进入可运行状态 此时与底层线程关联,由操作系统调度执行 &…

python就是学不会怎么办?

编程从来都不是只看,只照葫芦画瓢就能学会的学科要想学会,必须是要有你个人是思考的,学会掌握编程逻辑,在学的过程中想为什么这么写,应该怎么去实现这个功能,拆分为几步不断的实操练习才能让你真的掌握知识…

并发,并行,串行,同步,异步,进程,进程池,线程,线程池

并发,并行,串行,同步,异步,进程,进程池,线程,线程池 进程 什么是进程: 开发写的代码称之为程序,将程序运行起来,就是进程 进程是申请一块内存空…

vue中动态引入图片为什么要是require, 你不知道的那些事

相信用过vue的小伙伴,肯定被面试官问过这样一个问题:在vue中动态的引入图片为什么要使用require 有些小伙伴,可能会轻蔑一笑:呵,就这,因为动态添加src被当做静态资源处理了,没有进行编译,所以要加上require, 我倒着都能背出来… emmm… 乍一看好像说的很有道理啊,但…

Linux实现文件定期本地备份/异地备份/删除备份的脚本

一.背景 1.总会出出现环境上的数据丢失,在没有备份的情况下会非常的被动,不管是由于病毒还是人为的原因造成的程序、数据被删除,有时候后悔已经来不及,不如提前做到数据的备份,而异地备份也更加的保险一点。 2.数据备…