Update: 2021/0816
原作者已经更新了好多个版本,我这里给出我写这篇文章时候的版本:Github,里面有我的最精简版的模型结构和模型
Update: 2021/05/19
新增 yolo-fastest keras/tflite 模型推理代码,仅图片,仓库地址:yolo-fastest_inference
github:Yolo-Fastest 的中文快速上手教程,包括 mAP 计算、
darknet 转 tflite
等目前有个检测的任务,需要轻量级的检测网络,在 NanoDet 和 Yolo-Fastest 中最终选择了后者,
不过要将作者的网络做进一步删减,目标平台(ART-PI)的 FLOPS 要求不超过0.1B
将 yolo-fastest 搬到 artpi 开发板上,且搭载 rt-thread 系统的工具是 RT-AK ,即将开放内测资格,这条仅对嵌入式小伙伴公布
2020.10 之前 号称是全网最轻量级的目标检测网络,有多轻量级呢?请看下面数据:
↓
这是 VOC 数据上的
Network | Model Size | mAP(VOC 2017) | FLOPS |
---|---|---|---|
Tiny YOLOv2 | 60.5MB | 57.1% | 6.97BFlops |
Tiny YOLOv3 | 33.4MB | 58.4% | 5.52BFlops |
YOLO Nano | 4.0MB | 69.1% | 4.51Bflops |
MobileNetv2-SSD-Lite | 13.8MB | 68.6% | &Bflops |
MobileNetV2-YOLOv3 | 11.52MB | 70.20% | 2.02Bflos |
Pelee-SSD | 21.68MB | 70.09% | 2.40Bflos |
Yolo Fastest | 1.3MB | 61.02% | 0.23Bflops |
Yolo Fastest-XL | 3.5MB | 69.43% | 0.70Bflops |
MobileNetv2-Yolo-Lite | 8.0MB | 73.26% | 1.80Bflops |
这是 COCO 数据集上的
Network | COCO mAP(0.5) | Resolution | Run Time(Ncnn 1xCore) | Run Time(Ncnn 4xCore) | FLOPS | Params | Weight size |
---|---|---|---|---|---|---|---|
Yolo-Fastest | 23.65 | 320X320 | 6.74ms | 4.42ms | 0.23BFlops | 0.325M | 1.3M |
Yolo-Fastest-XL | 32.45 | 320X320 | 15.15ms | 7.09ms | 0.70BFlops | 0.875M | 3.5M |
这是 前段时间超级火的 NanoDet
Model | COCO mAP | Resolution | Latency(ARM 4xCore) | FLOPS | Params | Model Size(ncnn bin) |
---|---|---|---|---|---|---|
NanoDet-m | 20.6 | 320*320 | 10.23ms | 0.72B | 0.95M | 1.8mb |
NanoDet-m | 21.7 | 416*416 | 16.44ms | 1.2B | 0.95M | 1.8mb |
YoloV3-Tiny | 16.6 | 416*416 | 37.6ms | 5.62B | 8.86M | 33.7mb |
YoloV4-Tiny | 21.7 | 416*416 | 32.81ms | 6.96B | 6.06M | 23.0mb |
什么?没看懂?!
请详细关注下 FLOPS
和Params
还有Model Size
mAP
啊!!!
兄弟,要是还看不懂,emmm,
由于该项目是基于 Darknet 训练和测试的,在开始之前需要先配置好 Darknet 环境
git clone https://github.com/dog-qiuqiu/Yolo-Fastest
System: linux
windows 编译 darknet的请看这:How to compile on Windows
修改 Makefile
, 且编译 make -j
, 成功标志是出现 darknet
这个可执行文件
财力充足:GPU
GPU=1
CUDNN=1
CUDNN_HALF=1
OPENCV=1
...
# 我用的是 1080ti, 所以要把前面几行删除
ARCH= -gencode arch=compute_52,code=[sm_52,compute_52] \
-gencode arch=compute_61,code=[sm_61,compute_61]
...
ifeq ($(CUDNN), 1)
COMMON+= -DCUDNN
ifeq ($(OS),Darwin) #MAC
CFLAGS+= -DCUDNN -I/usr/local/cuda/include
LDFLAGS+= -L/usr/local/cuda/lib -lcudnn
else
# CFLAGS+= -DCUDNN -I/usr/local/cudnn/include
# LDFLAGS+= -L/usr/local/cudnn/lib64 -lcudnn
CFLAGS+= -DCUDNN -I/usr/local/cuda/include
LDFLAGS+= -L/usr/local/cuda/lib64 -lcudnn
endif
endif
在这个地方,可能会遇到一些问题。
Makefile
文件中检索的CUDA
路径可能会遇到一些问题。
我习惯了用 conda
来傻瓜式安装 tensorflow
,但是这个时候,这个笨笨的 Makefile 竟然不会识别 conda
环境下的 CUDA
路径
为了简单的快速上手,我选择了脱离 conda
,在服务器上手动安装CUDA
、cudnn
,并且安装了一个 tensorflow-gpu
, 所以上面需要更改 CUDNN
路径
此时,顺利的话,执行 make -j
之后,就应该可以看到当前文件夹下出现一个 darknet
的可执行文件。
Soft | Version |
---|---|
CUDA | 11.0.228 |
CUDNN | cudnn-11.0-linux-x64-v8.0.5.39 |
tensorflow-gpu | 2.4.0 |
当然,还有不顺利的情况,意外频频有,今年特别多。
有一个问题我不记得了,出现的时候没有记录,问题的原因是找不到 nvcc
解决方法:
/usr/local/cuda/bin
下是否有nvcc可执行程序~/.bashrc
,添加环境变量 export PATH=$PATH:/usr/local/cuda/bin
sudo apt install nvidia-cuda-toolkit
nvcc --version
囊中羞涩:CPU
好了,上面的一些巨佬的一些配置通通跟咱们没有任何的关系。
高兴的话,在 Makefile
的第4行,将 OPENCV=0
改成1,保不齐啥时候咱会用到 opencv
这个大杀器。一般我都会必装 opencv
的。
执行:
make -j
在当前文件夹下面,生成了 darknet
可执行文件
图片检测验证:
bash image_yolov3.sh
# 等同于
./darknet detector test ./data/coco.data ./Yolo-Fastest/COCO/yolo-fastest.cfg ./Yolo-Fastest/COCO/yolo-fastest.weights data/person.jpg -thresh 0.55
# 不显示图片,因为有时候在服务器上,不能显示图片,会报这个warning,有点看不顺眼
# Gtk-WARNING **: 17:42:47.783: cannot open display:
./darknet detector test ./data/coco.data ./Yolo-Fastest/COCO/yolo-fastest.cfg ./Yolo-Fastest/COCO/yolo-fastest.weights data/person.jpg -thresh 0.55 -dont_show
# 神奇的命令
./darknet detector test ./data/coco.data ./Yolo-Fastest/COCO/yolo-fastest.cfg ./Yolo-Fastest/COCO/yolo-fastest.weights -thresh 0.55 -dont_show
视频检测验证:
# 这个时候就不能直接使用下面这个命令了
# sh video_yolov3.sh
# 需要指定视频路径
./darknet detector demo ./data/coco.data ./Yolo-Fastest/COCO/yolo-fastest.cfg ./Yolo-Fastest/COCO/yolo-fastest.weights /home/lebhoryi/RT-Thread/Detection_API/video/000.mp4 -thresh 0.55
作者的建议是先获取训练好的权重文件,然后在此基础上做训练。嗯,按照作者的思路走,不会有坑
以训练单个person类别为例,VOC数据集
./darknet partial yolo-fastest.cfg yolo-fastest.weights yolo-fastest.conv.109 109
# 该步骤来自:https://pjreddie.com/darknet/yolo/
# Training YOLO on VOC
# Get The Pascal VOC Data
wget https://pjreddie.com/media/files/VOCtrainval_11-May-2012.tar
wget https://pjreddie.com/media/files/VOCtrainval_06-Nov-2007.tar
wget https://pjreddie.com/media/files/VOCtest_06-Nov-2007.tar
tar xf VOCtrainval_11-May-2012.tar
tar xf VOCtrainval_06-Nov-2007.tar
tar xf VOCtest_06-Nov-2007.tar
# Generate Labels for VOC
#
# 记得修改代码文件中对应的路径,由于要训练一个person类别,classes那里也需要做更改
# classes = ['person']
wget https://pjreddie.com/media/files/voc_label.py
python voc_label.py
ls
# 2007_test.txt VOCdevkit
# 2007_train.txt voc_label.py
# 2007_val.txt VOCtest_06-Nov-2007.tar
# 2012_train.txt VOCtrainval_06-Nov-2007.tar
# 2012_val.txt VOCtrainval_11-May-2012.tar
cat 2007_train.txt 2007_val.txt 2012_*.txt > train.txt
classes= 1
train = <path-to-voc>/train.txt
valid = <path-to-voc>/2007_test.txt
names = data/voc.names
backup = backup # 模型存储文件夹
将 data/voc.names
文件中的类别删除只剩下 person
./darknet detector train voc.data ./Yolo-fastest/VOC/yolo-fastest.cfg yolo-fastest.conv.109
训练好的模型文件将会保存在backup
文件夹下面。
# 我选择了最简单的,更多信息请戳下面链接
# https://github.com/MuhammadAsadJaved/darknet#how-to-calculate-map-on-pascalvoc-2007
# points 11 是VOC 数据集,101 是 MS COCO,0 是 ImageNet, PascalVOC 2010-2012, your custom dataset
./darknet detector map data/voc.data Yolo-Fastest/VOC/yolo-fastest.cfg Yolo-Fastest/VOC/yolo-fastest.weights -points 11
这个时候,就很奇怪,我测出来是 56.19 %,没有到作者说的61.02%,可能是数据集不对,我用 VOC2007 测得,作者上写的是 VOC2017
这个不重要,重要的是我成功获取了mAP
这个指标。嗯,距离大佬又近了一步。
既然看到了这里,差不多大家都可以获取到 darknet
训练好的模型
但是在下对 darknet
不熟啊,要搬到目标平台,还是 keras
和 tflite
更适合我
然后,认真的看了两圈作者的仓库,没有发现如何转 tensorflow
的教程,嗯,问题不大,因为我发现了这个:
NCNN
和 MNN
,这些都吸引不了我,我一眼就相中了 TensorRT
,正好手里有一块 Jetson nano
,等下周挤出点时间折腾一下。
darknet
转 keras
、tflite
仓库:
david8862/keras-YOLOv3-model-set
git clone https://github.com/david8862/keras-YOLOv3-model-set
cd keras-YOLOv3-model-set
pip install -r requirement.txt
# -f 是固定输入,否则你会发现输入是 None×None×3
# -p 是将神经网络结构图保存为 .png
python tools/model_converter/convert.py <path-to-cfg>/yolo-fastest.cfg <path-to-weights>/yolo-fastest.weights weights/yolo-s.h5 -f -p
如果你训练的时候,输入是 weight×height×1,则需要改动:
...
print('Creating Keras model.')
if width and height and args.fixed_input_shape:
# input_layer = Input(shape=(height, width, 3), name='image_input')
input_layer = Input(shape=(height, width, 1), name='image_input')
else:
# input_layer = Input(shape=(None, None, 3), name='image_input')
input_layer = Input(shape=(None, None,1), name='image_input')
...
python tools/model_converter/custom_tflite_convert.py --keras_model_file ./weights/yolo-fastest.h5 --output_file ./weights/yolo-fastest.tflite
python tools/model_converter/post_train_quant_convert.py --keras_model_file ./weights/yolo-fastest.h5 --annotation_file <path-to-voc>/2007_test.txt --model_input_shape 320x320 --sample_num 30 --output_file ./weights/yolo-fastest.tflite
如果你训练的时候,输入是 weight×height×1,则需要改动:
...
image = np.array([image], dtype=np.float32)
image = image[..., -1]
image = np.expand_dims(image, axis=-1)
yield [image]
...
Model | mAP(%) | Input | BFLOPS | Size | Inference | Data |
---|---|---|---|---|---|---|
yolo-fastest | 56.19 | 320x320x3 | 0.238 | 613.6k | Failed | 01/09 |
yolo-xl | 44.51 | 320x320x1 | 0.096 | 224.1k | Failed | 01/08 |
yolo-l | 22.67 | 320x320x1 | 0.057 | 176.7k | 787ms | 01/12 |
~~01/13 ~~ |
yolo-s 单类别检测(人):21.58%,在 art-pi 上的推理时间是 50ms
推理时间是在 rt-thread
系统 + ART-PI
开发板下做的测试
Size
是量化后的 tflite
模型大小
i5-9400
yolo-fastest
的推理时间是 50ms,mAP 56.19%
i5-9400
yolo-xl
的推理时间是 19ms,mAP 44.51%
i5-9400
yolo-l
的推理时间是 10ms,mAP 22.67%
有一个问题,1080ti 服务器下的推理时间是150ms
,不知道为啥
好了,下一步就是将yolo-fastest
请上jetson nano
…
Yolo-Fastest/README.md
darknet/README.md
解决nvcc找不到的问题
yolo 官网