前天跑了一下caffe-ssd模型,并在pascal voc上跑了两天,效果不错,今天突然发现caffe-ssd目录没有了,,好像莫名被删除了,于是早上重新装了一遍,下午开始摸索如何用caff-ssd跑自己的数据,一个下午时间总算摸索出来了,记录一下,方便有需要的朋友参考.
caffe-ssd训练自己的数据其实挺简单的,生成目标检测的lmdb数据时候需要根据caffe-ssd中的代码生成,下面讲解一下如何操作:
需求说明:使用caffe-ssd训练文本区域检测的ssd模型,简单说就是检测一张纸上面的文字区域,检测类别只有一类textarea.(如果你有多个检测类别也可以,一样的操作方法)
1,数据准备:不管你的数据是用什么标注工具标的,肯定可以得到一个.txt文件吧(自己写一个程序把标注工具标注的文件解析出来),.txt文件里面如下第一行所示:(xmin, ymin,xmax, ymax)
data/data_ori/IMG_20171113_114301.jpg 924 740 2593 3549 0(我只有一个类别,所有标签是0)
data/data_ori/IMG_20171113_114301.jpg 332 484 1913 3261 0 1076 1036 2669 3785 1(如果你是多个类别,那一张图片肯定对应如这行一样的多个标签和坐标值)
数据先任意放在一个目录处理即可,然后写个程序该图片名字,改成和VOC一样的命名,改成数字开头即可,比如从00000000.jpg开始的图片,图片改为名字记得对应的.txt文件中也要改哈,提供一个改名字的参考代码:https://pan.baidu.com/s/14zNf5BhsKa35SsRbQ6M1fg(在data目录下放着)(124行函数为改名字代码,输入参数为你的.txt文件路径,改完名字之后需要保存的图片目录,新生成的改名之后图片对应的label.txt文件,里面是改名后的图片对应的bbox坐标和标签类别)
改为名字后开始生成改完名字图片的xml文件,看第127行,127行是生成每个改名之后图片的voc格式的xml文件,输入参数为保存的改名后的图片目录,需要保存的xml文件的路径,刚刚改完名后的图片对应的.txt文件
注意:1,生成每个图片的voc格式的xml时参考127行代码,代码121行 node_folder.text = 'VOC_textarea'改成你的,随便前一个名字就行,我起的VOC_textarea,2,17行有个width=1609, height=500,改成你图片的大小,我的图片同一个设备拍的,所以所有图片长宽一样,3,第40行改成你的标签类别,比如我只有有个类别就是textarea,所有就是这个,如果你是多个检测目标,那么在36-37行之间根据c的值判断,这个值是多少,比如你的0代表aa,1代表bb,2代表cc,那么就把node_name.text ="aa"等.
2,将数据划分成训练和测试数据:参照上一篇博客下载编译caffe-ssd,我的caffe-ssd目录是/home/user/yjf/caffe,进入caffe目录,在
caffe/data/VOCdevkit目录下新建文件夹VOC_textarea,这个名字要和你刚刚生成xml文件时21行的node_folder.text = 'VOC_textarea'名字一样.然后在该目录下在新建Annotations,ImageSets,JPEGImages三个目录.将之前改完名字后的图片放到JPEGImages目录下.将之前生成的xml文件放在Annotations目录下.
参照我上传的代码中的mian方法中的第三和第四步生成训练和测试文件.第三步生成训练数据其实就是把所有数据按比例分别写到txt文件中而已,如下所示:(注意生成的时候路径从刚刚新建的
VOC_textarea开始写)
VOC_textarea/JPEGImages/000000238.jpg VOC_textarea/Annotations/000000238.xml
VOC_textarea/JPEGImages/000000291.jpg VOC_textarea/Annotations/000000291.xml
生成的时候把我的代码放在data目录下执行,执行结束会在data目录生成test.txt,trainval.txt,注意不要改这个文件夹名字!然后在参照的代码中的第四步对所有test.txt文件中的图片生成一个对应的test_name_size.txt里面如下:
000000238 3968 2976
000000291 3968 2976
第一列为test.txt中图片的名字,第二列为图片高度,第三列为图片宽度,参照我的第四步代码写就行
3.生成lmdb数据:在caffe/data目录新建VOC_label,这个名字自己起,然后将刚刚生成的data目录下的test.txt,test_name_size.txt,trainval.txt拷贝到这个目录.并在这个目录在创建一个文件labelmap_voc.prototxt,命名不要改,就写这个名字.内容如下:
item {
name: "textarea"
label: 0
display_name: "textarea"
}
item {
name: "none_of_the_above"
label: 1
display_name: "background"
}
因为我只有一个检测目标,加上背景一共是2类,第二类是背景,如果你有多个类,就继续加,将背景类到最后一个就行,写的时候注意 name要和你生成xml时候40行 node_name.text = 'textarea'指定的一样
然后将caffe/data/VOC0712/create_data.sh复制到caffe/data/VOC_label目录下.注释掉cur_dir,和root_dir,添加一个root_dir=/home/user/yjf/caffe,这是caffe-ssd目录,将里面的dataset_name改成VOC_label,然后修改caffe/scripts/create_annoset.py,在开始添加sys.path.insert(0,'/home/user/yjf/caffe/python'),最后在caffe目录执行./data/VOC_label/create_data.sh开始生成lmdb数据
过程如下:
结束之后会在caffe/data/VOCdevkit/VOC_label目录生成lmdb文件夹,也即是训练数据.
4,模型训练:修改caffe/examples/ssd/ssd_pascal.py,其中的gpus='0,1,2,3' 该成gpus='0'和文件地址等等,我复制了一份这个文件为ssd_pascal_textarea.py到同目录,放在网盘,大家参考我的修改就好,注意num_classes = 2改成你的类别,我是一个类别加背景所以是2,background_label_id=1,因为我的背景是标号为1,所以写1(在data/VOC_label/labmap_voc.protxt查看你的背景是第几类),还有其他修改,参考我的一步步改就行(包括图片大小,name_size_file, label_map_file等路径等等).改完记得在caffe/models/VGGNet目录下存放预训练模型.参考上篇博客,最后python /examples/ssd/ssd_pascal_textarea.py就开始训练.
训练如下:
训练过程如果出现loss为nan,则是学习率太大,降低学习率即可.
5,预测:生成的模型会自动在/home/user/yjf/caffe/models/VGGNet/VOC_label/SSD_384x521目录下,将/example/ssd/score_ssd_pascla.py复制一份,我复制为sccore_ssd_textarea.py,里面加入caffe目录,在最开始,在caffe目录执行
python examples/ssd/score_ssd_textarea.py即可对模型进行评价,不需要指定模型地址,程序会自己在生成模型的目录下找模型编号最大的一个.评价会输出一个值,参考上篇截图.值越大模型越好.
将/example/ssd/ssd_detect.pyf复制一份,我复制为ssd_detect_textarea.py然后加入caffe目录在开始,最后在caffe目录执行python examples/ssd/ssd_detect_textarea.py --gpu_id 0 --labelmap_file data/VOC_label/labelmap_voc.prototxt --image_file data/VOCdevkit/VOC_textarea/JPEGImages/000000220.jpg --model_def models/VGGNet/VOC_label/SSD_384x521/deploy.prototxt --model_weights models/VGGNet/VOC_label/SSD_384x521/VGG_VOC_label_SSD_384x521_iter_4500.caffemodel即可对输入图片预测,如下所示:
当然画的框比较细哈,当然换可以正在视频预测,把python examples/ssd/ssd_pascal_video.py,改下这个函数就行,我就不试了哈,各位如果有实现过程有什么问题随时留言,很乐意帮助大家