一.前言
由于诸多原因,这篇的创作相对于第二篇确实过了很久,对于感兴趣的研究人员实在是抱歉(虽然前两篇也没什么人看)。
之前我试着跑Jetson Nano官方开源的项目dusty-nv/jetson-inference
但是因为各种各样的原因死活跑不起来,在网上搜索了很多,还在Issues里提问了,最终也解决不了,属实无奈😔。后来在油管上看到有大神在Jetson Nano上跑了yolov3的各种版本,还把模型拿出来卖!于是我便对这个广泛应用于目标检测的轻量级网络起了兴趣,并做了如下的工作。
二.yolov3的运行
1.环境搭建
我全篇参考这个博客。
在此我仅仅把上面的内容稍微翻译一下:
1)更新库
sudo apt-get update
2)设置cuda的环境变量路径(这里是以10.0版本的cuda为例;建议把环境变量配置到gedit ~/.bashrc文件末尾)
export PATH=/usr/local/cuda-10.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
3)下载Darknet 以及Yolov3的权重文件
git clone https://github.com/AlexeyAB/darknet
cd darknet
wget https://pjreddie.com/media/files/yolov3.weights
wget https://pjreddie.com/media/files/yolov3-tiny.weights
4)配置GPU相关参数
sudo gedit Makefile
打开后配置参数(之前应该都是0):
GPU=1
CUDNN=1
OPENCV=1
5)完成配置
make
2.普通版运行
**记得要用5V3A的电源供电,不要用USB port不然会带不动导致Jetson Nano闪退.**
1)进入yolov3(darknet)根目录
cd darknet
2)图片检测()
./darknet detector test cfg/coco.data yolov3.cfg yolov3.weights -ext_output dog.jpg
./darknet detector test cfg/coco.data yolov3-tiny.cfg yolov3-tiny.weights -ext_output dog.jpg
3)视屏检测(如果没建swap分区,建议用yolov3-tiny)
./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights -ext_output test.mp4
./darknet detector demo cfg/coco.data cfg/yolov3-tiny.cfg yolov3-tiny.weights -ext_output test.mp4
4)摄像头检测(这一步按原版会出错,我后来参考的是)
./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights -c 0
./darknet detector demo cfg/coco.data cfg/yolov3-tiny.cfg yolov3-tiny.weights "nvarguscamerasrc ! video/x-raw(memory:NVMM), width=1280, height=720, format=NV12, framerate=30/1 ! nvvidconv flip-method=2 ! video/x-raw, width=1280, height=720, format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink"
我只在室内简单地跑了以下,感觉检测效果还行,就是FPS稍微低了些(15左右,有可能是CSI摄像头或者其它环境配置的问题,知乎上有人说可以达到25FPS),其实老实讲对于这对于一个总价不到1000的嵌入式设备(并且兼容树莓派/ARM系列单片机的周边设备)而言已经非常不错了。
3.Yolov3剪枝
这里我主要是参考,因为这篇应该是github上有关yolov3剪枝方面去最容易理解的一个模型,我按作者的思路一步一步地做到了最后(建议不是太懂的还是老老实实地下载oxford hand数据集,除了正常训练其它的都做了).这篇应该是集大成者,有兴趣的可以去深究它.
1)准备自己的数据集
此处我使用的是coco2017数据集,通过提取其person类作为模型数据集。
提取代码主要参考这两篇: 参考1
参考2
2)更改配置文件
这个是我稀疏化训练的程序:
python3 train.py --cfg cfg/yolov3-tiny-1cls.cfg --data data/coco_person.data --weights weights/yolov3-tiny.weights --accumulate 1 --epoch 100 --batch-size 16 -sr --s 0.001 --prune 2
其中参考做出解读:
- cfg: 配置文件;此处根据数据集和weights文件选择。我是因为只训练一类并且使用的是yolov3-tiny.weights
- data: 此处最好是仿照oxfordhand.data进行修改并更改oxfordhand.names
- weights: yolov3.weights/yolov3-tiny.weights 二选一,因为要跑在jetson nano上所以我先选了tiny
- accumulate : 它和batch-size决定了在送入优化器之前的有效批次大小,我习惯地把这两个参数调小
- epoch: 参考中有说’第一次我使用的是默认的300轮,当我训练到43轮时,如下图所示loss与map趋于稳定,权重也 相对归一化,我选择减小轮次以使用更小的学习率’,而且我目前这张卡性能不大好,所以参照着修改为100
- -sr --s: 这两处近乎默认,如果数据集不够好可以稍微改小点
- prune: 用的是tiny,所以选2
3)稀疏化训练
按上述命令进行训练,环境:
- 机器 : Dell T5820服务器
- GPU: Nvidia P4000
- cuda: 10.1
- cudnn: 7.5
总共训练了77个小时,曲线相对正常,只不过最后的map比较低,可能和我的超参数设置有关(欢迎各位点评).
4)tiny剪枝
需要注意的是,这里需要在.py文件内,将opt内的cfg和weights变量指向第2步稀疏化后生成的cfg文件和weights文件。 此外,可通过增大代码中percent的值来获得更大的压缩率。(若稀疏化不到位,且percent值过大,程序会报错;我选择了0.1和0.3的)
python3 prune_tiny_yolo.py
单张图片测试
5)在Jetson nano上运行
未剪枝的tiny版本: fps约在15左右(jetson nano现在不在身边,等以后再附上视屏)。
剪枝的tiny版本: