dlunion caffe训练MTCNN

dlunion caffe训练MTCNN

前言

如果你想训练mtcnn,但对框架没要求的话,建议选择tensorflow这个版本的,坑少,代码明晰,基本不用修改,而且训练效果好Tensorflow训练MTCNN
上一个博文caffe训练MTCNN的项目,每一次迭代分类和回归只能随机训练其中一个,感觉有点别扭
ConWeilin caffe训练MTCNN
于是又尝试了另外一个caffe工程
参考github

P-Net数据集准备和网络训练

1、将准备好的数据集,替代./samples/WIDER_train这个文件夹,./samples/wider_face_train.txt是其对应的标签文件,执行

python gen_12data.py

2、在当前目录下生成12文件夹,文件夹存放negative,part,positive三个文件夹和对应的标签文本。
目录进入12文件夹下
分别执行

python gen_12net_list.py
#用来生成总的标签文本label-train.txt
sh ./create_data.sh
#转化成lmdb格式的训练数据

gen_12net_list.py这个文件是工程目录里本来就有的
create_data.sh代码如下:

#!/usr/bin/env sh
export PYTHONPATH=$PYTHONPATH:/home/caffe/mtcnn-new/samples/native_12
set -e

EXAMPLE=/home/caffe/mtcnn_new/samples
DATA=/home/caffe/mtcnn_new/samples/native_12
TOOLS=/home/caffe/build/tools

CLS_DATA_ROOT=/home/caffe/mtcnn_new/samples/

GLOG_logtostderr=1 $TOOLS/convert_imageset_multi \
  $CLS_DATA_ROOT \
  $DATA/label-train.txt \
  $EXAMPLE/lmdb12 

echo "Creating lmdb12..."

2.1、同时强调一下,caffe自带的$TOOLS/convert_imageset生成lmdb文件只支持单标签,上述代码中的convert_imageset_multi是修改只有重新编译的caffe接口,具体的方法见wwww1244的这篇博文,这个阿婆主一步步写的很清楚,照做就行了,不难。
3、最后生成的lmdb12文件就是用来训练P-Net的数据啦!
训练P-Net所有的文件都在./12这个文件夹里
在这里插入图片描述
12,24,48分别存放训练网络的文件,samples存放数据
进入12目录下
在这里插入图片描述
3.1、LOG是记录训练日志的文件
3.2、models-12是存放训练模型的地方
3.3、det1-train.prototxt是网络结构文件
(1)MTCNNData和MTCNNEuclideanLoss是原工程作者自己编译的层,但是链接已经失效,无法找到源文件
(2)Caffe自带的Data层只允许单标签输出
所以,需要修改数据输入层,将标签进行分割,修改之后的网络文件如下:

name: "PNet"
layer {
name: "data"
type: "Data"
top: "data"
top: "label"
transform_param {
  mirror: false
  mean_value: 127.5
  scale: 0.0078125
  #crop_size: 12
}
data_param {
  source: "../samples/lmdb12"
  label_num: 5
  batch_size: 64
  backend: LMDB
}
}
layer {
name: "slice"
type: "Slice"
bottom: "label"
top: "cls"
top: "roi"
include { 
  phase: TRAIN
}
slice_param {
  axis: 1
  slice_point: 1
}
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 10
  kernel_size: 3
  stride: 1
  weight_filler {
    type: "xavier"
  }
  bias_filler {
    type: "constant"
    value: 0
  }
}
}
layer {
name: "PReLU1"
type: "PReLU"
bottom: "conv1"
top: "conv1"
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
  pool: MAX
  kernel_size: 2
  stride: 2
}
}

layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 16
  kernel_size: 3
  stride: 1
   weight_filler {
    type: "xavier"
  }
  bias_filler {
    type: "constant"
    value: 0
  }
}
}
layer {
name: "PReLU2"
type: "PReLU"
bottom: "conv2"
top: "conv2"
}

layer {
name: "conv3"
type: "Convolution"
bottom: "conv2"
top: "conv3"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 32
  kernel_size: 3
  stride: 1
   weight_filler {
    type: "xavier"
  }
  bias_filler {
    type: "constant"
    value: 0
  }
}
}
layer {
name: "PReLU3"
type: "PReLU"
bottom: "conv3"
top: "conv3"
}


layer {
name: "conv4-1"
type: "Convolution"
bottom: "conv3"
top: "conv4-1"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 2
  kernel_size: 1
  stride: 1
   weight_filler {
    type: "xavier"
  }
  bias_filler {
    type: "constant"
    value: 0
  }
}
}

layer {
name: "cls_loss"
type: "SoftmaxWithLoss"
bottom: "conv4-1"
bottom: "cls"
top: "cls_loss"
propagate_down: 1
propagate_down: 0
loss_weight: 1
loss_param{
  ignore_label: -1
}
}

layer {
name: "cls_Acc"
type: "Accuracy"
bottom: "conv4-1"
bottom: "cls"
top: "cls_acc"
include {
  phase: TRAIN
}
accuracy_param{
  ignore_label: -1
}
}


layer {
name: "conv4-2"
type: "Convolution"
bottom: "conv3"
top: "conv4-2"
param {
  lr_mult: 1
  decay_mult: 1
}
param {
  lr_mult: 2
  decay_mult: 0
}
convolution_param {
  num_output: 4
  kernel_size: 1
  stride: 1
   weight_filler {
    type: "xavier"
  }
  bias_filler {
    type: "constant"
    value: 0
  }
}
}
layer {
name: "roi_loss"
type: "EuclideanLoss"
bottom: "conv4-2"
bottom: "roi"
top: "roi_loss"
loss_weight: 0.5
loss_param{
  ignore_label: 0
}
}

3.4、det1.caffemodel是预训练模型,帮助快速收敛
3.5、slover-12.prototxt是网络参数文件/3
3.6、train12.sh是训练脚本
训练脚本代码如下:

#!/usr/bin/env sh
export PYTHONPATH=$PYTHONPATH:/home/caffe/mtcnn-new/12/
LOG=./LOG/train-`date +%Y-%m-%d-%H-%M-%S`.log
set -e
~/caffe/build/tools/caffe train \
   --solver=./solver-12.prototxt --weights=./det1.caffemodel 2>&1 | tee $LOG

日志文件和权重可以选择加或不加
最后P-Net训练损失曲线如下:
dlunion caffe训练MTCNN_第1张图片
dlunion作者训练并没有用hard examples,所以训练R-Net,O-Net就和P-Net类似,不再多叙述。
但是因为没有使用hard examples,就感觉不够完美,下一篇将添上使用hard examples训练训练R-Net,O-Net的步骤。

你可能感兴趣的:(MTCNN)