YOLOv3训练自己的数据(附优化与问题总结)

YOLOv3训练自己的数据附优化与问题总结

环境说明

  1. 系统:ubuntu16.04

  2. 显卡:Tesla k80 12G显存

  3. python环境: 2.7 && 3.6

  4. 前提条件:cuda9.0 cudnn7.0 opencv3.4.0

实现YOLOV3的demo

  1. 首先安装darknet框架官网链接

    git clone https://github.com/pjreddie/darknet.git
    cd darknet
    vim  Makefile
    
    • 根据情况修改Makefile,如果使用GPU、cudnn和opencv,就将其标志位改成1。

    • 编译

      make
      
    • 编译完成,测试一下

      ./darknet
      

      应该会出现以下信息

      usage: ./darknet <function>
      

      如果有使用opencv,则可以测试下检测用例,会出现很多老鹰的图片说明darknet的安装odk了

      ./darknet imtest data/eagle.jpg
      
  2. 使用yolov3预训练模型检测物体

    • 首先获取模型权重

      wget https://pjreddie.com/media/files/yolov3.weights
      
    • 然后运行目标检测

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

      这边运行的时候很可能出现的一个问题就是,没有出现bbox

      原因

      如果GPU = 1或CUDNN = 1,darknet将为每个层预先分配GPU虚拟内存,这取决于cfg文件中的批量大小和子分区设置。
      对于训练,批量大小表示将在迭代中对GPU执行多少图片,更大的值可以减少训练时间,并且如果GPU在迭代中没有足够的内存,则子划分可以将它们分组以防止存储器大小限制问题。
      保持1检测,因为这些设置主要用于训练网络。

      参考:

      https://github.com/pjreddie/darknet/issues/405

      https://github.com/pjreddie/darknet/issues/405

      解决方法:

      (1)检测的时候令cudnn=0,

      (2)修改cfg文件成batch=1,sub=1

命令简介

先举个例子

./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg

darknet :一个可执行的程序,类似win下的exe

detector:是一个第一个参数,执行detector.c

test:detector.c里面的一个函数test_detector(),用来测试图片

cfg/coco.data:"cfg/"是训练的配置文件所在路径,coco.data是.data配置文件名

cfg/yolov3.cfg:"cfg/"是训练的配置文件所在路径,yolov3.cfg是.cfg配置文件名

yolov3.weights:训练好的模型,yolov3.weights在darknet根目录

data/dog.jpg:“data/”是要测试图片所在路径,dog.jpg是测试图片文件名

  1. 测试

    • 测试图片

      指令格式

      ./darknet detector test <data_cfg> <test_cfg> <yolo_weights> <image_file>(可选)
      

      如果没有指定 <image_file> 就可以像这样测试多张图片

      <test_cfg>文件中batch和subdivisions两项须为1或者测试时不使用cudnn

      测试时还可以用-thresh调整置信度阈值 ,例如只显示置信度在60%以上的 bbox

      ./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg  -thresh .6
      
    • 检测视频,需要用到demo函数(src/demo.c)

      ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights test.avi
      
    • 在摄像头上测试,需要用到demo函数

      ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights
      
  2. 训练模型

    指令格式

    ./darknet -i <gpu_id> detector train <data_cfg> <train_cfg> <yolo_weights>
    
    • 单GPU训练

      ./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74
      
    • 更换GPU训练

      ./darknet detector -i 2 train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74
      
    • 多GPU训练

      ./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 -gpus 0,1,2,3
      
    • CPU训练

      ./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 --nogpu
      
  3. 模型评估recall,生成测试结果

    • 生成测试结果

      ./darknet detector valid <data_cfg> <test_cfg> <yolo_weights> <out_file>
      

      (1)<test_cfg>文件中batch和subdivisions两项需为1。
      (2)测试结果生成在<data_cfg>的results指定的目录下以<out_file>开头的若干文件中,若<data_cfg>没有指定results,那么默认为darknet/results。

    • 计算recall(需要修改detectocr.c请参考第五部分优化与个性化——计算map与recall)

      ./darknet detector recall <data_cfg> <test_cfg> <weights>
      

      (1)<test_cfg>文件中batch和subdivisions两项需为1
      (2)RPs/Img、IOU、Recall都是到当前测试图片的均值(意义待续)

训练自己的数据

  1. 首先下载预训练卷积权重

    wget https://pjreddie.com/media/files/darknet53.conv.74
    
  2. 其次标注数据集,生成yolo所需要的txt格式的labels

    • 推荐使用yolo_mark数据集标注工具,可以直接生成txt

    • 下载yolo_mark

      git clone https://github.com/AlexeyAB/Yolo_mark.git
      
    • 要在Linux上编译,输入:

      cd Yolo_mark
      cmake .
      make
      chmod +x linux_mark.sh
      ./linux_mark.sh
      
    • 打开yolo_mark就是GUI的标注了,主要是修改data和names,具体请参考官网

  3. 修改配置文件

    • 修改.data文件

      classes= 4 (修改成自己训练的种类数)
      train  = /home/user_name/darknet/data/train.txt   (修改成自己train.txt的路径)
      valid  = /home/user_name/darknet/data/2007_test.txt (评估测试的图片的路径,用于后面的评估测试)
      names = data/voc.names                                  (修改成自己的类别名的路径)
      backup = backup                                         (训练的权重所存放的路径)
      results = results                            (评估测试结果存放路径,也可以自己定义)
      
    • 修改.names这个比较简单,修改自己的类别就可以

      例如我的文件是yolov3.names

    • 修改.cfg文件

    • 关于cfg修改,以4类目标检测为例,主要有以下几处调整(蓝色标出),#表示注释,根据训练和测试,自行修改,修改说明:

      A:filters的计算和聚类数目分布有关

      yolov3:filters=(classes + 5)x3

      yolov2: filters=(classes + 5)x5。

      B.classes就是类别数量

      C.如果想修改默认anchors数值,可以使用k-means;

      D.如果显存够大,则可以开启多尺度训练令random=1,不过loss会有点震荡;

      给出一份我的cfg以供参考,传送门

      [net]
      #Testing
      #batch=1
      #subdivisions=1
      #Training

      batch=64

      subdivisions=8

      [convolutional]
      size=1
      stride=1
      pad=1

      filters=27###75

      activation=linear

      [yolo]
      mask = 6,7,8
      anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
      classes=4###20
      num=9
      jitter=.3
      ignore_thresh = .5
      truth_thresh = 1
      random=0###1

      [convolutional]
      size=1
      stride=1
      pad=1
      filters=27###75
      activation=linear

      [yolo]
      mask = 3,4,5
      anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
      classes=4###20
      num=9
      jitter=.3
      ignore_thresh = .5
      truth_thresh = 1
      random=0###1

      [convolutional]
      size=1
      stride=1
      pad=1
      filters=27###75
      activation=linear

      [yolo]
      mask = 0,1,2
      anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
      classes=4###20
      num=9
      jitter=.3
      ignore_thresh = .5
      truth_thresh = 1
      random=0###1

    • 给一份标注好的数据集,有需要的可以参考目录和格式.百度网盘戳我
      提取码: j1zi

  4. 开始训练

    ./darknet detector train cfg/yolov3.data cfg/yolov3.cfg  darknet53.conv.74
    

    avg:平均loss,越小越好,

    rate:学习率,默认为0.001,可以根据自己的训练情况调整,一般为0.01,0.003,0.001等

    训练参数说明

    Region xx: cfg文件中yolo-layer的索引,82是大物体层,94是中物体层,106小物体层;

    Avg IOU: 当前迭代中,预测的box与标注的box的平均交并比,越大越好,期望数值为1;

    Class: 标注物体的分类准确率,越大越好,期望数值为1;

    obj: 越大越好,期望数值为1;

    No obj: 越小越好;

    .5R: 以IOU=0.5为阈值时候的recall; recall = 检出的正样本/实际的正样本

    0.75R: 以IOU=0.75为阈值时候的recall;

    count: 正样本数目。

优化与个性化问题

这边的更改之后都需要make clean后再make。如果改了之后发现没变化,请第一时间看看是不是没有执行这一步。

  1. 什么时候保存模型,又要如何更改呢?

    迭代次数小于1000时,每100次保存一次,大于1000时,每10000次保存一次。

    自己可以根据需求进行更改,然后重新编译即可[ 先 make clean ,然后再 make]

    代码位置: examples/detector.c line 138

  2. 如何在图像上添加置信度?

    可以看github的修改记录,也可以看下面的修改,修改传送门

    修改src/image.c文件draw_detections()函数,代码修改如下:

    int i,j;
     
        for(i = 0; i < num; ++i){
         
            char labelstr[4096] = {
         0};
    		char s1[]={
         "  "};//为了name与置信度之间加空格
            int class = -1;
    	    char possible[5];//存放检测的置信值
            for(j = 0; j < classes; ++j){
         
    	    sprintf(possible,"%.2f",dets[i].prob[j]);//置信值截取小数点后两位赋给possible
                if (dets[i].prob[j] > thresh){
         
                    
  • 37
    点赞
  • 195
    收藏
    觉得还不错? 一键收藏
  • 34
    评论
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值