嘿!您似乎在 United States,您想使用我们的 English 网站吗?
Switch to English site
Skip to main content

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

作者

张嘉钧

难度

普通

YOLOv4

0144_fda73a2fb60254b286683e060219e88238d3fb4c.png

这边我们就不会对YOLOv4的技术进行介绍,大致上可以了解YOLOv4是由很多强大的技巧所组成,是现阶段教育界、商业都很常用到的一个技术。如果一一描述需要两篇的文章,而网络上很多介绍很详细的文章,大家可以直接去搜寻、查看;本篇着重在Github实作以及介绍TensorRT加速的方法给大家。

如何使用YOLOv4

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

$ git clone https://github.com/AlexeyAB/darknet.git
$ cd darknet

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

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的动作了:

$ make

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

0234_a6027e8357211e280e44fe8c5c3e220878cb51d2.png

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

0339_f4dc7303e9980c7faa1a4c50aae8891d91460c7e.png

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

使用YOLOv4进行推论

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

wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights \
       -q --show-progress --no-clobber

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

./darknet detector test ./cfg/coco.data ./cfg/yolov4.cfg ./yolov4.weights

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

0440_cb49da1e873ab3196254bcf6eb4ec0fe9c17d16d.png

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

./darknet detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -thresh 0.25

0537_974f8da339df8cb239f86c45c2a98b262093ab20.png

06-11_508e61733524785b31f7c9aea4b0da9430a846c9.png

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

./darknet detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -ext_output Taiwan.jfif

0739_d70f3001909b84891635fc4b5d7e73d5b255691e.png

0826_3a11dd47b79e5b9c760c0de448f098bff39c7a16.jpg

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

./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights sample.mp4 -out_filename sample_.mp4

0927_3a8ebf0d084598d0ef90a9eebaab579bb8a2883b.jpg

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

$ ./darknet detector demo cfg/coco.data \
                          cfg/yolov4.cfg \
                          yolov4.weights \
                          -c 0

1158_d172442e2e757248ee4708881d6ac7cf0ac58c65.jpg

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

修改输入维度大小

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

$ cp cfg/yolov4.cfg cfg/yolov4-416.cfg && nano cfg/yolov4-416.cfg

1252_8038bb0530576a7badf584878f708d435d8e849e.png

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

1347_ed6388bd2904cf514d2f06bd584e4c4f4dfa5c43.jpg

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

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

$ wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights

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

$ ./darknet detector demo cfg/coco.data \
                          cfg/yolov4-tiny.cfg \
                          yolov4-tiny.weights \
                          -c 0

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

1444_6de8f8798930c921890e486f74e805fc37d9b1f3.jpg

使用TensorRT引擎加速

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

下载、安装环境

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

$ git clone https://github.com/jkjung-avt/tensorrt_demos.git

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

$ cd ${HOME}/project/tensorrt_demos/ssd
$ ./install_pycuda.sh

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

1530_b09462a51cf610ec3eff34e6ac9049dbacffbbe2.png

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

$ nano ./install_pycuda.sh

1635_161d599b6a6a7841b3db1abcf488ccccd732ef93.png

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

1727_7f39338b22b749bcd79d704a958790747521ac6a.png

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

$ sudo apt-get install protobuf-compiler libprotoc-dev
$ sudo pip3 install onnx==1.4.1

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

$ cd ${HOME}/project/tensorrt_demos/plugins
$ make

1829_9f576cb0183e80b325d15add150471ca91835f97.png

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

1930_0afae7a74a20f070151a58e747c02caf57d44cd5.png

下载并转换yolo模型

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

$ cd ${HOME}/project/tensorrt_demos/yolo
$ ./download_yolo.sh	

2025_d01bfa793d6a45c9e0f5d7393bfd376da28a9d5c.png

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

$ 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。

使用TRT运行YOLOv4-416

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

$ cd ${HOME}/project/tensorrt_demos
$ python3 trt_yolo.py --usb 0 --model yolov4-416

2139_60be6c5bb769cf3c1db6ad030f6c4fc1fc381f57.jpg

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

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

2226_d1dbea00b0ca01e93caa55f145b7c0d876301d8e.png

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

使用TRT运行YOLOv4-Tiny-416

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

$ 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所以辨识的成效没有预期中的好:

2335_6d0e93914d974c5f782b5733fc006813562782b4.jpg

使用TensorRT运行模型比较表

此表从jkjung-avt/tensorrt_demos的github当中移植过来,其中mAP是常用评估对象侦测的算法,在yolov3的部分 tiny虽然有不错的FPS但是mAP相较yolov4却是差了不少,目前我认为yolov4-tiny-416以FPS实测18左右、mAP约0.38的状况算是较能够接受的范围:

TensorRT engine

mAP @
IoU=0.5:0.95

mAP @
IoU=0.5

FPS on Nano

yolov3-tiny-288 (FP16)

0.077

0.158

35.8

yolov3-tiny-416 (FP16)

0.096

0.202

25.5

yolov3-288 (FP16)

0.331

0.601

8.16

yolov3-416 (FP16)

0.373

0.664

4.93

yolov3-608 (FP16)

0.376

0.665

2.53

yolov3-spp-288 (FP16)

0.339

0.594

8.16

yolov3-spp-416 (FP16)

0.391

0.664

4.82

yolov3-spp-608 (FP16)

0.410

0.685

2.49

yolov4-tiny-288 (FP16)

0.179

0.344

36.6

yolov4-tiny-416 (FP16)

0.196

0.387

25.5

yolov4-288 (FP16)

0.376

0.591

7.93

yolov4-416 (FP16)

0.459

0.700

4.62

yolov4-608 (FP16)

0.488

0.736

2.35

yolov4-csp-256 (FP16)

0.336

0.502

12.8

yolov4-csp-512 (FP16)

0.436

0.630

4.26

yolov4x-mish-320 (FP16)

0.400

0.581

4.79

yolov4x-mish-640 (FP16)

0.470

0.668

1.46

结语

今天带大家稍微深入一点的了解了YOLOv4的Github,也带大家认识了使用TensorRT针对模型进行加速的部分,相信大家应该都很快就上手了!接下来我想带大家解析 darknet.py 并且尝试修改成更浅显易懂的程序代码。

相关文章

https://github.com/AlexeyAB/darknet

https://github.com/jkjung-avt/tensorrt_demos#yolov4

CAVEDU Education is devoted into robotics education and maker movement since 2008, and is intensively active in teaching fundamental knowledge and skills. We had published many books for readers in all ages, topics including Deep Learning, edge computing, App Inventor, IoT and robotics. Please check CAVEDU's website for more information: http://www.cavedu.com, http://www.appinventor.tw
DesignSpark Electrical Logolinkedin