Bootstrap

YoLov3训练自己的数据集

转自https://blog.csdn.net/weixin_42731241/article/details/81352013

工具:labelimg、MobaXterm

1.标注自己的数据集。用labelimg进行标注,保存后会生成与所标注图片文件名相同的xml文件,如图。我们标注的是各种表,名称就简单的按外观大小分了s、m、l、xl、xxl共5类标签名

2.下载yolov3项目工程。按照YoLo官网下载


 
 
  1. git clone https: //github.com/pjreddie/darknet
  2. cd darknet
  3. make

3.修改Makefile文件(文件就在下载的darknet文件夹内)

vi Makefile  #打开文件

 
 

 
 
  1. GPU= 1 #使用GPU训练,其他的没有用,所以没有置为1,可根据自己的需要调整
  2. CUDNN= 0
  3. OPENCV= 0
  4. OPENMP= 0
  5. DEBUG= 0
make  #保存并退出后,进行make才可生效,如果出现错误,自行百度(因为我们的大神帮忙修复了)
 
 

3.准备数据集。在scripts文件夹下创建文件夹VOCdevkit(因为scripts文件夹下有vov_label.py文件,它的作用下面会说,下面创建的文件也跟它有关),根据下图在VOCdevkit文件夹下创建文件,并放入相应的数据


 
 
  1. VOCdevkit
  2. —— VOC2018 #文件夹的年份可以自己取,但是要与你其他文件年份一致,看下一步就明白了
  3. ———— Annotations #放入所有的 xml文件
  4. ———— ImageSets
  5. —————— Main #放入 train .txt, val .txt文件
  6. ———— JPEGImages #放入所有的图片文件
  7. Main中的文件分别表示 test .txt是测试集, train .txt是训练集, val .txt是验证集, trainval .txt是训练和验证集,反正我只建了两个

        创建后的样子如下图

       

        其中Main中的txt文件是要写文件名,比如train.txt里写的是用来训练的图片的文件名(不包含后缀,只是文件名哦!!!),这个文件可以找代码生成(下面的python代码可以用),代码的话看懂他的作用,特别的文件的路径之类的,根据自己的情况修改下,就可以用


 
 
  1. import os
  2. from os import listdir, getcwd
  3. from os.path import join
  4. if __name__ == '__main__':
  5. source_folder= '/home/darknet/scripts/VOCdevkit/VOC2018/JPEGImages/'
  6. dest= '/home/darknet/scripts/VOCdevkit/VOC2018/ImageSets/Main/train.txt'
  7. dest2= '/home/darknet/scripts/VOCdevkit/VOC2018/ImageSets/Main/val.txt'
  8. file_list=os.listdir(source_folder)
  9. train_file=open(dest, 'a')
  10. val_file=open(dest2, 'a')
  11. for file_obj in file_list:
  12. file_path=os.path. join(source_folder,file_obj)
  13. file_name,file_extend=os.path.splitext(file_obj)
  14. file_num=int(file_name)
  15. if(file_num< 776):
  16. train_file.write(file_name+ '\n')
  17. else :
  18. val_file.write(file_name+ '\n')
  19. train_file.close()
  20. val_file.close()

5.修改voc_label.py,这个文件就是根据Main中txt里的文件名,生成相应的txt,里面存放的是它们的路径


 
 
  1. sets=[( '2018', 'train'), ( '2018', 'val')] #这里要与Main中的txt文件一致
  2. classes = [ "s", "m", "l", "xl", "xxl"] #你所标注的表签名,第一步中已经说过
  3. os.system( "cat 2018_train.txt 2018_val.txt > train.txt") #文件最后一句,意思是要将生成的文件合并,所以很据需要修改,这里的年份都是一致的,简单理解下代码应该会懂,不要盲目修改
python voc_label.py    #保存后运行
 
 

运行后会生成2018_train.txt、2018_val.txt、train.txt,如图

          

6.下载Imagenet上预先训练的权重

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

7.修改cfg/voc.data


 
 
  1. classes= 5 #classes为训练样本集的类别总数,第一步中说了我分了5类标签
  2. train = /darknet/scripts/ 2018_train.txt #train的路径为训练样本集所在的路径,上一步中生成
  3. valid = /darknet/scripts/ 2018_val.txt #valid的路径为验证样本集所在的路径,上一步中生成
  4. names = data/voc.names #names的路径为data/voc.names文件所在的路径
  5. backup = backup

8.修改data/voc.name


 
 
  1. s
  2. m
  3. l
  4. xl
  5. xxl
  6. #修改为自己样本集的标签名即第一步中标注的标签名

9.修改cfg/yolov3-voc.cfg


 
 
  1. [ net]
  2. # Testing
  3. # batch=1 #这里的batch跟subdivisions原来不是注释掉的,但是训练后没成功,有的blog上说为1的时候太小难以收敛,但是不知道下面训练模式的 batch=64 subdivisions=8 会不会覆盖掉,总之注释掉后就成功了,不过这个脚本不是很明白,还来不及验证
  4. # subdivisions=1
  5. # Training
  6.  batch= 64
  7.  subdivisions= 8
  8. ......
  9. [ convolutional]
  10. size= 1
  11. stride= 1
  12. pad= 1
  13. filters= 30 #---------------修改为3*(classes+5)即3*(5+5)=30
  14. activation=linear
  15. [ yolo]
  16. mask = 6, 7, 8
  17. anchors = 10, 13,   16, 30,   33, 23,   30, 61,   62, 45,   59, 119,   116, 90,   156, 198,   373, 326
  18. classes= 5 #---------------修改为标签类别个数,5类
  19. num= 9
  20. jitter= .3
  21. ignore_thresh = .5
  22. truth_thresh = 1
  23. random= 0 #1,如果显存很小,将random设置为0,关闭多尺度训练;(转自别的blog,还不太明白)
  24. ......
  25. [ convolutional]
  26. size= 1
  27. stride= 1
  28. pad= 1
  29. filters= 30 #---------------修改同上
  30. activation=linear
  31. [ yolo]
  32. mask = 3, 4, 5
  33. anchors = 10, 13,   16, 30,   33, 23,   30, 61,   62, 45,   59, 119,   116, 90,   156, 198,   373, 326
  34. classes= 5 #---------------修改同上
  35. num= 9
  36. jitter= .3
  37. ignore_thresh = .5
  38. truth_thresh = 1
  39. random= 0
  40. ......
  41. [ convolutional]
  42. size= 1
  43. stride= 1
  44. pad= 1
  45. filters= 30 #---------------修改同上
  46. activation=linear
  47. [ yolo]
  48. mask = 0, 1, 2
  49. anchors = 10, 13,   16, 30,   33, 23,   30, 61,   62, 45,   59, 119,   116, 90,   156, 198,   373, 326
  50. classes= 5 #---------------修改同上
  51. num= 9
  52. jitter= .3
  53. ignore_thresh = .5
  54. truth_thresh = 1
  55. random= 0

10.开始训练


 
 
  1. ./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg scripts/darknet53.conv .74 -gpus 0, 1
  2. #注意文件路径

11.测试识别。训练后会在backup文件夹下生成权重文件,利用生成的权重文件进行测试

./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_600.weights data/210.jpg

 
 

   训练结果,如下图,训练次数不是很多,数据集也不是很大,所以结果还没有很准确。因为运行的服务器散发的热量在这个燥热的夏季让我宛若置身汗蒸馆,纵使养生大师们都宣称这种方式可以排除体内毒素,让你延年益寿,但我还是觉得这样下去大概会中暑,毕竟午后的阳光还时不时透过玻璃悄悄爬上我的桌子,顶楼的天花板一整天都在沐浴阳光也会让温暖包围着我,偶尔冲出这个暖和的地方奔向空调感受凉爽,结果在这冷热交替中感冒还是不请自来

 

以上对于一些文件的理解也是多次失败的收获,可能并不全对,有误请指正,遇到问题也可以交流。

遇到的问题:

训练完后进行测试,测试出来的结果标签名不是data/voc.name里面写的,而是修改之前的person、dog。。。巴拉巴拉的东西

问题解决:

测试命令路径有误,具体原因见(第四部分:测试问题(1)bounding box正确,标签错乱


 
 
  1. #失败
  2. ./darknet detect cfg/yolov3-voc.cfg backup/yolov3-voc_600.weights data/210.jpg
  3. #成功
  4. ./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_600.weights data/210.jpg

 

;