YOLOv4: Darknet 如何于 Docker 编译,及训练 COCO 子集
YOLO 算法是非常著名的目标检测算法。从其全称 You Only Look Once: Unified, Real-Time Object Detection ,可以看出它的特性:
- Look Once: one-stage (one-shot object detectors) 算法,把目标检测的两个任务分类和定位一步完成。
- Unified: 统一的架构,提供 end-to-end 的训练和预测。
- Real-Time: 实时性,初代论文给出的指标 FPS 45 , mAP 63.4 。
YOLOv4: Optimal Speed and Accuracy of Object Detection ,于今年 4 月公布,采用了很多近些年 CNN 领域优秀的优化技巧。其平衡了精度与速度,目前在实时目标检测算法中精度是最高的。
论文地址:
- YOLO: https://arxiv.org/abs/1506.02640
- YOLO v4: https://arxiv.org/abs/2004.10934
源码地址:
本文将介绍 YOLOv4 官方 Darknet 实现,如何于 Docker 编译使用。以及从 MS COCO 2017 数据集中怎么选出部分物体,训练出模型。
主要内容有:
- 准备 Docker 镜像
- 准备 COCO 数据集
- 用预训练模型进行推断
- 准备 COCO 数据子集
- 训练自己的模型并推断
- 参考内容
准备 Docker 镜像
首先,准备 Docker ,请见:Docker: Nvidia Driver, Nvidia Docker 推荐安装步骤 。
之后,开始准备镜像,从下到上的层级为:
- nvidia/cuda: https://hub.docker.com/r/nvidia/cuda
- OpenCV: https://github.com/opencv/opencv
- Darknet: https://github.com/AlexeyAB/darknet
nvidia/cuda
准备 Nvidia 基础 CUDA 镜像。这里我们选择 CUDA 10.2 ,不用最新 CUDA 11,因为现在 PyTorch 等都还都是 10.2 呢。
拉取镜像:
docker pull nvidia/cuda:10.2-cudnn7-devel-ubuntu18.04
测试镜像:
$ docker run --gpus all nvidia/cuda:10.2-cudnn7-devel-ubuntu18.04 nvidia-smi
Sun Aug 8 00:00:00 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.100 Driver Version: 440.100 CUDA Version: 10.2 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce RTX 208... Off | 00000000:07:00.0 On | N/A |
| 0% 48C P8 14W / 300W | 340MiB / 11016MiB | 2% Default |
+-------------------------------+----------------------+----------------------+
| 1 GeForce RTX 208... Off | 00000000:08:00.0 Off | N/A |
| 0% 45C P8 19W / 300W | 1MiB / 11019MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
OpenCV
基于 nvidia/cuda 镜像,构建 OpenCV 的镜像:
cd docker/ubuntu18.04-cuda10.2/opencv4.4.0/
docker build \
-t joinaero/ubuntu18.04-cuda10.2:opencv4.4.0 \
--build-arg opencv_ver=4.4.0 \
--build-arg opencv_url=https://gitee.com/cubone/opencv.git \
--build-arg opencv_contrib_url=https://gitee.com/cubone/opencv_contrib.git \
.
其 Dockerfile 可见这里: https://github.com/ikuokuo/start-yolov4/blob/master/docker/ubuntu18.04-cuda10.2/opencv4.4.0/Dockerfile 。
Darknet
基于 OpenCV 镜像,构建 Darknet 镜像:
cd docker/ubuntu18.04-cuda10.2/opencv4.4.0/darknet/
docker build \
-t joinaero/ubuntu18.04-cuda10.2:opencv4.4.0-darknet \
.
其 Dockerfile 可见这里: https://github.com/ikuokuo/start-yolov4/blob/master/docker/ubuntu18.04-cuda10.2/opencv4.4.0/darknet/Dockerfile 。
上述镜像已上传 Docker Hub 。如果 Nvidia 驱动能够支持 CUDA 10.2 ,那可以直接拉取该镜像:
docker pull joinaero/ubuntu18.04-cuda10.2:opencv4.4.0-darknet
准备 COCO 数据集
MS COCO 2017 下载地址: http://cocodataset.org/#download
图像,包括:
- 2017 Train images [118K/18GB]
- 2017 Val images [5K/1GB]
- 2017 Test images [41K/6GB]
- 2017 Unlabeled images [123K/19GB]
标注,包括:
- 2017 Train/Val annotations [241MB]
- 2017 Stuff Train/Val annotations [1.1GB]
- 2017 Panoptic Train/Val annotations [821MB]
- 2017 Testing Image info [1MB]
- 2017 Unlabeled Image info [4MB]
用预训练模型进行推断
预训练模型 yolov4.weights ,下载地址 https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights 。
运行镜像:
xhost +local:docker
docker run -it --gpus all \
-e DISPLAY \
-e QT_X11_NO_MITSHM=1 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/.Xauthority:/root/.Xauthority \
--name darknet \
--mount type=bind,source=$HOME/Codes/devel/datasets/coco2017,target=/home/coco2017 \
--mount type=bind,source=$HOME/Codes/devel/models/yolov4,target=/home/yolov4 \
joinaero/ubuntu18.04-cuda10.2:opencv4.4.0-darknet
进行推断:
./darknet detector test cfg/coco.data cfg/yolov4.cfg /home/yolov4/yolov4.weights \
-thresh 0.25 -ext_output -show -out /home/coco2017/result.json \
/home/coco2017/test2017/000000000001.jpg
推断结果:

准备 COCO 数据子集
MS COCO 2017 数据集有 80 个物体标签。我们从中选取自己关注的物体,重组个子数据集。
首先,获取样例代码:
git clone https://github.com/ikuokuo/start-yolov4.git
- scripts/coco2yolo.py: COCO 数据集转 YOLO 数据集的脚本
- scripts/coco/label.py: COCO 数据集的物体标签有哪些
- cfg/coco/coco.names: 编辑我们想要的那些物体标签
之后,准备数据集:
cd start-yolov4/
pip install -r scripts/requirements.txt
export COCO_DIR=$HOME/Codes/devel/datasets/coco2017
# train
python scripts/coco2yolo.py \
--coco_img_dir $COCO_DIR/train2017/ \
--coco_ann_file $COCO_DIR/annotations/instances_train2017.json \
--yolo_names_file ./cfg/coco/coco.names \
--output_dir ~/yolov4/coco2017/ \
--output_name train2017 \
--output_img_prefix /home/yolov4/coco2017/train2017/
# valid
python scripts/coco2yolo.py \
--coco_img_dir $COCO_DIR/val2017/ \
--coco_ann_file $COCO_DIR/annotations/instances_val2017.json \
--yolo_names_file ./cfg/coco/coco.names \
--output_dir ~/yolov4/coco2017/ \
--output_name val2017 \
--output_img_prefix /home/yolov4/coco2017/val2017/
数据集,内容如下:
~/yolov4/coco2017/
├── train2017/
│ ├── 000000000071.jpg
│ ├── 000000000071.txt
│ ├── ...
│ ├── 000000581899.jpg
│ └── 000000581899.txt
├── train2017.txt
├── val2017/
│ ├── 000000001353.jpg
│ ├── 000000001353.txt
│ ├── ...
│ ├── 000000579818.jpg
│ └── 000000579818.txt
└── val2017.txt
训练自己的模型并推断
准备必要文件
cfg/coco/coco.names <cfg/coco/coco.names.bak has original 80 objects>
- Edit: keep desired objects
cfg/coco/yolov4.cfg <cfg/coco/yolov4.cfg.bak is original file>
- Download yolov4.cfg, then changed:
batch=64,subdivisions=32 <32 for 8-12 GB GPU-VRAM>width=512,height=512 <any value multiple of 32>classes=<your number of objects in each of 3 [yolo]-layers>max_batches=<classes*2000, but not less than number of training images and not less than 6000>steps=<max_batches*0.8, max_batches*0.9>filters=<(classes+5)x3, in the 3 [convolutional] before each [yolo] layer>filters=<(classes+9)x3, in the 3 [convolutional] before each [Gaussian_yolo] layer>
-
- Edit:
train,validto YOLO datas
- Edit:
csdarknet53-omega.conv.105
- Download csdarknet53-omega_final.weights, then run:
docker run -it --rm --gpus all \
--mount type=bind,source=$HOME/Codes/devel/models/yolov4,target=/home/yolov4 \
joinaero/ubuntu18.04-cuda10.2:opencv4.4.0-darknet ./darknet partial cfg/csdarknet53-omega.cfg /home/yolov4/csdarknet53-omega_final.weights /home/yolov4/csdarknet53-omega.conv.105 105
训练自己的模型
运行镜像:
cd start-yolov4/
xhost +local:docker
docker run -it --gpus all \
-e DISPLAY \
-e QT_X11_NO_MITSHM=1 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/.Xauthority:/root/.Xauthority \
--name darknet \
--mount type=bind,source=$HOME/Codes/devel/models/yolov4,target=/home/yolov4 \
--mount type=bind,source=$HOME/yolov4/coco2017,target=/home/yolov4/coco2017 \
--mount type=bind,source=$PWD/cfg/coco,target=/home/cfg \
joinaero/ubuntu18.04-cuda10.2:opencv4.4.0-darknet
进行训练:
mkdir -p /home/yolov4/coco2017/backup
# Training command
./darknet detector train /home/cfg/coco.data /home/cfg/yolov4.cfg /home/yolov4/csdarknet53-omega.conv.105 -map
中途可以中断训练,然后这样继续:
# Continue training
./darknet detector train /home/cfg/coco.data /home/cfg/yolov4.cfg /home/yolov4/coco2017/backup/yolov4_last.weights -map
yolov4_last.weights 每迭代 100 次,会被记录。
如果多 GPU 训练,可以在 1000 次迭代后,加参数 -gpus 0,1 ,再继续:
# How to train with multi-GPU
# 1. Train it first on 1 GPU for like 1000 iterations
# 2. Then stop and by using partially-trained model `/backup/yolov4_1000.weights` run training with multigpu
./darknet detector train /home/cfg/coco.data /home/cfg/yolov4.cfg /home/yolov4/coco2017/backup/yolov4_1000.weights -gpus 0,1 -map
训练过程,记录如下:

加参数 -map 后,上图会显示有红线 mAP。
查看模型 mAP@IoU=50 精度:
$ ./darknet detector map /home/cfg/coco.data /home/cfg/yolov4.cfg /home/yolov4/coco2017/backup/yolov4_final.weights
...
Loading weights from /home/yolov4/coco2017/backup/yolov4_final.weights...
seen 64, trained: 384 K-images (6 Kilo-batches_64)
Done! Loaded 162 layers from weights-file
calculation mAP (mean average precision)...
Detection layer: 139 - type = 27
Detection layer: 150 - type = 27
Detection layer: 161 - type = 27
160
detections_count = 745, unique_truth_count = 190
class_id = 0, name = train, ap = 80.61% (TP = 142, FP = 18)
for conf_thresh = 0.25, precision = 0.89, recall = 0.75, F1-score = 0.81
for conf_thresh = 0.25, TP = 142, FP = 18, FN = 48, average IoU = 75.31 %
IoU threshold = 50 %, used Area-Under-Curve for each unique Recall
mean average precision (mAP@0.50) = 0.806070, or 80.61 %
Total Detection Time: 4 Seconds
进行推断:
./darknet detector test /home/cfg/coco.data /home/cfg/yolov4.cfg /home/yolov4/coco2017/backup/yolov4_final.weights \
-ext_output -show /home/yolov4/coco2017/val2017/000000006040.jpg
推断结果:

参考内容
- Train Detector on MS COCO (trainvalno5k 2014) dataset
- How to evaluate accuracy and speed of YOLOv4
- How to train (to detect your custom objects)
结语
为什么用 Docker ? Docker 导出镜像,可简化环境部署。如 PyTorch 也都有镜像,可以直接上手使用。
关于 Darknet 还有什么? 下回介绍 Darknet 于 Ubuntu 编译,及使用 Python 接口 。
Let's go coding ~
YOLOv4: Darknet 如何于 Docker 编译,及训练 COCO 子集的更多相关文章
- YOLOv4: Darknet 如何于 Ubuntu 编译,及使用 Python 接口
本文将介绍 YOLOv4 官方 Darknet 实现,如何于 Ubuntu 18.04 编译,及使用 Python 接口. 主要内容有: 准备基础环境: Nvidia Driver, CUDA, cu ...
- 矩池云上安装yolov4 darknet教程
这里我是用PyTorch 1.8.1来安装的 拉取仓库 官方仓库 git clone https://github.com/AlexeyAB/darknet 镜像仓库 git clone https: ...
- 利用Docker编译Hadoop 3.1.0
前言 为什么要使用Docker编译,请自行百度 操作系统环境:Centos 6.8 uname -r 内核版本:2.6.32-642.el6.x86_64 除非有把握否则不要在Centos6.8中直接 ...
- 使用 Docker 编译 OpenWRT(Widora)
Docker 是一种新的被称之为容器的虚拟机.本文将使用此工具,进行 OpenWRT 的编译. 在 Docker 中下载 Ubuntu 14.04 的镜像 使用以下命令可以十分方便的从远程服务器上将 ...
- (原) ubuntu下用pycharm2016.1专业版配docker编译环境(docker Interpreter)
一:先创建docker-machine 先创建docker machine.我主机上的虚拟机是virtualbox.$ docker-machine create --driver virtualbo ...
- docker 编译开发代码做镜像
文件目录 Dockerfile 是docker制作镜像的文件,docker_run.sh是sh文件,gin_test是go编译之后的linux可执行程序,gintest.env是配置文件夹 首先写一个 ...
- Docker编译Android6.0源码
docker环境配置 更正时区时间 # 查看当前时间 $ date # 修改当前时间 $ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ech ...
- 使用Docker编译OpenResty支持国密ssl加密
编译环境 执行编译操作环境如下 #操作系统 CentOS Linux release 7.4.1708 (Core) #docker版本 Version: 19.03.5 编译过程 Dockerfil ...
- 编译原理实验 NFA子集法构造DFA,DFA的识别 c++11实现
实验内容 将非确定性有限状态自动机通过子集法构造确定性有限状态自动机. 实验步骤 1,读入NFA状态.注意最后需要设置终止状态. 2,初始态取空,构造DFA的l0状态,将l0加入未标记状态队列que ...
随机推荐
- Java 8中Lambda表达式默认方法的模板方法模式,你够了解么?
为了以更简单的术语描述模板方法,考虑这个场景:假设在一个工作流系统中,为了完成任务,有4个任务必须以给定的执行顺序执行.在这4个任务中,不同工作流系统的实现可以根据自身情况自定义任务的执行内容. 模板 ...
- Autocad.net利用Xaml创建Ribbon界面
0.Ribbon界面 Ribbon界面设计语言最早于Office 2007出现,后来逐渐被其他Windows系统组件采用,一些专业软件也开始以Ribbon界面取代传统菜单栏设计.Ribbon设计语言显 ...
- python 3.7 jupyter中安装 docx报错
from docx import Document报错: Import Error: No module named ‘exceptions‘ 解决办法: 使用下面的命令重新安装docx !pip i ...
- Jmeter 常用函数(4)- 详解 __setProperty
如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 前言 有看我之前写的 Jmeter 文章的童 ...
- Go 切片的一种有趣内存泄漏方式
今天我在看 Prashant Varanasi 的 Go 发布会演讲:使用火焰图进行生产分析(Analyzing production using Flamegraphs),在演讲开始的第 28 分钟 ...
- Java 8新特性(二):Stream API
本篇文章继续介绍Java 8的另一个新特性--Stream API.新增的Stream API与InputStream和OutputStream是完全不同的概念,Stream API是对Java中集合 ...
- 第三篇 Scrum冲刺博客
一.会议图片 二.项目进展 成员 完成情况 今日任务 冯荣新 商品列表,商品详情轮播图 商品底部工具栏,购物车列表 陈泽佳 历史足迹,静态页面 渲染搜索结果,防抖的实现 徐伟浩 未完成 商品信息录入 ...
- pytest的fixture怎么用?
文章总览图 fixture和unittest是冲突的.舍弃unittest只用pytest. 会遇到在很多用例当中,它的前置条件是长得一样的.用例写的越来越多的时候,肯定会遇到前置条件都差不多,大家差 ...
- 真是没想到 Springboot + Flowable 工作流开发会这么简单
本文收录在个人博客:www.chengxy-nds.top,技术资料共享,同进步 程序员是块砖,哪里需要哪里搬 公司内部的OA系统最近要升级改造,由于人手不够就把我借调过去了,但说真的我还没做过这方面 ...
- [CSP-S2019]格雷码 题解
CSP-S2 2019 D1T1 考场上第一遍读题的时候感觉不是很一眼……不是很符合D1T1的气质 之前完全没听说过格雷码是什么玩意,还是我太菜了 仔细读题后发现应该是有规律可循的 赛后据说有$O(1 ...