Pytorch_WiderFace_2_Retina_2_YOLO数据集

YOLOv5训练

1.数据
    图片和标签要分开存放。
     yolov5的代码会根据图片找标签,具体形式的把图片路径/images/*.jpg替换为/labels/*.txt,
     所以要新建两个文件夹,一个名为 images 存放图片,一个名为 labels 存放标签txt文件
2.配置文件
     自定义训练需要修改.yaml文件,一个是模型文件(可选),一个是数据文件
	    模型文件
	        ./models里的yolov5s.yaml / yolov5m.yaml / yolov5l.yaml / yolov5x.yaml文件
	    	或者选用预训练权重初始化 ./weight中的
	    数据文件:根据./data文件夹里的coco数据文件,制作自己的数据文件
		
3.训练
    -weights指定权重,--data指定数据文件,--batch-size指定batch大小,--epochs指定epoc
	 --weights '' 则会随机初始化权重
	 -hyp指定超参数文件
	 --epochs (⭐)指定epoch数,默认300
	 --project 训练结果存放目录,默认./runs/train/

数据集 WIDER FACE

 WIDER FACE 数据集是人脸检测的一个benchmark数据集,WIDERFace datasets
 包含32203图像,以及393703个标注人脸,
 其中,158989个标注人脸位于训练集,
       39496个位于验证集。
 每一个子集都包含3个级别的检测难度:Easy,Medium,Hard。
 这些人脸在尺度,姿态,光照、表情、遮挡方面都有很大的变化范围Illumination  光照makeup 化妆
 wider_face_split.zip
    有mat和txt两个版本,还有readme
	  wider_face_train_bbx_gt.txt
	  wider_face_val_bbx_gt.txt
	  /wider_face_test_filelist.txt  
ReadMe
     blur:  blur:是模糊度,分三档:0,清晰;1:一般般;2:分不清
       clear->0
       normal blur->1
       heavy blur->2
     expression: 表情 正常和夸张
       typical expression->0
       exaggerate expression->1
     illumination:  曝光,分2档: 正常 过曝
       normal illumination->0
       extreme illumination->1
     occlusion:  遮挡,分三档。0,无遮挡;1,小遮挡;2,大遮挡
       no occlusion->0
       partial occlusion->1
       heavy occlusion->2
     pose:
       typical pose->0
       atypical pose->1
     invalid:
       false->0(valid image)
       true->1(invalid image)
     The format of txt ground truth.
         File name
         Number of bounding box
         x1, y1, w, h, blur, expression, illumination, invalid, occlusion,
数据说明
 第一行是文件夹,文件名
 第二行是图中人脸的数量
 再下面是人脸信息的参数  x1, y1, w, h, 代表人脸框的位置

文件目录

 YOLOV5
 ├── data
 │   ├── scripts
 │   ├   ├── download_weights.sh
 │   ├   ├── get_coco.sh
 │   ├── coco.yaml  
 │   ├── hyp.scratch.yaml   	 
 ├── models
 │   ├── common.py
 │   ├── experimental.py  yolov5的实验模块
 │   ├── activations.py   一些激活函数
 │   ├── yolo.py	      yolov5的模型搭建模块 
 │   ├── yolov5l.yaml  
 │   ├── tf.py	   
 ├── utils
 │   ├── augmentations.py
 │   ├── autoanchor.py
 │   ├── datasets.py       create_dataloader  关键核心是 LoadImagesAndLabels() 目标检测一般还需要重写collate_fn函数
 │   ├── general.py         通用工具类,写了一些通用的工具函数check
 │   ├── loss.py           yolov5的损失函数部分。-核心的地方
 │   ├── metrics.py        存放的是计算mAP、混淆矩阵、IOU相关的函数
 │   ├── plots.py          画图工具类
 │   ├── torch_utils.py   一些torch相关工具的使用。
 │   ├── google_utils.py  目前已改名为了downloads.py 下载所需的一些文件  safe_download和attempt_download。在train.py或者yolo.py等文件中都会用到
 │   ├── autobatch.py
 ├── export.py   模型的转换部分,将模型转换为torchscript、 onnx、coreml等格式	 
 ├── hubconf.py   torch.hub
 ├── train.py
 ├── val.py       在每一轮训练结束后,验证当前模型的mAP、混淆矩阵等指标
 ├── detect.py    一个检测(推理)脚本

说明

hyp.scratch.yaml
    训练相关参数
	损失函数相关参数
	其他几个参数
	数据增强相关参数
coco.yaml
   数据配置文件,存放着 数据集源路径root、训练集、验证集、测试集地址,类别个数,类别名,下载地址等信息

yolov5l.yaml .
   方便进行基于函数式的模块化开发,
    01.parameters 参数配置用于模型搭建 yolo.py(nc(number of classes)数据集类别个数) depth_multiple width_multiple
    02.anchors配置 初始化了 anchors,在三个Detect层使用(3个feature map)中使用,每个feature map的每个grid_cell都有三个anchor进行预测
       yolov5还有一个anchor进化的策略:autoanchor.py 使用k-means和遗传进化算法
    03.backbone 
	   args: 是一个list,模块搭建所需参数,channel,kernel_size,stride,padding,bias
	04.head
	    YOLOv5 head = PANet+Detect
	05.整体模型
yolo.py	
  parse_model模块用来解析模型文件(从Model中传来的字典形式),并搭建网络结构
  Detect模块是用来构建Detect层的,将输入feature map 通过一个卷积操作和公式计算到我们想要的shape,为后面的计算损失或者NMS作准备。
  Model 这个模块是整个模型的搭建模块。且yolov5的作者将这个模块的功能写的很全,不光包含模型的搭建,还扩展了很多功能
common.py 
 yolov5网络搭建常见Common模块 
    Focus  作者自己设计的一个模块,用在了模型的一开始,将输入图像先 slice 成4份,再做concat
   autopad 
   Conv  由卷积层 + BN层 + 激活函数 组成
   Bottleneck
   BottleneckCSP
   C3  简化版的BottleneckCSP,因为除了Bottleneck部分只有3个卷积,可以减少参数,所以取名C3
   SPP  了将更多不同分辨率的特征进行融合,得到更多的信息
   Concat
   注意力模块
   transformer自注意力模块
 experimental.py  yolov5的实验模块
   attempt_load 函数用于加载模型权重文件并构建模型(可以构造普通模型或者集成模型)。被广泛用于val.py、detect.py、train.py等文件中,用在测试、验证阶段。

步骤

1.数据预处理-
 01.原始数据   wider face训练集标签
   /Testface/WIDER_train/images
   /Testface/WIDER_val/images
   /Testface/wider_face_split/wider_face_train_bbx_gt.txt
    /Testface/wider_face_split/wider_face_val_bbx_gt.txt
	
	把 wider_face_train_bbx_gt 放在和 images 在同一的文件夹下
	    /Testface/widerface/train/images
		                                  wider_face_train_bbx_gt.txt
         /Testface/widerface/val/images
                                         wider_face_val_bbx_gt.txt
									 
 001.原始的数据 origin wider_face_train_bbx_gt.txt
    0--Parade/0_Parade_marchingband_1_849.jpg
    1
    449 330 122 149 0 0 0 0 0 0 
    0--Parade/0_Parade_Parade_0_904.jpg
    1
    361 98 263 339 0 0 0 0 0 0 
    0--Parade/0_Parade_marchingband_1_799.jpg
    21
    78 221 7 8 2 0 0 0 0 0 
    78 238 14 17 2 0 0 0 0 0 	
	
 002.修改为retinaface_gt的数据	-- wider face训练集标签转换为retinaface的标签格式
    # 0--Parade/0_Parade_marchingband_1_849.jpg
    449 330 122 149 488.906 373.643 0.0 542.089 376.442 0.0 515.031 412.83 0.0 485.174 425.893 0.0 538.357 431.491 0.0 0.82
    # 0--Parade/0_Parade_Parade_0_904.jpg
    361 98 263 339 424.143 251.656 0.0 547.134 232.571 0.0 494.121 325.875 0.0 453.83 368.286 0.0 561.978 342.839 0.0 0.89
    # 0--Parade/0_Parade_marchingband_1_799.jpg	
	
	目录格式
	     /Testface/widerface/train/images
		                                 label.txt
        /Testface/widerface/val/images
                                        label.txt
	
 003.修改为yolo的数据
   最终的输出
   save_path = '/Testface/widerface/train'
     /Testface/widerface/
	                  val/images/
					  val/labels/
	                  train/images/
	                  train/labels/
	Retinaface - 数据集的处理(WIDER FACE)
	 代码说明 "#"号开头的,便是图片的地址,将其放入img_path中
	       path = line[2:]  因为路径是从#空格开始# 0–Parade/0_Parade_marchingband_1_849.jpg

        结果是path="0–Parade/0_Parade_marchingband_1_849.jpg"
		path = txt_path.replace(‘label.txt’,‘images/’) + path

数据转换

import os
import sys

def widerface2retina(input_path,out_path):
    out_f = open(out_path,mode='w',encoding='utf8')
    with open(input_path,mode='r',encoding='utf8') as fin_obj:
        while True:
            line = fin_obj.readline()
            if not line:
                break
            out_f.write("# "+line)
            num = int(fin_obj.readline())
            if num == 0:
                num =1
            for i in range(num):
                line =  fin_obj.readline()
                values = [x for x in line.strip().split()]
                out_f.write(values[0]+' '+ values[1]+' '+ values[2]+' '+ values[3])
                out_f.write(' -1.0'*16)
                out_f.write('\n')
    out_f.close()

if __name__ == '__main__':
    train_path = r"/Testface/widerface/train/wider_face_train_bbx_gt.txt"
    retina_path = r"/Testface/widerface/train/label.txt"
    widerface2retina(train_path,retina_path)

修改成yolo的数据格式

修改 python3 train2yolo.py 中的地址

训练

 vim  /Testface/usedface/widerface
train_path = data_dict['train']
test_path = data_dict['val']

 /opt/yolov5-face-master/
python3 train.py --data data/widerface.yaml --cfg models/yolov5s.yaml --weights '/opt/yolov5-face-master/weights/yolov5s.pt'
###代码
yolov5/detect.py  
yolov5-face/detect_face.py  
License-Plate-Detector/detect_plate.py 

查看执行情况
   nvidia-smi

参考:

 https://github.com/ultralytics/yolov5/blob/master/detect.py
 https://github.com/deepcam-cn/yolov5-face/blob/master/detect_face.py
 https://github.com/zeusees/License-Plate-Detector/blob/master/detect_plate.py
 YOLOv5.yaml文件 & 超参详细介绍  https://blog.csdn.net/weixin_42410915/article/details/118785807?spm=1001.2014.3001.5501
  【YOLOV5-5.x 源码解读】yolov5s.yaml https://blog.csdn.net/qq_38253797/article/details/119754854
  CSDN源码讲解导航 https://github.com/SCAU-HuKai/yolov5-5.x-annotations
  https://netron.app/
  【YOLOV5-5.x 源码解读】datasets.py https://blog.csdn.net/qq_38253797/article/details/119904518
  Widerface数据集 | 用YOLOV5训练widerface数据集  https://blog.csdn.net/mary_0830/article/details/116600832
  widerface2retina 标签格式转换 https://blog.csdn.net/xiakejiang/article/details/100664973
原文地址:https://www.cnblogs.com/ytwang/p/15802707.html