训练自己特定的图片及预测单张图片(仅CPU)

最近自己琢磨caffe,主要参考了博主徐其华denny的学习专栏,http://www.cnblogs.com/denny402/p/5083300.html,接下来的过程基本是按照他的步骤进行的。

好记性不如烂笔头,虽然对深度学习的了解才刚刚开始,但还是希望能记录点滴学习过程。以下是我训练自己的图片的过程,正确率只有0.333,可能是样本源的选择不好,但总算是训练出精度了,所以记录一下。

以下所有操作都是在caffe根目录下进行,否则都会出错。

我根据http://www.2cto.com/kf/201606/515700.html博主提供的数据(共10类1000张train,200test)训练36h后得到0.545的精度,训练时间太长(是跟电脑配置有关?),网上博主使用上面的配置训练,得到的结果准确率是0.2+,数据集的制作者迭代了12000次得到0.5的准确率。参数配置如下所示:


net: "examples/303file/train_val.prototxt"
test_iter: 4
test_interval: 300
base_lr: 0.001
lr_policy: "step"
gamma: 0.1
stepsize: 300
display: 20
max_iter: 1200
momentum: 0.9
weight_decay: 0.0005
snapshot:600
snapshot_prefix:"/home/jenny/caffe/examples/303file/"
solver_mode: CPU

我主要目的是想对高压输电线上的三种金具(防震锤,间隔器,悬垂线夹)进行分类,所以用摄像头拍摄了一段视频截取了部分图片,图片背景比较昏暗,而且防震锤与悬垂线夹的差别不大,不知这是不是精度较低的原因。
总共300张图片,包括240张train,60张test,分三类,编号分别以1,3,5开头,每类80张训练,20张测试,图片大小为512*684。我将图片放在caffe根目录下的data文件夹下面。即训练图片目录:data/obstacle/train/ ,测试图片目录: data/obstacle/test/



二、转换lmdb格式


具体转换过程可参考denny博主的http://www.cnblogs.com/denny402/p/5082341.html
在examples下面创建一个jennyfile的文件夹,来用存放配置文件和脚本文件。然后编写一个脚本create_filelist.sh,用来生成train.txt和test.txt清单文件


sudo mkdir examples/jennyfile
sudo vi examples/jennyfile/create_filelist.sh


编辑此文件,写入如下代码,并按Esc键,再按冒号:wq保存


#!/usr/bin/env sh
DATA=data/obstacle/
MY=examples/jennyfile

echo "Create train.txt..."
rm -rf $MY/train.txt
for i in 1 3 5
do
find $DATA/train -name $i*.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/">>$MY/train.txt
done
echo "Create test.txt..."
rm -rf $MY/test.txt
for i in 1 3 5
do
find $DATA/test -name $i*.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/">>$MY/test.txt
done
echo "All done"
然后,运行此脚本

sudo sh examples/jennyfile/create_filelist.sh

成功的话,就会在examples/jennyfile/ 文件夹下生成train.txt和test.txt两个文本文件,里面就是图片的列表清单。(此处需要注意的是图片名称与类别数字之间是一个空格,我之前遇到过can't find or open xxx.jpg的错误,原因就是中间是tab键而不是空格键,改过后就OK了)

接着再编写一个脚本文件,调用convert_imageset命令来转换数据格式。

sudo vi examples/jennyfile/create_lmdb.sh


插入代码如下:

#!/usr/bin/env sh
MY=examples/jennyfile

echo "Create train lmdb.."
rm -rf $MY/img_train_lmdb
build/tools/convert_imageset \
--shuffle \
--resize_height=256 \
--resize_width=256 \
/home/jenny/caffe/data/obstacle/ \
$MY/train.txt \
$MY/img_train_lmdb

echo "Create test lmdb.."
rm -rf $MY/img_test_lmdb
build/tools/convert_imageset \
--shuffle \
--resize_width=256 \
--resize_height=256 \
/home/jenny/caffe/data/obstacle/ \
$MY/test.txt \
$MY/img_test_lmdb
因为图片大小不一,因此我统一转换成256*256大小。运行成功后,会在 examples/jennyfile下面生成两个文件夹img_train_lmdb和img_test_lmdb,分别用于保存图片转换后的lmdb文件。



三、计算均值并保存

图片减去均值再训练,会提高训练速度和精度。因此,一般都会有这个操作。

caffe程序提供了一个计算均值的文件compute_image_mean.cpp,我们直接使用就可以了

sudo build/tools/compute_image_mean examples/jennyfile/img_train_lmdb examples/jennyfile/mean.binaryproto

compute_image_mean带两个参数,第一个参数是lmdb训练数据位置,第二个参数设定均值文件的名字及保存路径。
运行成功后,会在 examples/jennyfile/ 下面生成一个mean.binaryproto的均值文件(一定要保证均值文件生成成功,检查它的大小)。


四、创建模型并编写配置文件

模型就用程序自带的caffenet模型,位置在 models/bvlc_reference_caffenet/文件夹下, 将需要的两个配置文件,复制到jennyfile文件夹内


sudo cp models/bvlc_reference_caffenet/solver.prototxt examples/myfile/
sudo cp models/bvlc_reference_caffenet/train_val.prototxt examples/myfile/


修改其中的solver.prototxt

sudo vi examples/jennyfile/solver.prototxt


更改为如下参数:

net: "examples/jennyfile/train_val.prototxt"
test_iter:60
test_interval: 40
base_lr: 0.0001
lr_policy: "step"
gamma:0.1
stepsize:50
display: 10
max_iter: 100
momentum: 0.9
snapshot:50
snapshot_prefix:"/home/jenny/caffe/examples/jennyfile/"
weight_decay: 0.005
solver_mode: CPU

60个测试数据,batch_size为1,因此test_iter设置为60就能全cover了(这两个参数调整了多次,每次训练都不太理想,所以最后将batch_size设为1)。在训练过程中,调整学习率,逐步变小。
修改train_val.protxt,只需要修改两个阶段的data层就可以了,其他可以不用管。


name:"CaffeNet"
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size: 227
    mean_file: "examples/jennyfile/mean.binaryproto"
  }
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: true
#  }
  data_param {
    source: "examples/jennyfile/img_train_lmdb"
    batch_size: 60
    backend: LMDB
  }
}
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    mirror: false
    crop_size: 227
    mean_file: "examples/jennyfile/mean.binaryproto"
  }
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: false
#  }
  data_param {
    source: "examples/jennyfile/img_test_lmdb"
    batch_size:1
    backend: LMDB
  }
}


除了修改两个Data layer的mean_file和source这两个地方,还要修改最后一个全连接层fc8的num_output参数,你训练的有几类就改为几类,我改为了3类。

layer {
  name: "fc8"
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc8"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 3
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}

五、训练和测试

如果前面都没有问题,数据准备好了,配置文件也配置好了,这一步就比较简单。在终端输入:

sudo build/tools/caffe train -solver examples/jennyfile/solver.prototxt


运行时间和最后的精确度会根据机器配置、参数配置的不同而不同。我的是仅CPU运行100次,大约50分钟,精度为0.333,LOSS为1.32062.训练完成后会生成_iter_100.caffemodel和_iter_100.solverstate两个文件,接下来用一个训练好的caffemodel来对一张新的图片进行分类。(在训练的时候一直出现Restarting data prefetching from start,此时需要耐心等待,我有时候出现三四次,历时30min才会显示下一次)

六、用训练好的caffemodel来分类


此步骤需要三个文件,caffemodel文件、均值文化和label.txt文件,其中caffemodel文件是训练好后保存的模型文件,在测试阶段,需要把测试数据减去均值mean.binaryproto,label.txt文件中存放的是各个类的名称,比如的这次分类较少只有三类,所以我可以手动完成。如果类别太多,必须要批量处理了。



数据准备好了,我们就可以开始分类了,我采用的是C++方法。
在caffe根目录下的 examples/cpp-classification/ 文件夹下面,有个classification.cpp文件,就是用来分类的。当然编译后,放在/build/examples/cpp_classification/ 下面
我们可以直接运行命令或者写个脚本文件

sudo vi examples/jennyfile/testonepicture.sh
打开sh文件后插入如下代码:

sudo .build/examples/cpp_classification/classification.bin \
  examples/jennyfile/deploy.prototxt \
  examples/jennyfile/_iter_100.caffemodel \
  examples/jennyfile/mean.binaryproto \
  examples/jennyfile/labels.txt \
  examples/images/jgq.jpg


其中jgq.jpg图片是我另找的一张间隔器图片,




最后得到的测试结果为0.3391的可能性为间隔器:


这次测试的精度很不理想,参数也没有仔细调,但是完整地走了一遍,最大的感受就是不要放弃。接下来就是学会调参,想办法提高精度。
caffe入门我主要是学习denny的学习专栏,非常感谢博主,里面有一系列的博文,http://www.cnblogs.com/denny402/tag/caffe/ 有兴趣的可以看看。



千里之行,始于足下,fighting!




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章