ubuntu18.04下SSD的运行及训练自己数据集
caffe的SSD运行及训练自己数据集
环境
ubuntu18.04
cuda:10.0.120
cudnn:7.6.5.32
opencv:3.2.0
配置
一、安装依赖
sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev
sudo apt-get install libhdf5-serial-dev protobuf-compiler
sudo apt-get install --no-install-recommends libboost-all-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install python-dev
sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev
二、下载源码
git clone https://github.com/weiliu89/caffe.git
下载完成后是一个caffe文件夹,如图:
然后执行:
cd caffe
git checkout ssd
出现分支则安装成功(如图):
三、文件配置
cp Makefile.config.example Makefile.config
1、修改Makefile.config文件
1.若使用Cudnn
将# USE_CUDNN := 1 前的注释取消
即:USE_CUDNN := 1
2.若使用opencv3.x
取消 # OPENCV_VERSION := 3 前的注释
即:OPENCV_VERSION := 3
3.若是用Python编程
取消 # WITH_PYTHON_LAYER := 1 前的注释
即:WITH_PYTHON_LAYER := 1
4.加入hdf5的目录:
将
INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib
修改为:
INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/hdf5/serial
5. 如果使用的是Cuda>8.0,则将
CUDA_ARCH := -gencode arch=compute_20,code=sm_20 \
-gencode arch=compute_20,code=sm_21 \
-gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=sm_50 \
-gencode arch=compute_52,code=sm_52 \
-gencode arch=compute_61,code=sm_61
修改为:
CUDA_ARCH := -gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=sm_50 \
-gencode arch=compute_52,code=sm_52 \
-gencode arch=compute_61,code=sm_61
因为我的GPU算力为7.5,所以上面第五步应改为:
CUDA_ARCH := -gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=sm_50 \
-gencode arch=compute_52,code=sm_52 \
-gencode arch=compute_61,code=sm_61 \
-gencode arch=compute_75,code=sm_75
否则会在make runtest的时候报错,具体错误看下面错误记录。
2、修改Makefile文件
LIBRARIES += glog gflags protobuf boost_system boost_filesystem m hdf5_hl hdf5
修改为:
LIBRARIES += glog gflags protobuf boost_system boost_filesystem m hdf5_serial_hl hdf5_serial
位置大概如图:
LIBRARIES += boost_thread stdc++后加boost_regex
修改为:
LIBRARIES += boost_thread stdc++ boost_regex
位置大概如图:
NVCCFLAGS +=-ccbin=$(CXX) -Xcompiler-fPIC $(COMMON_FLAGS)
修改为:
NVCCFLAGS += -D_FORCE_INLINES -ccbin=$(CXX) -Xcompiler -fPIC $(COMMON_FLAGS)
位置大概如图:
四、编译
依次执行如下命令:
cd caffe
sudo make clean
mkdir build
cd build
sudo cmake ..
cd ..
sudo make all -j18
sudo make test
sudo make runtest
sudo make pycaffe (执行这句话之前一定将python路径添加到环境变量 export PYTHONPATH=/home/yh/caffe/python:$PYTHONPATH
可根据你的caffe下的python路径进行修改)
sudo cmake … 执行完如图:
sudo make all 执行完如图:
sudo make runtest 执行完如图:
遇到的问题
问题一:
caffe error == cudaSuccess (48 vs. 0)
解决办法:
在Makefile.config中进行修改, CUDA_ARCH ,根据你自己GPU的算力,进行修改,算力表如下:
修改完之后先make clean,再进行make all -j18。
五、配置环境变量
打开配置文件
gedit ~/.bashrc
在文件的最后一行添加以下路径
export PYTHONPATH=~/caffe/python:$PYTHONPATH #如果caffe在别的目录下,记得修改路径
配置文件生效
source ~/.bashrc
六、测试
XXX@XXX:~$ python
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import caffe
>>>
如果不报错,则配置成功!
遇到的问题
出现如下问题:
ImportError: No module named google.protobuf.internal
则执行下面命令:
sudo apt-get install python-protobuf
测试demo
一、VOC数据集下载
官网
下载如下三个文件:VOC2012trainval、VOC2007trainval、VOC2007test
#下载
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
然后在home文件夹下创建data文件夹,解压刚刚下载的三个文件
tar -xvf VOCtrainval_11-May-2012.tar
tar -xvf VOCtrainval_06-Nov-2007.tar
tar -xvf VOCtest_06-Nov-2007.tar
二、VGG-16预训练模型下载
链接 提取码:515c
然后将此模型放在caffe/models/VGGNet下,如果没有就新建这个目录然后放入。
三、LMDB数据集制作
进入/caffe/data/VOC0712文件夹下
chmod +x ./create_list.sh #赋予权限,为可执行文件
./create_list.sh #执行
chmod +x ./create_data.sh
./create_data.sh
第一步执行结果:
第二步执行结果:
四、训练模型
1、打开caffe/examples/ssd/ssd_pascal.py这个文件,找到gpus=’0,1,2,3’这一行,如果您的服务器有一块显卡,则将123删去,如果有两个显卡,则删去23,以此类推。如果您服务器没有gpu支持,则注销以下几行,程序会以cpu形式训练。
#Ifnum_gpus >0:
#batch_size_per_device =int(math.ceil(float(batch_size) / num_gpus))
#iter_size =int(math.ceil(float(accum_batch_size) / (batch_size_per_device * num_gpus)))
#solver_mode =P.Solver.GPU
#device_id =int(gpulist[0])
gpus=’0,1,2,3’这一行位置如图
保存后终端运行:
cd /home/**(服务器的名字)/caffe
python examples/ssd/ssd_pascal.py #注意要在caffe下面,不能进入文件夹直接执行.py
运行结果:
测试图片
python examples/ssd/score_ssd_pascal.py
测试视频:
python examples/ssd/ssd_pascal_webcam.py
遇到的问题
1、执行python examples/ssd/ssd_pascal.py时出现
则将上面语句改为:
sudo python examples/ssd/ssd_pascal.py
2、遇到模型找不到
在ssd_pascal.py文件import caffe 之前添加:
import sys
sys.path.insert(0,'/home/**/caffe/python') #**为自己的路径
注意每次重新执行都要重新运行一遍:sudo make pycaffe ,否则会报错找不到caffe模型
训练自己数据集
一、制作自己数据集
最终目录如下:
caffe
├── data
│ ├── ...
│ ├── mydata...............你需要新建的文件夹
│ └── VOC0712
├── examples
│ ├── ...
│ ├── mydata...............自动生成的lmdb文件链接
│ ├── ssd
│ │ │── ...
│ │ └── ssd_pascal.py
│ └── VOC0712
├── models
│ ├── ...
... └── VGGNet
└── VOC0712...........最后存放训练好的caffemodel模型
1、用labelImage来标注图片,标注好的图片会有与其名称对应的xml文件保存识别框位置,具体如下:
2、在caffe/examples下创建MyDataSet文件夹,用于存放后续生成的lmdb文件.
3、在caffe/data文件夹下新建自己训练数据VOC格式文件MyDataSet,则在MyDataSet目录下需包含Annotations、ImageSets、JPEGImages三个文件夹。同时将把data/VOC0712目录下的create_list.sh 、create_data.sh、labelmap_voc.prototxt 这三个文件拷贝到MyDataSet下。
- 将刚刚标注生成的xml文件放入Annotations
- 将所有图片放入JPEGImages
- ImageSet目录下包含Main文件下,在ImageSets\Main里有四个txt文件:test.txt train.txt trainval.txt val.txt(后续生成)
4、MyDataSet目录下新建generate.py文件,生成Main文件夹下的test.txt,trainval.txt,train.txt,val.txt
import os
import random
xmlfilepath=r'/data_1/SSD/caffe/data/VOCdevkit/mydata/Annotations'
saveBasePath=r"/data_1/SSD/caffe/data/VOCdevkit/mydata/ImageSets/Main"
trainval_percent=0.7
train_percent=0.7
total_xml = os.listdir(xmlfilepath)
num=len(total_xml)
list=range(num)
tv=int(num*trainval_percent)
tr=int(tv*train_percent)
trainval= random.sample(list,tv)
train=random.sample(trainval,tr)
print("train and val size",tv)
print("traub suze",tr)
ftrainval = open(os.path.join(saveBasePath,'trainval.txt'), 'w')
ftest = open(os.path.join(saveBasePath,'test.txt'), 'w')
ftrain = open(os.path.join(saveBasePath,'train.txt'), 'w')
fval = open(os.path.join(saveBasePath,'val.txt'), 'w')
for i in list:
name=total_xml[i][:-4]+'\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftrain.write(name)
else:
fval.write(name)
else:
ftest.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest .close()
5、在与caffe 同级的目录下新建data,data下新建Mydata
6、修改labelmap_voc.prototxt文件(改成自己的类别),以及create_list.sh和create_data.sh文件中的相关路径
#labelmap_voc.prototxt需修改:
item {
name: "none_of_the_above"
label: 0
display_name: "background"
}
item {
name: "aeroplane"
label: 1
display_name: "person"
}
#create_list.sh需修改:
root_dir=/home/yi_miao/data/Mydataset/
...
for name in yourownset
...
#if [[ $dataset == "test" && $name == "VOC2012" ]]
# then
# continue
# fi
#create_data.sh需修改:
root_dir=/home/yi_miao/caffe-ssd
data_root_dir="/home/yi_miao/data/Mydataset"
dataset_name="Mydataset"
修改如下图
7、运行命令
./data/mydataset/create_list.sh
./data/mydataset/create_data.sh
在examples/mydataset/文件夹下可以看到两个子文件夹, mydataset_trainval_lmdb, mydataset_test_lmdb;里面均包含data.dmb和lock.dmb
如图
二、修改脚本,开始训练
在/examples/ssd/文件夹下复制ssd_pascal.py并重名为ssd_pascal_mydata.py并按如下修改
...
# The database file for training data. Created by data/mydata/create_data.sh
train_data = "/home/[yourname]/data/VOCdevkit/mydata/lmdb/mydata_trainval_lmdb" #82行
# The database file for testing data. Created by data/mydata/create_data.sh
test_data = "/home/[yourname]/data/VOCdevkit/mydata/lmdb/mydata_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_mydata_{}".format(job_name) #237行,将VOC0712改为mydata
# Directory which stores the model .prototxt file
save_dir = "models/VGGNet/mydata/{}".format(job_name) #240行,同上
# Directory which stores the snapshot of models
snapshot_dir = "models/VGGNet/mydata/{}".format(job_name) #242行,同上
# Directory which stores the job script and log file.
job_dir = "jobs/VGGNet/mydata/{}".format(job_name) #244行,同上
# Directory which stores the detection results.
output_result_dir = "{}/data/VOCdevkit/results/mydata/{}/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/mydata/test_name_size.txt" #259行
...
# Stores LabelMapItem.
label_map_file = "data/mydata/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 # 359行 #360-361行,设置测试数据batch尺寸
test_batch_size = 8
...
prior_variance=prior_variance, kernel_size=3, pad=1, lr_mult=lr_mult,conf_postfix='_mydata') #445行,加上conf_postfix
...
prior_variance=prior_variance, kernel_size=3, pad=1, lr_mult=lr_mult,conf_postfix='_mydata') #474行,加上conf_postfix
...
然后运行python examples/ssd/ssd_pascal_mydata.py。
它将会在$CAFFE_ROOT/models/VGGNet/mydata/SSD_300x300(上面237-263行设置,就与传统的/models/VOC0712/文件夹分开了)生成prototxt/ caffemodel/ solverstate三类文件。
下图为训练完成图:
三、测试图片
在example/ssd/ssd_detect.py
修改如下位置:
然后在caffe目录下,运行ssd_detect.py
训练过程可视化以及测试评价
一、可视化loss
参考
将SSD训练过程中生成的日志文件可视化
1、在/caffe/jobs/VGGNet/VOC0712/SSD_300x300文件夹中会有VGG_VOC0712_SSD_300x300.log文件。利用这个文件绘制训练过程中的loss与accuracy曲线。
2、使用caffe/tools/extra中自带日志分析工具
caffe/tools/extra路径下执行命令行:
./parse_log.sh ../../jobs/VGGNet/VOC0712/SSD_300x300/VGG_VOC0712_SSD_300x300.log
将在当前目录下生成VGG_VOC0712_SSD_300x300.log.test,VGG_VOC0712_SSD_300x300.log.train两个文件。
3、
首先,在caffe/tools/extra执行
cp plot_log.gnuplot.example plot_log.gnuplot
然后,修改代码
gedit plot_log.gnuplot
33行,设置图片名称
44行,更改为自己的文件
最后,caffe/tools/extra路径执行:
gnuplot plot_log.gnuplot
二、评价指标mAP
参考,自己只是记录一下。
新建一个文件夹,里面含有train.prototxt,test.prototxt,solver.prototxt,test.sh,训练好的caffemodel以及标注的测试集lmdb。
其中
test.sh文件如下:
/home/mx/paper-use/caffe/build/tools/caffe train \
--solver='solver.prototxt' \
--weights='KITTI_SSD_300x300_ft_iter_61000.caffemodel' \
--gpu 0 2>&1 | tee test_result.log
solver.prototxt文件如下:
修改最大迭代次数max_iter设置为0,把test_iter设置为测试图片数量除以测试的batchsize,同时制定训练册测试网络文件
train.prototxt文件如下:
# train.prototxt
data_param {
source: "/home/mx/paper-use/caffe/examples/KITTI/KITTI_trainval_lmdb"
batch_size: 1 # 根据显卡调整,越大越好
backend: LMDB
}
label_map_file: "/home/mx/paper-use/caffe/data/KITTI/labelmap_kitti.prototxt"
test.prototxt文件如下:
# test.prototxt
data_param {
source: "/home/mx/paper-use/caffe/examples/KITTI/KITTI_test_lmdb"
batch_size: 1
backend: LMDB
}
annotated_data_param {
batch_sampler {
}
label_map_file: "/home/mx/paper-use/caffe/data/KITTI/labelmap_kitti.prototxt"
}
save_output_param {
output_directory: "/home/mx/paper-use/test-kitti-model/main"
output_name_prefix: "comp4_det_test_"
output_format: "VOC"
label_map_file: "/home/mx/paper-use/caffe/data/KITTI/labelmap_kitti.prototxt"
name_size_file: "/home/mx/paper-use/caffe/data/KITTI/test_name_size.txt"
num_test_image: 899 # 测试图片的数量
}
name_size_file: "/home/mx/paper-use/caffe/data/KITTI/test_name_size.txt"
之后执行./test.sh,得到:
I0127 20:25:05.363581 9889 solver.cpp:332] Iteration 0, loss = 1.2211
I0127 20:25:05.363626 9889 solver.cpp:433] Iteration 0, Testing net (#0)
I0127 20:25:05.376278 9889 net.cpp:693] Ignoring source layer mbox_loss
I0127 20:25:16.671056 9889 solver.cpp:553] Test net output #0: detection_eval = 0.774722
I0127 20:25:16.671093 9889 solver.cpp:337] Optimization Done.
I0127 20:25:16.671098 9889 caffe.cpp:254] Optimization Done.
detection_eval就是mAP,表明其mAP是77.4%。