SSD算法训练

     没接触过linux,直接在linux下配置环境+训练ssd,用了快一周时间,各种坑,各种吐血,因各人平台配置差异,以下仅供参考。

       平台:Ubuntu16.04+GTX1060 6G(GPU型号)+处理器64位
       CUDA:CUDA8.0,直接上Nvidia官方网站下载,选择cuda_8.0.61_375.26_linux.run
       cuDNN:cuDNN,上Nvidia官网,注册帐户后下载,选择cudnn-8.0-linux-x64-v6.0.tgz或cudnn-8.0-linux-x64-v5.1.tgz

一、安装CUDA和cuDNN
       参见http://www.linuxidc.com/Linux/2016-12/138870.htm  其中注意几点
       1、开始安装依赖项时,libprotobuf-dev先不装。因为这个依赖项对应到protobuf版本是2.6.1的。后面装的protobuf是2.5.0版本。
       2、环境变量配置时,打开~/.bashrc文件,添加下面两行到尾部,然后 soure ~/.bashrc使之生效
      export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}
      export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
       3、安装cuDNN时(6.0版本),解压后得到lib64和include,把这两个文件夹下到文件拷贝到对应的CUDA安装目录下的lib64和include文件夹中。这里cuda默认安装目录是/usr/local/cuda8.0,还有一个cuda文件夹,其实是链接到cuda8.0,所以路径写到这两个文件夹都可以。
       4、建立软链接,按照上面链接的说明,把libcudnn.so.5改成libcudnn.so.6,libcudnn.so.5.0.5改成libcudnn.so.6.0.21。
二、opencv我用opencv2.4.9版本。
以上是平台的配置,要根据自己到软件版本来修改,看上去很简单,然鹅总是有很多报错的,你只能不断百度必应谷歌,欢迎交流。

三、caffe配置。

      1、boost安装

下载boost的安装包,解压
tar -xjf boost_1_58_0.tar.bz2
在解压目录下运行
./bootstrap.sh
然后运行b2构建
sudo ./b2
成功会显示
The Boost C++ Libraries were successfully built!
The following directory should be added to compiler include paths:
    /home/o/Boost库/boost_1_58_0
The following directory should be added to linker library paths:
    /home/o/Boost库/boost_1_58_0/stage/lib
如果没有显示这样则运行
sudo apt-get install libbz2-dev
然后再
sudo ./bjam install
sudo ./b2
    2、安装protobuf
    这里有很多坑,一开始装3.0.0版本,总是出现caffe.pb.h的错或caffe.pb.o的错,看这位兄台,改成2.6版本解决问题,但是又出现其他问题,后面改为安装2.5.0版本。
    安装protobuf过程:
    下载protobuf2.5.0,解压后看有没有gtest文件夹,如果有就不用下载gtest-1.5.0了,如没有,下载gtest-1.5.0后解压放到protobuf下,然后重命名为gtest。
cd protobuf
$ ./autogen.sh

运行上面代码得到configure文件,然后
./configure -prefix=/usr   //这里是你安装的路径,可以自己设置,一定要明确,后面添加环境变量要用。再执行

make
make check
sudo make install

安装完成后添加环境变量,注意自己的路径
sudo vim /etc/profile
####### add protobuf lib path ########
#(动态库搜索路径) 程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径
如果是安装在/usr中则用下面配置
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/
#(静态库搜索路径) 程序编译期间查找动态链接库时指定查找共享库的路径
export LIBRARY_PATH=$LIBRARY_PATH:/usr/lib/
#执行程序搜索路径
export PATH=$PATH:/usr/bin/
#c程序头文件搜索路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include/
#c++程序头文件搜索路径
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/
#pkg-config 路径
export PKG_CONFIG_PATH=/usr/lib/pkgconfig/

source /etc/profile生效

完成后可以用protoc --version查看版本。

如果要卸载protobuf,则可用先去除依赖项sudo apt-get remove libprotobuf-dev,再到原安装的位置,一个一个删除文件。

     3、修改caffe下MakeFile和Makefile.config文件配置,按照各人配置来修改。Makefile.config中,使用GPU当然就不用把# CPU_ONLY := 1这一行打开, 使用cudnn则去掉前面的#,变为USE_CUDNN := 1,同样#WITH_PYTHON_LAYER := 1打开

参照http://www.linuxidc.com/Linux/2016-12/138870p2.htm,如果缺少什么文件,可能是没安装依赖项,或者没包含相关头文件,常见到错误网上一般答案很多。

# For CUDA < 6.0, comment the *_50 through *_61 lines for compatibility.
# For CUDA < 8.0, comment the *_60 and *_61 lines for compatibility.
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_60,code=sm_60 \
        -gencode arch=compute_61,code=sm_61 \
        -gencode arch=compute_61,code=compute_61

这里意思是如果CUDA版本低于6.0则把50到61那几行注释,低于8.0则注释60到61那3行。

python我用自带的2.7版本,所以按安装上面链接里的路径修改。


然后编译

make all -j8或make all -j4,看自己机器几核的。配置过程中在这里停了好久,很多protobuf的错误在这边出现,各人平台不一样,错的也不一样。

通过后再

sudo make runtest

这里会跑很久

完成后配置caffe到python环境变量

sudo vim ~/.bashrc
export PYTHONPATH=~/caffe/python:$PYTHONPATH    //根据实际caffe路径来写
LD_LIBRARY_PATH=~/caffe/build/lib:$LD_LIBRARY_PATH
source ~/.bashrc  //使环境变量生效

很多人是配置sudo vi /etc/profile 这个文件,查了下,~/.bashrc文件是在当前用户生效,profile则是对所有用户生效。

如果出现

Traceback (most recent call last):
  File "/home/zc/caffe/data/VOC0712/../../scripts/create_annoset.py", line 103, in <module>
    label_map = caffe_pb2.LabelMap()
AttributeError: 'module' object has no attribute 'LabelMap'

可能没有配置好环境变量。

到此caffe配置基本完成,其中可能会遇到很多问题,总结了一下,基本上是缺少依赖库,版本不对,环境变量路径不对这几个问题。

python后

import pycaffe看看,如果换行没报错,则成功。

四、训练ssd

      1、数据整理。比如3000张样本,其中2000张作为训练样本train.txt,1000张作为测试样本test.txt,这里就没有像VOC2007数据一样还有trainval和val,假设你已经制作好xml文件,还有两个文件train.txt, test.txt。里面的内容为对应的图像名,不带jpg后缀,一张图像一行。

00000

00001

00002


在caffe/data下新建ssdtrain和train_dataset文件夹,在ssdtrain下新建train_dataset文件夹,在ssdtrain/train_dataset下新建Annotations,ImageSets ,JPEGImages三个文件夹,在ImageSets下新建Layout,Main, Segmentation三个文件夹,上面train.txt, test.txt放在caffe/data/ssdtrain/train_dataset/ImageSet/Main下,所有xml文件放在Annotations下,所有图像放在JPEGImages下。当然,这里坑又来了,vim下打开train.txt, test.txt看看他们到格式 :set ff,如果显示是DOS,则设置为unix,:set ff=unix不然后面坑到你吐血。这个是windows和unix的换行符问题。
        2、修改create_data.sh ,labelmap_voc.prototxt ,create_list.sh三个文件,见这里http://www.cnblogs.com/zjutzz/p/6845002.html
        将VOC0712下这三个文件复制到caffe/data/train_dataset下,改名为create_data_traindata.sh ,labelmap_traindata.prototxt ,create_list_traindata.sh,里面的路径要根据自己caffe的路径修改,比如create_list_traindata.sh中root_dir = .../caffe/data/ssdtrain,可用绝对路径

---------------------------------------------------------

create_list_traindata.sh:

root_dir=我的绝对路径/caffe/data/ssdtrain
sub_dir=ImageSets/Main
bash_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for dataset in train test
do
  dst_file=$bash_dir/$dataset.txt
  if [ -f $dst_file ]
  then
    rm -f $dst_file
  fi
  for name in train_dataset
  do
    if [[ $dataset == "test" && $name == "VOC2012" ]]
    then
      continue
    fi
    echo "Create list for $name $dataset..."
    dataset_file=$root_dir/$name/$sub_dir/$dataset.txt

    img_file=$bash_dir/$dataset"_img.txt"
    cp $dataset_file $img_file
    sed -i "s/^/$name\/JPEGImages\//g" $img_file
    sed -i "s/$/.jpg/g" $img_file

    label_file=$bash_dir/$dataset"_label.txt"
    cp $dataset_file $label_file
    sed -i "s/^/$name\/Annotations\//g" $label_file
    sed -i "s/$/.xml/g" $label_file

    paste -d' ' $img_file $label_file >> $dst_file

    rm -f $label_file
    rm -f $img_file
  done

  # Generate image name and size infomation.
  if [ $dataset == "test" ]
  then
    $bash_dir/../../build/tools/get_image_size $root_dir $dst_file $bash_dir/$dataset"_name_size.txt"
  fi

  # Shuffle trainval file.
  if [ $dataset == "train" ]
  then
    rand_file=$dst_file.random
    cat $dst_file | perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' > $rand_file
    mv $rand_file $dst_file
  fi
done

------------------------------------------------

create_data_traindata.sh:

cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
root_dir=$cur_dir/../..
cd $root_dir
redo=1
data_root_dir="我的绝对路径/caffe/data/ssdtrain"
#dataset_name="VOC0712"
dataset_name="train_dataset"
mapfile="$root_dir/data/$dataset_name/labelmap_traindata.prototxt"
anno_type="detection"
db="lmdb"
min_dim=0
max_dim=0
width=0
height=0

extra_cmd="--encode-type=jpg --encoded"
if [ $redo ]
then
  extra_cmd="$extra_cmd --redo"
fi
for subset in train test
do
  python $root_dir/scripts/create_annoset.py --anno-type=$anno_type --label-map-file=$mapfile --min-dim=$min_dim --max-dim=$max_dim --resize-width=$width --resize-height=$height --check-label $extra_cmd $data_root_dir $root_dir/data/$dataset_name/$subset.txt $data_root_dir/$dataset_name/$db/$dataset_name"_"$subset"_"$db examples/$dataset_name
done

-------------------------------------

labelmap_voc.prototxt:看你检测任务来改

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

在caffe目录下运行
./data/train_dataset/create_list_traindata.sh
会得到test_name_size.txt,train.txt,test.txt三个文件,
train.txt,test.txt内容格式为对应的xml和图像文件路径
train_dataset/JPEGImages/02000.jpg train_dataset/Annotations/02000.xml
train_dataset/JPEGImages/02001.jpg train_dataset/Annotations/02001.xml
train_dataset/JPEGImages/02002.jpg train_dataset/Annotations/02002.xml
注意:这里又有一个大坑和上面一样,换行符问题,但可能显示是unix格式,但是用vim
打开文件会有^M字符,如果你继续运行./data/train_dataset/create_data_traindata.sh
可能出现找不到xml或jpg图像的错误。
解决办法是删除上面文件中的^M,在vim下:%s/^M//g,回车,然后在caffe/examples下新建train_dataset文件夹,运行

./data/train_dataset/create_data_traindata.sh

会在caffe/examples/train_datasetcaffe/data/ssdtrain/train_dataset下生成lmdb文件,内容一样。

        3、修改ssd_pascal_traindata.py文件

       把examples下ssd文件夹中的ssd_pascal.py文件复制到caffe/examples/train_dataset下,修改为ssd_pascal_traindata.py,内容修改如下:

--------------------------------------------------------------------

# The database file for training data. Created by data/VOC0712/create_data.sh
train_data = "examples/train_dataset/train_dataset_train_lmdb"
# The database file for testing data. Created by data/VOC0712/create_data.sh
test_data = "examples/train_dataset/train_dataset_test_lmdb"

------------------------------------------------------------------

# Modify the job name if you want.
job_name = "SSD_{}".format(resize)
# The name of the model. Modify it if you want.
model_name = "VGG_train_dataset_{}".format(job_name)

# Directory which stores the model .prototxt file.
save_dir = "models/VGGNet/train_dataset/{}".format(job_name)
# Directory which stores the snapshot of models.
snapshot_dir = "models/VGGNet/train_dataset/{}".format(job_name)
# Directory which stores the job script and log file.
job_dir = "jobs/VGGNet/train_dataset/{}".format(job_name)
# Directory which stores the detection results.
output_result_dir = "{}/data/ssdtrain/result/train_dataset/{}/Main".format(os.environ['HOME'], job_name)

--------------------------------路径按照自己的路径--------------------------------------

# Stores the test image names and sizes. Created by data/VOC0712/create_list.sh
name_size_file = "data/train_dataset/test_name_size.txt"
# The pretrained model. We use the Fully convolutional reduced (atrous) VGGNet.
pretrain_model = "models/VGGNet/VGG_ILSVRC_16_layers_fc_reduced.caffemodel"
# Stores LabelMapItem.
label_map_file = "data/train_dataset/labelmap_traindata.prototxt"

-----------------类别数量如果是1类,加上背景,所以为2---------------------------

num_classes = 2

-------------------------------gpu设置---只有一个-------------------------------

# Defining which GPUs to use.
gpus = "0"

cd到caffe下

python examples/train_dataset/ssd_pascal_traindata.py

则会在caffe下生成jobs,model等文件夹和文件,会提示找不到VGG_ILSVRC_16_layers_fc_reduced.caffemodel

下载预训练模型VGG_ILSVRC_16_layers_fc_reduced.caffemodel放到models/VGGNet下。再次运行可能提示cudnn内存不足,把ssd_pascal_traindata.py中改为

# Divide the mini-batch to different GPUs.
#batch_size = 32
#accum_batch_size = 32
batch_size = 10
accum_batch_size = 10


训练得到模型后在windows下vs工程中测试,把deploy.prototxt,labelmap_traindata.prototxt,solver.prototxt,test.prototxt,train.prototxe,VGG_train_dataset_SSD_300x300_iter_6000.caffemodel复制到vs工程下,修改

deploy.prototxt中最后save_output_param中,只留下label_map_file,并修改路径。


在linux下编辑没有上传图,等有空时再完善吧。欢迎交流讨论。

参考:

http://www.linuxidc.com/Linux/2016-12/138870.htm

http://www.linuxidc.com/Linux/2016-12/138870p2.htm

http://blog.csdn.net/missdaddio/article/details/67631777

http://blog.csdn.net/xiexievv/article/details/47396725


-----------------------------------------20170915------------------------------------------------------------

训练SSD512模型,batch_size和accum_batch_size相对于SSD300要减小,否则显存不够。batch_size减小后,训练不易收敛。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值