caffe上手:使用INRIA行人数据集对BVLC Caffe进行fine-tuning

上次使用mnist对caffe进行了初步了解,这一次就要开始对毕设的任务进行尝试了。这次打算对ImageNet进行fine tune,使用的是行人检测数据集INRIA。

首先下载下来INRIA数据集,发现有Train和Test文件夹里的图片大小不固定,而且没有进行crop。而其中有两个子文件夹96X160H96和70X134H96下的图片是crop好的,可以直接拿来用作行人检测的正样本。但因为INRIA并不是针对caffe设计的,所以需要先对它进行一定处理。这里就需要明确哪些数据作为训练数据,哪些数据作为测试数据。因为只是对fine tuning进行测试,所以我这里没有对准备训练数据花很多精力,直接拿96X160H96/Train/pos文件夹下的图片作为训练正样本,Train/neg/下的图片作为训练负样本,70X134H96/Test/pos下的作为测试正样本,Test/neg/下的作为测试负样本。

然后需要做的是从这些数据产生lmdb数据,我直接借鉴了ImageNet的配置文件create_imagenet.sh稍作修改写了一个create_pedenet.sh。

为了方便管理路径起见,我又单独建立了一个data/pedestrian文件夹,下面有两个子文件夹train和val,分别装训练和测试数据,每个文件夹下又分别有pos和neg两个文件夹装正负样本。

在create_pedenet文件中,首先将DATA、EXAMPLE、TRAIN_DATA_ROOT和VAL_DATA_ROOT几个变量设置如下:

EXAMPLE=project/pedestrian/newdata/(是处理好之后的lmdb数据存储的路径,事先这个路径下一定不能有pedenet_train_lmdb和pedenet_val_lmdb两个文件夹)
DATA=data/pedestrian/(是存储图片路径的train.txt和val.txt两个文件的路径)
TOOLS=build/tools


TRAIN_DATA_ROOT=data/pedestrian/train/(存储训练数据的路径,TRAIN_DATA_ROOT + train.txt的每一行路径就对应着每个图片文件)
VAL_DATA_ROOT=data/pedestrian/val/(同上)

然后需要做的就是生成对应各个样本路径的train.txt和val.txt文件。这里我自己写了一个几十行的C程序专门生成这两个文件,将每个文件写成如下的格式:

pos/person_and_bike_209b.png   1
neg/00000002a.png   0

其中1表示正样本,0表示负样本(其实这个只是自己约定的label,机器并不知道哪个是正,哪个是负)。需要注意的是在windows系统中文件路径的分隔号是\\,而在linux系统中合法的分隔号是/,要注意区分,否则会出现找不到文件的错误:

E0321 21:50:27.440016  2448 io.cpp:80] Could not open or find file data/pedestrian/val/pos\person_037a.png

然后执行create_pedenet.sh,完成数据预处理:

~/caffe-master$ ./project/pedestrian/create_pedenet.sh
Creating train lmdb...
I0321 21:58:04.069706  2493 convert_imageset.cpp:82] Shuffling data
I0321 21:58:05.401593  2493 convert_imageset.cpp:85] A total of 3328 images.
I0321 21:58:05.402035  2493 db_lmdb.cpp:23] Opened lmdb project/pedestrian/newdata//pedenet_train_lmdb
I0321 21:58:19.187896  2493 convert_imageset.cpp:146] Processed 1000 files.
I0321 21:58:31.109478  2493 convert_imageset.cpp:146] Processed 2000 files.
I0321 21:58:43.797771  2493 convert_imageset.cpp:146] Processed 3000 files.
I0321 21:58:47.886440  2493 convert_imageset.cpp:152] Processed 3328 files.
Creating val lmdb...
I0321 21:58:48.577513  2502 convert_imageset.cpp:82] Shuffling data
I0321 21:58:49.921418  2502 convert_imageset.cpp:85] A total of 1426 images.
I0321 21:58:49.921867  2502 db_lmdb.cpp:23] Opened lmdb project/pedestrian/newdata//pedenet_val_lmdb
I0321 21:58:59.190737  2502 convert_imageset.cpp:146] Processed 1000 files.
I0321 21:59:03.346020  2502 convert_imageset.cpp:152] Processed 1426 files.
Done.

这样就完成了数据的预处理,产生的文件data.mdb和lock.mdb存储在EXAMPLE路径下面。

下一步就是计算图像的平均值。这个步骤在imagenet中是通过compute_imagenet_mean.sh脚本来进行的,这里我就直接把这个文件拿过来修改了一下它的变量,就可以直接使用:

EXAMPLE=project/pedestrian/newdata(是存储处理后的图片的路径)
DATA=data/pedestrian(是生成的目标文件pedenet_mean.binaryproto的存储路径)
TOOLS=build/tools


$TOOLS/compute_image_mean $EXAMPLE/pedenet_train_lmdb \
  $DATA/pedenet_mean.binaryproto

这样就生成了data/pedestrian/pedenet_mean.binaryproto文件,网络训练的前期准备工作完成了。

下面需要对网络的核心配置文件进行编辑,主要是train_val.prototxt和solver.prototxt两个文件。

solver.prototxt主要是训练阶段的一些配置,首先net变量要修改为train_val.prototxt文件的路径,然后根据caffe官网上的提示,为了使网络中除了最后一层之外的其它层权重改变尽可能的缓慢,最好把网络前部的学习率lr改小一些,为了方便,直接将全局的base_lr变量调小,我第一次试验将其从0.01改到了0.005。

train_val.prototxt主要是对网络结构和参数的定义,因为我是对imagenet网络进行调优,所以这里我直接在imagenet的配置文件的基础上进行修改,主要是需要修改一下TRAIN和TEST两个阶段分别对应的data层的数据输入路径,然后还需要修改fc8层的输出数量,从1000改到了2(是否是行人),然后顺便将fc8层的名称改为fc8_pede以便区分。除此之外,为了让结构改变的fc8_pede的权重学习速度加快,要将这一层的lr_mult调大一些,因为前面base_lr减小了一半,我直接将这一层的lr_mult提高了10倍。

这样就完成了两个核心配置文件的修改。这里发现,要对已经训练好的imagenet进行参数的fine-tuning,现在服务器上没有这个网络已经训练好的权重...所以现下载一个权重数据caffemodel文件。这可以执行如下的命令行:

./scripts/download_model_binary.py models/bvlc_reference_caffenet

这个数据文件大约200多M,下载过程视网速而定,我往实验室的服务器上下载的速度只有10k/s左右,大约需要7~8个小时= = 所以果断选择了先用迅雷下载到本地,再传到服务器上。下载的链接可以在./models/bvlc_reference_caffenet/readme.md文件里找到,其他需要调优的参数权重也可以用类似的方法找到。

然后修改train_pedenet.sh脚本为:

caffe % ./build/tools/caffe train -solver project/pedestrian/solver.prototxt -weights models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel -gpu 0
然后执行这个脚本文件,就开始了网络的训练。首先会跳出一些提示信息显示网络的结构正在搭建,然后就开始了optimization过程,每1000次迭代都会显示一次accuracy,开始迭代之前accuracy是0.492,1000次之后是0.7897,再之后每1000次基本都维持在这个水平上。我分析这个网络精度不高的原因之一是网络的训练样本数量较少(训练正样本只有2400多,负样本只有1200多),与imagenet原来使用的动辄上万的训练样本量相差太大,而且网络结构上面主要优化的是最后一个全连接层的参数,所以参数的优化很快就达到了“饱和”状态,没有了继续提升的空间。因此要想提升网络的性能,一方面要用更大的数据集去进行训练,另一方面也需要考虑是否需要对网络结构进行调整。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值