3

如何使用 Yolov4 训练人脸口罩检测模型 - 之一Yo

 1 year ago
source link: https://www.cnblogs.com/zhiyiYo/p/16757345.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

疫情当下,出入医院等公共场所都被要求佩戴口罩。这篇博客将会介绍如何使用 Yolov4,训练一个人脸口罩检测模型(使用 Yolov4 的原因是目前只复现到了 v4 😇),代码地址为 https://github.com/zhiyiYo/yolov4

Yolov4

Yolov4 的神经网络结构相比 Yolov3 变化不是很大,主要更换了激活函数为 Mish,增加了 SPP 块和 PAN 结构(图源 《yolo系列学习笔记----yolov4(SPP原理)》)。

2065884-20221006111420662-130956113.jpg

感觉 Yolov4 最大的特点就是使用了一大堆的 Trick,比如数据增强方面使用了马赛克数据增强、Mixup 数据增强,将定位损失函数更换为 CIOU 损失。论文中提到了很多的 Trick,我的代码中没有全部复现,不过在 VOC2012 数据集训练了 160 个 epoch 之后 mAP 也能达到 83%,效果还是不错的。

可以在终端使用下述指令下载 Yolov4 的代码:

复制git clone https://github.com/zhiyiYo/yolov4.git

人脸口罩数据集

网上可以找到很多人脸口罩数据集,这里使用的是 AIZOOTech 提供的数据集。由于这个数据集的结构和 Pascal VOC 数据集不一样,所以重新组织一下数据集,并且修复和移除了数据集中的非法标签,可以在 Kaggle 上下载此数据集。目前这个数据集包含 6130 张训练图像,1839 张测试图像,对于 Yolov4 的训练来说应该是绰绰有余的。下载完数据集将其解压到 data 文件夹下。

在训练之前,我们需要使用 K-means 聚类算法对训练集中的边界框进行聚类,对于 416×416 的输入图像,聚类结果如下:

复制anchors = [
    [[100, 146], [147, 203], [208, 260]],
    [[26, 43], [44, 65], [65, 105]],
    [[4, 8], [8, 15], [15, 27]]
]

训练神经网络

训练目标检测模型一般都需要加载预训练的主干网络的权重,可以从谷歌云盘下载预训练好的权重 CSPDarknet53.pth 并将其放在 model 文件夹下。这里给出训练所用的代码 train.py,使用 python train.py 就能开始训练。模型会先冻结训练上 50 个 epoch,接着解冻训练 110 个 epoch:

复制# coding:utf-8
from net import TrainPipeline, VOCDataset
from utils.augmentation_utils import YoloAugmentation, ColorAugmentation

# 训练配置
config = {
    "n_classes": len(VOCDataset.classes),
    "image_size": 416,
    "anchors": [
        [[100, 146], [147, 203], [208, 260]],
        [[26, 43], [44, 65], [65, 105]],
        [[4, 8], [8, 15], [15, 27]]
    ],
    "darknet_path": "model/CSPdarknet53.pth",
    "lr": 1e-2,
    "batch_size": 8,
    "freeze_batch_size": 16,
    "freeze": True,
    "freeze_epoch": 50,
    "max_epoch": 160,
    "start_epoch": 0,
    "num_workers": 4,
    "save_frequency": 10,
    "no_aug_ratio": 0
}

# 加载数据集
root = 'data/FaceMaskDataset/train'
dataset = VOCDataset(
    root,
    'all',
    transformer=YoloAugmentation(config['image_size']),
    color_transformer=ColorAugmentation(config['image_size']),
    use_mosaic=True,
    use_mixup=True,
    image_size=config["image_size"]
)

if __name__ == '__main__':
    train_pipeline = TrainPipeline(dataset=dataset, **config)
    train_pipeline.train()

测试神经网络

训练完使用 python evals.py 可以测试所有保存的模型,evals.py 代码如下:

复制# coding:utf-8
import json
from pathlib import Path

import matplotlib as mpl
import matplotlib.pyplot as plt

from net import EvalPipeline, VOCDataset

mpl.rc_file('resource/theme/matlab.mplstyle')


# 载入数据集
root = 'data/FaceMaskDataset/val'
dataset = VOCDataset(root, 'all')
anchors = [
    [[100, 146], [147, 203], [208, 260]],
    [[26, 43], [44, 65], [65, 105]],
    [[4, 8], [8, 15], [15, 27]]
]

# 列出所有模型,记得修改 Yolo 模型文件夹的路径
model_dir = Path('model/2022-10-05_22-59-44')
model_paths = [i for i in model_dir.glob('Yolo_*')]
model_paths.sort(key=lambda i: int(i.stem.split("_")[1]))

# 测试所有模型
mAPs = []
iterations = []
for model_path in model_paths:
    iterations.append(int(model_path.stem[5:]))
    ep = EvalPipeline(model_path, dataset, anchors=anchors, conf_thresh=0.001)
    mAPs.append(ep.eval()*100)

# 保存数据
with open('eval/mAPs.json', 'w', encoding='utf-8') as f:
    json.dump(mAPs, f)
    
# 绘制 mAP 曲线
fig, ax = plt.subplots(1, 1, num='mAP 曲线')
ax.plot(iterations, mAPs)
ax.set(xlabel='iteration', ylabel='mAP', title='mAP curve')
plt.show()

得到的 mAP 曲线如下图所示,在第 120 个 epoch 达到最大值 94.14%:

2065884-20221006115554561-589148662.png

下面使用一张真实图像看看训练效果如何,运行 demo.py

复制# coding:utf-8
from net import VOCDataset
from utils.detection_utils import image_detect

# 模型文件和图片路径
model_path = 'model/Yolo_120.pth'
image_path = 'resource/image/三上老师.jpg'

# 检测目标
anchors = [
    [[100, 146], [147, 203], [208, 260]],
    [[26, 43], [44, 65], [65, 105]],
    [[4, 8], [8, 15], [15, 27]]
]
image = image_detect(model_path, image_path, VOCDataset.classes, anchors=anchors, conf_thresh=0.5)
image.show()

不错,效果非常好 😊:

2065884-20221006114035207-300097184.jpg

至此,介绍完了训练 Yolov4 人脸口罩检测模型的过程,代码放在了 https://github.com/zhiyiYo/yolov4,以上~~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK