ubuntu上使用自己的训练数据集 训练 caffe SSD网络

4 篇文章 0 订阅
1 篇文章 0 订阅

参考https://blog.csdn.net/zhang_shuai12/article/details/52346878;
https://blog.csdn.net/jiangyanting2011/article/details/78873199

前提

首先把Caffe的环境搭建好,要求能正常运行官方的例子:

# $CaffeRoot路径下,首先下载官方数据集范例
cd $HOME/data
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
# Extract the data.就能获得.jpg文件和.xml的标记文件。
tar -xvf VOCtrainval_11-May-2012.tar
tar -xvf VOCtrainval_06-Nov-2007.tar
tar -xvf VOCtest_06-Nov-2007.tar
....
# 就能生成LMDB文件
cd $CAFFE_ROOT
./data/VOC0712/create_list.sh
./data/VOC0712/create_data.sh
# 接下来就能进行训练了
python examples/ssd/ssd_pascal.py

也就是说主要的流程为
原始图片jpg(JPEGImages) 》 标记文件xml(Annotations) 》 文件清单txt(ImageSets/Main) 》 Caffe可读取文件LMDB 》训练生成weights模型caffemodel

接下来按各步骤依次分析。

标记

标记也就是在图片上提供2个点坐标确定一个矩形框及矩形框内的类别,图片内可有多个矩形框(也就是可有多个类)。你可以自己写代码来标记,opencv也不难,但一般使用现成标记工具:
- LabelImg
- BBox-Label-Tool

操作上LabelImg更方便,且能同时标记多个类,故以LabelImg为例进行讲解(安装方式参考官网)。

先建立VOC结构文件夹

先参照VOC2007/ VOC2012建立文件夹结构,在$HOME/data/VOCdevkit/路径下建立你自己的项目文件夹,假设命名为indoor,这样路径就为$HOME/data/VOCdevkit/indoor/。再在indoor文件夹下建立如下文件夹结构:

indoor
├── Annotations
├── ImageSets
│   └── Main
└── JPEGImages

数据集原始jpg图片放在JPEGImages文件夹下。

设置标定路径

进入LabelImg的源文件下输入python labelImg.py,就能打开界面,分别点击左侧按钮设置
- Open Dir,设置 数据集原始jpg图片路径,一般选JPEGImages
- Change Save Dir,设置 生成的标定xml文件路径,一般选Annotations

标定

非常简单,就是鼠标点击即可完成。注意有快捷键可加快工作效率:

Ctrl + uLoad all of the images from a directory
Ctrl + rChange the default annotation target dir
Ctrl + sSave
Ctrl + dCopy the current label and rect box
SpaceFlag the current image as verified
wCreate a rect box
dNext image
aPrevious image
delDelete the selected rect box
Ctrl++Zoom in
Ctrl–Zoom out
↑→↓←Keyboard arrows to move selected rect box

标定完后就会在Annotations路径下看到图片同名的xml文件了。

生成清单

参考:https://blog.csdn.net/u014696921/article/details/53353896

以上的2个标记工具都没有生成清单的功能,得你自己编程实现。
your doc路径下新建genMainList.py文件, 后文假设your doc就是indoor

[your doc]
├── genMainList.py
├── Annotations
├── ImageSets
│   └── Main
└── JPEGImages

改写的相关代码为

import os
import sys
import random
CURDIR = os.path.dirname(os.path.realpath(__file__))
dirImg=os.listdir("{}/JPEGImages".format(CURDIR))
print(dirImg)
try:
    start = 0
    end = len(dirImg)
    allNum = end-start
    test = int(allNum * 0.25)
except:
    print 'Please input test proportion'
    print './genMainList.py [test proportion]'
    os._exit(0)
b_list = range(start,end)
blist_webId = random.sample(b_list, test )
blist_webId = sorted(blist_webId) 
allFile = []
testFile = open('ImageSets/Main/test.txt', 'w')
trainFile = open('ImageSets/Main/trainval.txt', 'w')

for i in b_list:
    allFile.append(i)
# generate test.txt
for test in blist_webId:
    allFile.remove(test)
    filename=str(dirImg[test])
    filenameIndex=filename.rfind('.')
    filename=filename[:filenameIndex]
    testFile.write(filename + '\n')   
# generate trainval.txt
for train in allFile:
    filename=str(dirImg[train])
    filenameIndex=filename.rfind('.')
    filename=filename[:filenameIndex]
    trainFile.write(filename + '\n')
testFile.close()
trainFile.close()

然后在 该路径下的控制台输入python genMainList.py,就能在ImageSets/Main自动生成训练用的清单文件trainval.txttest.txt

生成caffe可食用文件LMDB

为啥LMDB?没办法,人家二进制文件,读取速度快啊。

修改自己脚本

进入Caffe的源文件夹,也是参照VOC建立文件夹结构,假设你的项目名称为indoor

caffe-ssd
├── data
│   ├── ...
│   ├── indoor...............你需要新建的文件夹
│   └── VOC0712
├── examples
│   ├── ...
│   ├── indoor...............自动生成的lmdb文件链接
│   ├── ssd
│   │  │── ...
│   │  └── ssd_pascal.py
│   └── VOC0712
├── models
│   ├── ...
... └── VGGNet
       └── VOC0712...........最后存放训练好的caffemodel模型

在源文件夹$CAFFE_ROOT/data下新建indoor文件夹,然后把同一路径下的VOC0712文件夹中的
- create_list.sh…………………..读取上步生成的清单
- create_data.sh…………………..生成lmdb文件
- labelmap_voc.prototxt…………….定义标定种类的文件

3个文件拷贝到你新建的indoor文件夹中,然后依次修改它们。

修改create_list.sh

只用改一处,第13行把

for name in VOC2007 VOC2012

改为

for name in indoor

其实你搜索关键词VOC就能找到了。

修改create_data.sh

只用改一处,第8行把

dataset_name="VOC0712"

改为

dataset_name="indoor"

同样,搜索关键词VOC就能找到了。

修改labelmap_voc.prototxt

这个文件夹里面定义你标定的种类。
其格式为

item {
  name: "none_of_the_above"
  label: 0
  display_name: "background"
}
item {
  name: "face"
  label: 1
  display_name: "face"
}

注意其中的label: 0是指背景,不用改。也就是你的种类从label:1开始,假设我这里的种类是face
那么总共的种类数量就是2了(后续改examples/ssd/ssd_pascal_indoor.py用得着)。

开始生成

进入Caffe源码根目录直接运行你定义的.sh文件

cd $CAFFE_ROOT
./data/indoor/create_list.sh
./data/indoor/create_data.sh

这样就会在$HOME/data/VOCdevkit/indoor/lmdb(你原来定义的源图像数据文件夹路径下)生成对应的**_lmdb的二进制文件,同时也会在$CAFFE_ROOT/examples/indoor/下建立相对应的链接。

训练生成caffemodel

Caffe的神经网络训练过程中会用到新的2类文件:
- 神经网络结构是通过.prototxt定义
- 预训练好的模型.caffemodel,其实就是网络结构上各weights/bias的值。

下载预训练好的caffemodel(可选)

参考:https://blog.csdn.net/Jesse_Mx/article/details/74011886

SSD的网络结构是基于VGGNet的,相当于在VGGNet的基础上再新建一些层。重头开始训练未免太费时间,这时可以 迁移学习,从网上直接下载已训练好的VGGNet网络 (在外网上,内网上可用此链接),然后将其解压放至models/VGGNet/VGG_ILSVRC_16_layers_fc_reduced.caffemodel。相应的路径对应于ssd_pascal_indoor.py中的pretrain_model(261行)部分。
这样,接下来只需训练SSD新增的那几层就行了。

修改脚本

$CAFFE_ROOT/examples/ssd/文件夹下复制ssd_pascal.py并重命名为ssd_pascal_indoor.py

caffe-ssd
├── data
├── examples
│   ├── ...
│   ├── indoor
│   ├── ssd
│   │  │── ...
│   │  │── ssd_pascal.py
│   │  └── ssd_pascal_indoor.py
... ...

然后开始修改ssd_pascal_indoor.py

...
# The database file for training data. Created by data/indoor/create_data.sh
train_data = "/home/[yourname]/data/VOCdevkit/indoor/lmdb/indoor_trainval_lmdb"  #81行
# The database file for testing data. Created by data/indoor/create_data.sh
test_data = "/home/[yourname]/data/VOCdevkit/indoor/lmdb/indoor_test_lmdb"       #84行
...
# A learning rate for batch_size = 1, num_gpus = 1. change into 0.001
base_lr = 0.00004                                                                #232行,修改学习率
...
# The name of the model. Modify it if you want. 
model_name = "VGG_indoor_{}".format(job_name)                                    #237行,将VOC0712改为indoor
# Directory which stores the model .prototxt file
save_dir = "models/VGGNet/indoor/{}".format(job_name)                            #240行,同上
# Directory which stores the snapshot of models
snapshot_dir = "models/VGGNet/indoor/{}".format(job_name)                        #242行,同上
# Directory which stores the job script and log file.
job_dir = "jobs/VGGNet/indoor/{}".format(job_name)                               #244行,同上
# Directory which stores the detection results.
output_result_dir = "{}/data/VOCdevkit/results/indoor/{}/Main".format(os.environ['HOME'], job_name)                                                                        #246行,同上
...
# Stores the test image names and sizes. Created by data/indoor/create_list.sh
name_size_file = "data/indoor/test_name_size.txt"                                #259行
...
# Stores LabelMapItem.
label_map_file = "data/indoor/labelmap_voc.prototxt"                             #263行
...
# MultiBoxLoss parameters.
num_classes = 2                                                                  #266行,这里改成你需要训练的识别类别数量(包括背景类)
...
# Defining which GPUs to use.
gpus = "0"                                                                       #332行,GPU数量改成适合你电脑的
...
# Divide the mini-batch to different GPUs.
batch_size = 32                                                                  #338-339行,根据你电脑的GPU性能合理设置batch尺寸
accum_batch_size = 32
...
# Evaluate on whole test set.
num_test_image = 32                                                              #360-361行,设置测试数据batch尺寸
test_batch_size = 8
...
prior_variance=prior_variance, kernel_size=3, pad=1, lr_mult=lr_mult,conf_postfix='_indoor')        #445行,加上conf_postfix
...
prior_variance=prior_variance, kernel_size=3, pad=1, lr_mult=lr_mult,conf_postfix='_indoor')        #474行,加上conf_postfix
...

训练

回到$CAFFE_ROOT下,运行python examples/ssd/ssd_pascal_indoor.py
它将会在$CAFFE_ROOT/models/VGGNet/indoor/SSD_300x300(上面237-263行设置,就与传统的/models/VOC0712/文件夹分开了)生成prototxt/ caffemodel/ solverstate三类文件。

部署使用

如果要部署使用的话,神经网络结构可用deploy.prototxt,生成的模型可用VGG_VOC0712_SSD_300x300_iter_[训练迭代次数].caffemodel,一般地取[迭代次数]最大的caffemodel。
这样就得到了自己图像训练集训练的最终结果:
- deploy.prototxt
- VGG_VOC0712_SSD_300x300_iter_[训练迭代次数].caffemodel

注意在部署使用用过程中,deploy.prototxt,还需要更改一个小细节:

...
save_output_param {
    # output_directory: "/home/tage/data/VOCdevkit/results/indoor/SSD_300x300/Main"
    # output_name_prefix: "comp4_det_test_"
    # output_format: "VOC"
    # label_map_file: "data/indoor/labelmap_voc.prototxt"
    # name_size_file: "data/indoor/test_name_size.txt"
    # num_test_image: 32
}
...

将最后(1616行左右)的save_output_param内的参数都注释了,这些参数只与训练有关。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值