caffe 学习系列之finetuning

在安装好caffe之后,下一步自然就是运行一些demo 来玩下。
在caffe 的官网的notebook 中已经介绍了如何对caffe 提供的demo 的数据集进行finetuning, 这里就不过多的介绍了。caffe finetuning 的demo

这一篇主要是介绍如何用caffe提供的model 来训练我们自己的数据集。

我用的系统是mac osx 10.11 EI, 主要实现的工具是使用terminal 终端和caffe c++ 的命令行接口

  1. 数据集是大概16000张照片,主要是对这些照片的9中照片做图像的分类。(因为这是我的一个课程作业,老师提供了大概3000张左右的照片给我们预测,预测结果在课程网站上面直接显示出来,所以我没有从训练集选择30%的照片作为测试集来验证。如果想要自己训练并且测试的话,可以写一个小程序自己生成训练集和测试集。)
    我把我的测试集放到百度云了
    链接: http://pan.baidu.com/s/1i5rsMFF 密码: edpc
    有兴趣的同学可以去下载下来玩一玩。
    数据集包括了16000张照片 和 包含他们文件位置和label 的train.txt

2.选择的model 是caffe 提供的googlenet, 它是2014 ilvsrc 图像分类比赛的冠军。装好caffe之后,可以在命令行进入caffe的根目录之后输入:

python scripts/download_model_binary.py models/bvlc_reference_googlenet

然后会下载一个大概50M 左右的googlenet.caffemodel 下载完成之后可以在 models/bvlc_googlenet/ 的文件夹中看到 以下文件:
train_val.prototxt
quick_solver.prototxt
solver.prototxt
deploy.protoxt
bvlc_googlenet.caffemodel
readme.md

3.在model 下载完成之后,下一步是要使用caffe tools中的convert_imagenet 把我们的数据集转成LMDB 格式。(在caffe中数据默认是通过LMDB 格式来存取的,所以要转格式。)当然,caffe 的框架也有提供其他的格式存取,不过入门的话还是用LMDB 比较方便。
转格式的代码如下:
进入caffe 根目录

GLOG_logtostderr=1 ./build/tools/convert_imageset \
/这里写的是照片根目录的路径 \
/这里写的是train.txt 的路径 \
/这里写的是生成的train_lmdb 存的路径 \

要注意的是:在命令行输入命令的时候,每个路径之间是用空格隔开的,要是想要换行可以输入 \
如果报错的话 看它提示的error,一般就是找不到照片的文件名或者存train_lmdb 的路径出错。 第一个问题在train.txt 的照片文件写文件的绝对路径,第二个问题就要看原来的路径下面是不是已经存在一个这样的lmdb文件夹了,如果有就把它删除就可以了。

转成lmdb 格式之后,下一步是生成mean.binaryproto
使用下面这个命令

./build_release/tools/compute_image_mean /path/to/train_lmdb /path/to/train_mean.binaryproto

两个文件名:一个是train_lmdb 的路径,一个是生成的mean.binaryproto 的路径

4.在数据格式准备完成之后,我们就是要修改原来的solver 或者quick_solver 的文件来进行训练了。

我们来看下solver.prototxt

net: "models/bvlc_googlenet/train_val.prototxt" # 这个是caffemodel 在的路径,默认是相对路径,也可以改成绝对路径
#test_iter: 1000        # 要是有测试集的话就可以用这个
#test_interval: 4000    # 也可以直接用全部训练集训练,然后输出正确率
#test_initialization: false # 这样就不需要用到这个了
display: 40             # 这里是每隔40个循环就显示一次结果
average_loss: 40
base_lr: 0.01           # 这个是基本的学习率
lr_policy: "step"       
# 这个是每过一定数量的循环之后就降低学习率,可以改成"fixed" 把学习率固定下来
stepsize: 320000  # 这个就设置下降学习率的step size
gamma: 0.96       # 下降是 * gamma
max_iter: 10000000  # 循环的次数
momentum: 0.9     # 冲量,一般都是0.9
weight_decay: 0.0002
snapshot: 40000
snapshot_prefix: "models/bvlc_googlenet/bvlc_googlenet"
solver_mode: GPU

然后我们还要设置train_val.prototxt:
由于这个比较长,所以我就只贴要修改的地方了:

layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN # 还有一个data layer 这里是TEST 的,可以把那个layer注释掉,我没有使用到它
  }
  transform_param { # 这里也可以放mean.binaryproto
    mirror: true
    crop_size: 224
    mean_value: 104
    mean_value: 117
    mean_value: 123
  }
  data_param {
    source: "/path/to/train_lmdb" # 这里是要改的地方
    batch_size: 16
    backend: LMDB
  }
}
layer {
  name: "fc8_flickr" # 这里原来是fc8, 但是我们要改成我们自己名字,这样就不会报错啦
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc8_flickr" # 这里也要改
  # lr_mult is set to higher than for other layers, because this layer is starting from random while the others are already trained
  param {
    lr_mult: 10
    decay_mult: 1
  }
  param {
    lr_mult: 20
    decay_mult: 0
  }
  inner_product_param {
    num_output: 9     # 这里我只分9类,所以就num_output 就是9
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "loss3/loss3"
  type: "SoftmaxWithLoss"
  bottom: "fc8_flickr"
  bottom: "label"
  top: "loss3/loss3"
  loss_weight: 1
}
layer {
  name: "loss3/top-1"
  type: "Accuracy"
  bottom: "fc8_flickr"
  bottom: "label"
  top: "loss3/top-1"
  include {
    phase: TRAIN     # 这里改成train 每次都可以输出正确率了
  }
}

在修改完solver 和train_val 之后,就可以尝试train了
进入caffe 根目录

./build/tools/caffe train -solver /path/to solver -weights /path/to/yourname.caffemodel

要是训练到一半退出了,caffe会保存一个snapshot,我们可以重新恢复训练

./build/tools/caffe train -solver /path/to solver -snapshot /path/to/yourname.solverstate

下一篇将会介绍caffe 的python接口 和可视化测试

你可能感兴趣的:(caffe)