Yolo训练自己的数据集
1 | config: |
错误递归逐渐忘记要干嘛。。。
yolo训练时间
1 | // cpu yolov3 |
一、数据集预准备
VOC数据集目录结构如下:
1 | ├──VOC2019 |
1.1 Annotations
存放VOC格式的xml文件,每一个xml对应一张图像,并且每个xml中存放的是标记的各个目标的位置和类别信息,命名通常与对应的原始图像一样
1.2 ImageSets
ImageSets我们只需要用到Main文件夹,这里面存放的是一些文本文件,通常为train.txt、test.txt等,该文本文件里面的内容是需要用来训练或测试的图像的名字(无后缀无路径)
1.3 JPEGImages
JPEGImages文件夹中放我们已按统一规则命名好的原始图像。
以此次我收集的关于泡面的数据集为例
数据来源:百度、京东、个人拍摄
1 | ├── JPEGImages |
图片命名格式为<label_name><num(len=5)>.jpg
,例如:LR00001.jpg
1.3.1 voc_spider.py
可以直接编译,爬取的图片存储在当前目录下。图片命名格式为<label_name><num(len=5)>.jpg
,例如:LR00001.jpg
。
1.3.2 resize_pic.py
放缩图片大小,因为网络需要图片归一化,默认是处理成正方形的大小所以只需要输入一个数字,处理所在目录下的所有图片(递归式)。需要的图片尺寸大小应与yolo.cfg
中的大小一致。
1 | # yolov2.cfg |
1.3.3 rename_voc.py
寻找文件夹下命名为class_<label_name>
的文件并根据序号重命名。这个主要是针对自己拍摄的照片进行处理时需要统一命名。
1.4 Conclusion
VOC数据集构建推荐步骤:
- 建立文件夹,目录结构如上述,建议命名为VOC+year,这样之后可以直接使用提供的
voc_label.py
。 JPEGImages
下建立每个类的文件夹,我主要是为了方便区分,也不可以不分。- 使用上述的py文件获取图片
- 最终所有图片都在
JPEGImages
文件夹下,不再另外区分。建议先做好这步!不然后期的xml文件夹还需要改动路径,不麻烦但是还是多了几步工作。
二、标记图像目标区域
跑opencv,报错了。。
1 | xxxdeMacBook-Pro:main xxx$ python |
看了一下自己并没有安装 ffmpeg
1 | xxxdeMacBook-Pro:main xxx$ brew install ffmpeg |
我吹爆brew!原来尝试源码安装疯狂报错。。。
opencv能import了,然后numpy又报错了😭😭😭
1 | xxxdeMacBook-Pro:main xxx$ python |
看了一下自己文件里的numpy
,发现在python3.7
下import
是没有任何毛病的!干脆就把/usr/local/lib/python2.7/site-pacages/
下的numpy
删了,再测试了一下,ojbk👌
fine,我很ok的,我配环境配两天了,佛了,被环境工程劝退,又是头秃的一天啊!😃😃😃
推测一下出现这么多错可能是因为我同时存在了多个python的版本,有的包可能同时存在几个版本,容易冲突,这个标记的demo是在python2.7
的环境下跑的,所以这些包我都尽量装在python2.7/site-pacages
目录下,使用pip指定目录安装
1 | pip install --target=<target_path> <pacakages> |
新的错,来自lxml
,无法import etree
,然鹅!python3.6
下跑没有任何毛病= =
1 | xxxdeMacBook-Pro:main xxx$ python |
注意:出错还有另外的可能是你的Python项目中有名称为lxml的文件(夹),就有可能导致这种错误。这种情况的话,把项目中对应的文件名称修改即可
曲线救国了
找到了另一个labelImg
,好了!完美!
git:labelImg的git地址
1 | install lableImg in Mac OS X 10.14 |
以下是xml的标准格式:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<annotation>
<folder>JPEGImages</folder>
<filename>LR00001.jpg</filename>
<path>/home/mei/Desktop/cv/darknet/scripts/VOCdevkit/NOODLE2019/JPEGImages/LR00001.jpg</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>608</width>
<height>608</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>luxiang</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>393</xmin>
<ymin>304</ymin>
<xmax>583</xmax>
<ymax>465</ymax>
</bndbox>
</object>
</annotation>
可能需要更改的地方:
folder
folder为最终跑模型的时候图片的放置位置。该命令运行在ubuntu 下
1
find -name '*.xml' |xargs perl -pi -e 's|<folder>class_LR|<folder>JPEGImages|g'
filename
可能导出的filename是没有文件后缀的,统一加上
1
find -name '*.xml' |xargs perl -pi -e 's|</filename>|.jpg</filename>|g'
path
path为图片在跑的模型上的绝对路径(因为我需要移植到另外一台电脑上跑)
1
find -name '*.xml' |xargs perl -pi -e 's|<path>$(your_original_pic_path)|<path>$(your_final_pic_path)|g'
width, height
有时候在Windows下用该工具label图像,可能会出现size那里的width和height都为0,如果在label之前已经归一化了图像大小那么就可以用下面两行命令来修改这个0值
1
2find -name '*.xml' |xargs perl -pi -e 's|0</width>|608</width>|g'
find -name '*.xml' |xargs perl -pi -e 's|0</height>|608</height>|g'
三、用yolov2训练
3.1 生成相关文件
按darknet的说明编译好后,接下来在darknet-master/scripts文件夹中新建文件夹VOCdevkit,然后将整个VOC2007文件夹都拷到VOCdevkit文件夹下。
然后,需要利用scripts文件夹中的voc_label.py文件生成一系列训练文件和label,具体操作如下:
首先需要修改voc_label.py中的代码,这里主要修改数据集名,以及类别信息,我的是VOC2019,并且所有样本用来训练,有两类目标,因此按如下设置
1 | ... |
修改好后在该目录下运行命令:python voc_label.py
,之后则在文件夹script/VOCdevki/VOC2019
下生成了文件夹labels
:
1 | ├──VOC2019 |
同时在scripts/
下应该也生成了2019_train.txt
这个文件,里面包含了所有训练样本的绝对路径。
❗️❗️❗️注意一下此时darknet/
文件夹下是否也生成了train.txt
文件,如果有,检查一下是否为空,若为空就把 2019_train.txt
的内容移到 train.txt
。
3.2 配置文件修改
做好了上述准备,就可以根据不同的网络设置(cfg文件)来训练了。在文件夹cfg中有很多cfg文件,应该跟caffe中的prototxt文件是一个意思。这里以yolov2.cfg
‘为例,主要修改参数如下:
1 | . |
另外也可根据需要修改learning_rate、max_batches等参数。
修改好了cfg文件之后,就需要修改两个文件,首先是data文件下的voc.names。打开voc.names文件可以看到有20类的名称,本例中只有一类,检测人,因此将原来所有内容清空,写上自己数据集对应的类名并保存。名字仍然用这个名字,如果喜欢用其他名字则请按一开始制作自己数据集的时候的名字来修改。
接着需要修改cfg文件夹中的voc.data文件。也是按自己需求修改,我的修改之后是这样的画风:
1
2
3
4
5classes= 1 //类别数
train = /home/mei/Desktop/cv/darknet/scripts/2019_train.txt //训练样本的绝对路径文件,也就是上文2.1中最后生成的
//valid = /home/pjreddie/data/voc/2007_test.txt //本例未用到
names = data/voc.names //上一步修改的voc.names文件
backup = backup/ //指示训练后生成的权重放在哪
修改后按原名保存最好,接下来就可以训练了。
3.3 运行训练
上面完成了就可以命令训练了,可以在官网上找到一些预训练的模型作为参数初始值,也可以直接训练,训练命令为
1 | ./darknet detector train ./cfg/voc.data cfg/tiny-yolo-voc.cfg |
如果用官网的预训练模型darknet.conv.weights
做初始化,则训练命令为
1 | ./darknet detector train ./cfg/voc.data .cfg/tiny-yolo-voc.cfg darknet.conv.weights |
不过我没试成功,加上这个模型直接就除了final,不知道啥情况。当然也可以用自己训练的模型做参数初始化,万一训练的时候被人终端了,可以再用训练好的模型接上去接着训练。
训练过程中会根据迭代次数保存训练的权重模型,然后就可以拿来测试了,测试的命令同理:
1 | ./darknet detector test cfg/voc.data cfg/tiny-yolo-voc.cfg results/tiny-yolo-voc_6000.weights data/images.jpg |
这样就完成了整个流程。