NVIDIA Jetson Nano使用Tensor RT加速YOLOv4神经网络推理

2021-06-01 11:02:32 浏览数 (1)

本文转载自:

注意手机浏览代码看不全,可以左右滑动代码哟!

1

如何使用YOLOv4

首先要先建置darknet的环境,先下载darknet的github:

代码语言:javascript复制
$ git clone https://github.com/AlexeyAB/darknet.git
$ cd darknet

接着需要修改一下Makefile,在官方的github当中有提到Jetson TX1/TX2的修改方法,Jetson Nano也是比照办理,前面的参数设定完了,往下搜寻到ARCH的部分,需要将其修改成compute_53:

代码语言:javascript复制
GPU=1
CUDNN=1
CUDNN_HALF=1
OPENCV=1
AVX=0
OPENMP=1
LIBSO=1
ZED_CAMERA=0
ZED_CAMERA_v2_8=0

......

USE_CPP=0
DEBUG=0

ARCH= -gencode arch=compute_53,code=[sm_53,compute_53]

接着就可以进行build的动作了:

代码语言:javascript复制
$ make

如果Build darknet的时候出现找不到nvcc的问题,如下图:

可以在Makefile当中的NVCC后面新增绝对位置:

接着重新make一次如果没有错误讯息就代表Build好了!

2

使用YOLOv4进行推理

我们需要先下载YOLOv4的权重来用

代码语言:javascript复制
wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights 
       -q --show-progress --no-clobber

基本的推理方法有三种:图片、视频、摄影头 ( 实时影像 ),我们一一来介绍使用方法!主要执行除了darknet的执行档之外还需要给予模式、数据集、配置文件:

代码语言:javascript复制
./darknet detector test ./cfg/coco.data ./cfg/yolov4.cfg ./yolov4.weights

可以使用 --help来帮助查看:

代码语言:javascript复制
./darknet detector --help

如果要开启图片的话需使用 test模式,他会在执行之后要你输入图片的位置,不过这边要注意的是按任意建离开后,图片不会帮你储存:

代码语言:javascript复制
./darknet detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -thresh 0.25

如果想要指定图片并且将结果储存下来则可以增加 -ext_output 的选项,执行完会储存成 prediction.jpg,这边我用另一张图片当示范 ( Ximending.jfif):

代码语言:javascript复制
./darknet detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -ext_output Taiwan.jfif

如果要使用影片或摄影机的话则是透过 demo 的指令来操作,这边如果用 -ext_output会直接覆盖掉原本的,我希望可以另存成别的档案则需要用到-output_filename来执行:

代码语言:javascript复制
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights sample.mp4 -out_filename sample_.mp4

使用摄影机进行影像实时辨识需要在后面参数导入 -c:

代码语言:javascript复制
$ ./darknet detector demo cfg/coco.data 
                          cfg/yolov4.cfg 
                          yolov4.weights 
                          -c 0

可以看到FPS大概会在0.8左右 ( 于终端机画面上 ),有明显的延迟感,但是辨识的结果还算可以。

3

修改输入維度大小

我们也可以直接修改输入输出的图片大小,我用简单一点的语法来操作,复制一个yolov4.cfg并命名为yolov4-416.cfg,并直接用nano去修改输入大小成416,这边使用&&的意思是让前一个指令完成之后再接续下一个指令:

代码语言:javascript复制
$ cp cfg/yolov4.cfg cfg/yolov4-416.cfg && nano cfg/yolov4-416.cfg

在下方的图片可以看到,缩小图片之后FPS就直接提高了许多,从0.8升到了1.5;注意!这个示范只是提供了可以修改输入大小的方法,因为有时候你用的图片或影片大小不同就需要稍微修改一下;官方较推荐的大小是608以上,缩小图片可能会导致辨识结果变差:

4

使用结构更小的YOLO ( Yolov4-Tiny )

下一种加快速度的方法是使用yolov4-tiny.weights,一个更小型的yolov4,这边的小型指的是神经网络模型的结构,一般我们都会使用在运算能力相较于显示适配器低的装置上 ( 例如 : 边缘装置 ),实作的部分,我们先将该权重下载下来:

代码语言:javascript复制
$ wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights

接着使用摄影头来开启,注意这边的config (cfg) 档案需要更改成 yolov4-tiny.cfg,因为yolov4跟yolov4-tiny的架构有所不同,config档案当中所提供的就是神经网络的结构:

代码语言:javascript复制
$ ./darknet detector demo cfg/coco.data 
                          cfg/yolov4-tiny.cfg 
                          yolov4-tiny.weights 
                          -c 0

可以看到FPS已经来到了14,延迟感明显降低许多:

5

使用TensorRT引擎加速

接下来是TensorRT的版本,稍微简短介绍一下Tensor RT (以下简称 TRT ),它是一个加速引擎可以运用在有CUDA核心的NVIDIA显示适配器当中,如果要使用TRT引擎加速需要先将神经网络模型转换成ONNX的格式才行。

下载、安装环境

坊间利用Yolov4做了很多应用,而转换这块也已经有人完成了,所以我们直接使用网络上提供的Github来实现即可:

代码语言:javascript复制
$ git clone https://github.com/jkjung-avt/tensorrt_demos.git

下载下来之后可以直接到ssd文件夹中执行install_pycuda.sh:

代码语言:javascript复制
$ cd ${HOME}/project/tensorrt_demos/ssd
$ ./install_pycuda.sh

如果显示nvcc not found的话则需要手动修改 install_pycuda的档案,我们需要将cuda的绝对位置存放到环境变量当中:

透过nano编辑器开启并且将iffi中间的内容修改如下,原本的内容记得要批注掉:

代码语言:javascript复制
$ nano ./install_pycuda.sh

安装完之后应该会显示 finished processing dependencies,也可以使用pip3 list去查看pycuda是否有安装成功:

接着需要安装onnx,一开始先安装相依套件,接着在安装onnx 1.4.1版本:

代码语言:javascript复制
$ sudo apt-get install protobuf-compiler libprotoc-dev
$ sudo pip3 install onnx==1.4.1

都完成之后我们需要先将相关的程序build起来:

代码语言:javascript复制
$ cd ${HOME}/project/tensorrt_demos/plugins
$ make

可以注意到又有nvcc的问题了,这时候一样需要修改Makefile来解决,将原本的NVCC=nvcc修改成NVCC=/usr/local/cuda/bin/nvcc即可:

6

下载并转换yolo模型

接着需要下载模型的权重,你将会看到它下载了yolo3跟yolo4的三种不同版本,并且直接放在当前文件夹当中,这边可以注意到下载的模型与刚刚的YOLOv4相同,所以其实也是可以直接用复制的方式或是直接写绝对位置进行转换:

代码语言:javascript复制
$ cd ${HOME}/project/tensorrt_demos/yolo
$ ./download_yolo.sh

最后可以执行 yolo_to_onnx.py 将yolo的权重档转换成onnx档案,接着再编译成TRT可用的模型,在onnx_to_tensorrt.py我会建议使用 -v 来看到进度,不然看着画面没动静会有点紧张:

代码语言:javascript复制
$ python3 yolo_to_onnx.py -m yolov4-416
$ python3 onnx_to_tensorrt.py -m yolov4-416 -v

转换ONNX大约耗费15分钟,会储存成yolov4-416.onnx,接着转换TRT大概也是差不多的时间,最后会储存成yolov4-416.trt。

7

使用TRT运行YOLOv4-416

这边我们使用 --usb 代表使用USB摄影机, --model则是选择特定模型:

代码语言:javascript复制
$ cd ${HOME}/project/tensorrt_demos
$ python3 trt_yolo.py --usb 0 --model yolov4-416

左上角有显示FPS数值,实测下来大约都会在 4.2~4.5之间,我们这次使用的是416维度,相较没有使用TensorRT引擎的Darknet ( FPS 1.5),快了将近3倍。

刚刚输入的部分使用usb摄影机,而作者很贴心地都写得很完善了,在utils/camera.py的部分可以看到输入的内容选项,也可以直接使用 --help来查看:

这里有提供图片( --image )、视频 ( --video )、重复视频 ( --video_lopping )、网络摄影机 ( --usb ) 等都可以使用。

使用TRT运行YOLOv4-Tiny-416

接下来为了追求更快的速度,我们当然要来实测一下tiny版本的:

代码语言:javascript复制
$ python3 yolo_to_onnx.py -m yolov4-tiny-416
$ python3 onnx_to_tensorrt.py -m yolov4-tiny -416 -v
$ cd ${HOME}/project/tensorrt_demos
$ python3 trt_yolo.py --usb 0 --model yolov4-tiny-416

使用tiny的话FPS来到18.05,基本上已经有不错的效果了!不过因为是tiny所以辨识的成效没有预期中的好:

0 人点赞