基于darknet的voc数据集训练和mAP测试

文章目录

0. darknet介绍

1. 框架结构

2. 安装

2.1 下载

2.2 修改Makefile配置文件

 2.3 编译

2.4 下载yolov3的预训练模型权重

2.5  测试是否安装成功

3. voc数据集训练,测试

3.1 准备voc数据集

3.2 将数据转换成darknet支持的格式

3.3 修改darknet/cfg下的voc.data,yolov3-voc.cfg和data/voc.names文件

3.4 下载darknet-53的预训练权重文件

3.5 开始训练

4. mAP测试

4.1 通过detector valid命令生成测试数据

4.2 使用darknet_voc_mAP测试mAP

4.3 分析compute_mAP.py文件内容

 参考链接



0. darknet介绍

Darknet是一个用C和CUDA编写的开源神经网络框架。它快速,易于安装,并支持CPU和GPU计算。

链接:https://github.com/pjreddie/darknet

1. 框架结构

 基于darknet的voc数据集训练和mAP测试_第1张图片

2. 安装

2.1 下载

git clone https://github.com/pjreddie/darknet
cd darknet

2.2 修改Makefile配置文件

GPU=1 #如果使用GPU设置为1,CPU设置为0
CUDNN=1  #如果使用CUDNN设置为1,否则为0
OPENCV=0 #如果调用摄像头,还需要设置OPENCV为1,否则为0
OPENMP=0  #如果使用OPENMP设置为1,否则为0
DEBUG=0  #如果使用DEBUG设置为1,否则为0
# 指定nvcc路径
NVCC = /usr/local/cuda-9.0/bin/nvcc

 2.3 编译

make

 可能存在的错误

 ./darknet: error while loading shared libraries: libcudart.so.10.0: cannot

解决方案:

sudo ldconfig /usr/local/cuda-9.0/lib64

2.4 下载yolov3的预训练模型权重

mkdir weights        # 将预训练权重保存到该目录下
wget https://pjreddie.com/media/files/yolov3.weights

2.5  测试是否安装成功

./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

 其中参数含义如下:

1. 网络配置文件

2. 预训练模型权重

3. 测试图像

 测试完成后会打印如下信息以及在根目录下生成一个prediciton.jpg文件为输出结果。

Loading weights from weights/yolov3.weights...Done!
data/dog.jpg: Predicted in 0.031283 seconds.
dog: 100%
truck: 92%
bicycle: 99%

 

基于darknet的voc数据集训练和mAP测试_第2张图片


3. voc数据集训练,测试

3.1 准备voc数据集

数据集的结构如下,我把数据集Vocdevkit目录放到了scripts文件夹下

VOC2007

           Annotaitons # 标记xml文件

          ImageSets/Main # 训练,测试数据集txt文件

          JPEGImages # 图像文件

3.2 将数据转换成darknet支持的格式

yolov3提供了将voc数据集转为yolo训练所需要的格式脚本

python scripts/voc_label.py

经过上述脚本,在scripts文件夹下会生成几个txt文件,其中包含的是图像的路径

  • 2007_test.txt          # voc2007测试集
  • 2007_train.txt        # voc2007训练集
  • 2007_val.txt          # voc2007验证集
  • 2012_train.txt       # voc2012训练集
  • 2012_val.txt         # voc2012测试集
  • train.txt               # voc2007+voc2012的训练集
  • train.all.txt          # 所有样本集

3.3 修改darknet/cfg下的voc.data,yolov3-voc.cfg和data/voc.names文件

如下是voc.data文件的内容,根据自己实际情况修改即可

classes= 20 # 类别总数

train = /home/xxx/darknet/scripts/train.txt # 训练集样本txt文件

valid = /home/xxx/darknet/scripts/2007_test.txt # 验证集样本txt文件

names = data/voc.names # 类别名称

backup = backup # 权重保存路径

yolov3-voc.cfg的文件默认不修改,如需修改请参考其他

voc.names文件中包含的是数据集的类别,对于voc数据集的类别如下,总共20类:

aeroplane
bicycle
bird
boat
bottle
bus
car
cat
chair
cow
diningtable
dog
horse
motorbike
person
pottedplant
sheep
sofa
train
tvmonitor

3.4 下载darknet-53的预训练权重文件

wget https://pjreddie.com/media/files/darknet53.conv.74

 

3.5 开始训练

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 -gups 0,1,2,3

 

4. mAP测试

4.1 通过detector valid命令生成测试数据

mkdir results   # 测试结果保存路径
./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights -out "" -gpu 0 -thresh .5

其中:-thresh为IOU阈值可以根据实际情况调节

通过上面命令在results文件夹下就可以得到不同类别的测试结果文件

4.2 使用darknet_voc_mAP测试mAP

darknet_voc_mAP是我自己写的一个用于测试基于darknet训练voc格式数据集mAP的项目。项目结构如下:

基于darknet的voc数据集训练和mAP测试_第3张图片

上述文件夹中重点是input文件夹,里面包含了如下一些文件夹:

  • detection-results                  # 来源4.1的测试数据
  • ground-truth                         # voc的测试集xml文件
  • images-optional                   # 如果gt的bounding box的坐标存在归一化需要测试集的images
  • test.txt                                 # 测试集的文件序号

使用方法,即将4.1得到的预测数据放到detection-results路径下,voc的测试集的xml文件放到ground-truth文件夹下,将数据集中ImageSets/Main文件夹下的test.txt放到input文件夹下,然后运行如下命令,即可得到mAP.

python3 compute_mAP.py

输出结果大致如下:

aeroplane :      0.8878980127914309 
bicycle :        0.8618205446114344 
bird :   0.7480539480998687 
boat :   0.7048997455770187 
bottle :         0.6794095545317449 
bus :    0.8635922538078116 
car :    0.8899740616851775 
cat :    0.8743744101970683
chair :  0.5987828351364424
cow :    0.866211540175532
diningtable :    0.7244442845069334
dog :    0.8581894889390733
horse :  0.8902089938157063
motorbike :      0.8571526878469593
person :         0.8404120889508571
pottedplant :    0.5042149724691987
sheep :  0.8150808201092643
sofa :   0.7711258567989381
train :  0.8566713335712046
tvmonitor :      0.7672438110465113
***************************
mAP :    0.7929880622334087

4.3 分析compute_mAP.py文件内容

该代码里面提供了两个额外的功能:

# 针对coco数据集训练测试mAP
# 1. coco数据集提供的gt数据中bounding box是经过归一化的所以需要反归一化,这里需要测试集的images数据          # scripts/coco2voc.py
# 2. 就是生成xml格式的文件                                                                                                                                                 # scripts/xml_maker.py

# 在detector valid生成测试数据时,没有指定-out参数会生成comp4_det_类别.txt的文件所以需要重命名一下测试数据

from voc_eval import voc_eval
import os

# 获取当前文件的路径
current_path = os.getcwd()
# 下面这块代码主要是针对coco数据集训练测试mAP
# 1. coco数据集提供的gt数据中bounding box是经过归一化的所以需要反归一化,这里需要测试集的images数据
# 2. 就是生成xml格式的文件

# --------------- 处理coco格式的ground-truth文件 ------------------
# 0. ground-truth的绝对路径
gt_path = os.path.join(current_path, "input", "ground-truth")
# image文件夹绝对路径
images_path = os.path.join(current_path, "input", "images-optional")
# 1. 判断文件格式
gt_files = os.listdir(gt_path)
if gt_files[0].endswith("txt"):
    print("the ground truth is in coco format, need to convert to voc format!\n")
    # coco转voc需要保证image文件存在
    try:
        # 2. 将coco格式的gt转换成voc格式
        from scripts.coco2voc import convert2voc
        import shutil
        gt_coco = os.path.join(current_path, "input", "ground-truth-coco")
        gt_voc = os.path.join(current_path,  "input", "ground-truth-voc")
        # 新建文件夹
        os.mkdir(gt_coco)
        os.mkdir(gt_voc)
        
        for file in gt_files:
            # 将coco的数据移动coco的文件夹中
            shutil.move(os.path.join(gt_path, file), os.path.join(gt_coco, file))
            prefix_fileName = file.split(".")[0]
            img_path = os.path.join(images_path, prefix_fileName+".jpg")
            coco_path = os.path.join(gt_coco, file)
            voc_path = os.path.join(gt_voc, prefix_fileName+".txt")
            # convert
            convert2voc(img_path=img_path, txt_path=coco_path, out_path=voc_path)
       
    except Exception:
        print("please confirm image file !!\n")
    # 3. 将voc格式的gt转换成xml的表现形式
    from scripts.xml_maker import maker
    maker(img_dir=images_path, label_dir=gt_voc, out_dir=gt_path)


# ----------------------------------------------------------------------
# 生成测试集文件
test_path = os.path.join(current_path, "input", "test.txt")
with open(test_path, "w", encoding="utf-8") as f:
    for file in os.listdir(gt_path):
        raw = file.strip().split(".")[0]
        f.write(raw + "\n")
       
# -----------------------------------------------------------------


# 预测结果绝对路径
results_path = os.path.join(current_path, "input", "detection-results")
sub_files = os.listdir(results_path)

# ------------------- 处理darknet的预测文件 ----------------
# 判断是否存在字符“_”从而修改文件的命名
for idx, fileName in enumerate(sub_files):
    if "_" in fileName:
        print("change the ground-truth filename ...")
        replaceName = fileName.strip().split("_")[-1]
        # 重命名
        sub_files[idx] = replaceName
        os.rename(os.path.join(results_path, fileName), os.path.join(results_path, replaceName))

# ---------------------------------------------------------

# --------------------- mAP测试 -------------------------
mAP = []
for i in range(len(sub_files)):
    class_name = sub_files[i].split(".txt")[0]
    rec, prec, ap = voc_eval('./input/detection-results/{}.txt',
                             './input/ground-truth/{}.xml',
                             './input/test.txt',
                             class_name,
                             './input/cache')
    print("{} :\t {} ".format(class_name, ap))
    mAP.append(ap)

mAP = tuple(mAP)

print("***************************")
print("mAP :\t {}".format(float(sum(mAP) / len(mAP))))

# ----------------------------------------------------------------

项目分享链接:链接:https://pan.baidu.com/s/1PcaPBwQz3cpLQs2I7EYEYQ 
提取码:8ych 
请记得解压input文件夹下的ground-truth压缩包,因为百度云上传有文件个数限制!!!

 参考链接

  • YOLOv3 mAP计算教程

  • darknet整体框架

你可能感兴趣的:(#,darknet,python,神经网络)