以下都是基于yolo v2版本的,对于现在的v3版本,可以先clone下来,再git checkout回v2版本。
玩了三四个月的yolo后发现数值相当不稳定,yolo只能用来小打小闹了。
v2训练的权重用v3做预测,结果不一样。
我的环境是 window 10 + cuda9.0 + opencv 3.4.0 + VS2015
先在这个地方下源文件:https://github.com/AlexeyAB/darknet
下好后,先打开用文本编辑器打开 darknet.vcxproj,将两处 cuda9.1 改成 cuda9.0
还要拷贝opencv的两个dll到 x64 下
用 VS2015 打开 darknet.sln,生成一下,在 darknet-master\build\darknet\x64 下面得到一个 darknet.exe
这个时候已经可以用 训练好的模型 对 训练时的类别 做预测了
当然,要预先下好对应的 weights 文件
darknet.exe detector test cfg/combine9k.data yolo9000.cfg yolo9000.weights data/dog.jpg
先准备好训练图片!
一定要先做好文件重命名工作!不然后面想添加、修改、删减样本都很痛苦。
然后再用 windows 版的 labelImg 做标注
然后修改相关配置文件,然后就可以开始训练了。
训练前下好一个 darknet19_448.conv.23 文件
训练命令如下
darknet.exe detector train cfg/voc.data cfg/yolo-voc.cfg cfg/darknet19_448.conv.23
要准备好.data 和 .cfg 文件 以及 训练数据集
训练时如果说找不到 txt 文件,直接把 txt 文件拷贝到image文件夹下
最后会得到一个自己的 weights 文件可以用来预测自己的类别
2018年8月24日08:58:19
总结一个比较完整的流程出来,大致有以下几个步骤:
1,不停的图片采集,以及不停的对新采集的图片重命名。
因为采集到的图片名称可能是以秒命名的,也有可能是按日期命名的,或者有其他命名规范。
后续标注和训练完测试的时候,如果发现某些样本图片不理想要剔除或跳过的时候,名字不易找就比较麻烦。
2,图片标注的技巧,实际标注的xml数量是少于采集到的图片数量的,因为有些图片拍的角度或光照不理想。
3,离线数据增强
yolo本身有一些在线的数据增强,然而没有深入阅读过代码的话很难改的动,而且提供的增强手段有限。所以做了个
简单的离线数据增强。
4,训练数据预处理,修改cfg文件等。
5,训练和测试
6,在opencv中调用,C++和python两种版本。以及批量抠图。
=====================================================
1,重命名 rename.py
1 import os 2 3 def getFilenames(filepath): 4 ''' 5 得到一个文件夹下所有的文件名,不包含后缀, 忽略文件夹 6 ''' 7 filenames = [] 8 9 for file in os.listdir(filepath): 10 pt = os.path.join(filepath, file) 11 12 if( os.path.isfile(pt) ): 13 filename = os.path.splitext(file)[0] 14 filenames.append(filename) 15 return filenames 16 17 filepath = "origin_img" 18 filenames = getFilenames(filepath) 19 print(filenames) 20 21 22 # 只对文件夹中新增加的图片重命名,增量式重命名。所以要取得图片文件名中最大的数字 23 def get_max_num(filenames): 24 max_num = 0 25 26 for name in filenames: 27 if( name.isdigit() and int(name) < 10000): 28 if(int(name) > max_num): 29 max_num = int(name) 30 31 return max_num 32 33 print("max num:", get_max_num(filenames)) 34 35 renameCount = get_max_num(filenames)+1 36 37 #renameCount = 1 38 39 for file in os.listdir(filepath): 40 if( os.path.isfile( os.path.join(filepath, file) ) ): # 如果是文件 41 filename = os.path.splitext(file)[0] # 取得文件名 42 43 if( not filename.isdigit() ): # 如果文件名不是数字,则重命名 44 print("rename count 1:", renameCount) 45 os.rename(os.path.join(filepath, file), os.path.join(filepath, str('%03d'%renameCount)+".jpeg")) 46 renameCount+=1 47 48 if( filename.isdigit() and int(filename) > 10000 ): 49 print("rename count 2:", renameCount) 50 os.rename(os.path.join(filepath, file), os.path.join(filepath, str('%03d'%renameCount)+".jpeg")) 51 renameCount+=1