人脸识别---利用caffe实现多层特征学习人脸识别网络

来源:互联网 发布:32bit安装tensorflow 编辑:程序博客网 时间:2024/04/30 10:33

摘要:本文主要讲解如何利用caffe搭建自己的网络,本文主要讲利用caffe搭建一种Hierarchical Feature Representation的网络。网络如下图:

这里写图片描述

数据库:CASIA-WebFace数据集,可以到我的网盘中下载:http://pan.baidu.com/s/1nuWsju5。在我的试验中我选用1000人的样本训练,在CASIA-WebFace数据中1000人包含图片最多,大概加起来有10W+的数据。

参看上篇博文:http://blog.csdn.net/hlx371240/article/details/51388022

1. 建立训练集和验证集
配置好ourfaceNet中的路径,执行ourfaceNet可以得到两个文件夹face_train_lmdb和face_val_lmdbface_val_lmdb.
ourfaceNet.sh

#!/usr/bin/env sh# Create the imagenet lmdb inputs# N.B. set the path to the imagenet train + val data dirsEXAMPLE=facenetDATA=facenetTOOLS=./build/toolsTRAIN_DATA_ROOT=ourfacenet/data/VAL_DATA_ROOT=ourfacenet/data/# Set RESIZE=true to resize the images to 256x256. Leave as false if images have# already been resized using another tool.RESIZE=trueif $RESIZE; then  RESIZE_HEIGHT=128  RESIZE_WIDTH=128else  RESIZE_HEIGHT=0  RESIZE_WIDTH=0fiif [ ! -d "$TRAIN_DATA_ROOT" ]; then  echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"  echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \       "where the ImageNet training data is stored."  exit 1fiif [ ! -d "$VAL_DATA_ROOT" ]; then  echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"  echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \       "where the ImageNet validation data is stored."  exit 1fiecho "Creating train lmdb..."GLOG_logtostderr=1 $TOOLS/convert_imageset.bin \    --resize_height=$RESIZE_HEIGHT \    --resize_width=$RESIZE_WIDTH \    --shuffle \    $TRAIN_DATA_ROOT \    $DATA/train.txt \    $EXAMPLE/face_train_lmdb1echo "Creating val lmdb..."GLOG_logtostderr=1 $TOOLS/convert_imageset.bin \    --resize_height=$RESIZE_HEIGHT \    --resize_width=$RESIZE_WIDTH \    --shuffle \    $VAL_DATA_ROOT \    $DATA/val.txt \    $EXAMPLE/face_val_lmdb1echo "Done."
  1. 求均值文件
    make_mean.sh
EXAMPLE=facenetDATA=facenetTOOLS=./build/tools$TOOLS/compute_image_mean $EXAMPLE/face_train_lmdb \  $DATA/face_mean.binaryprotoecho "Done."

这样可以得到face_mean.binaryproto

3.根据上图搭建自己的框架
我搭建的是分层式的网络,可以得到卷积层具有区分性的特征
train_val.prototxt

name: "train_val.prototxt"layer {  name: "data"  type: "Data"  top: "data"  top: "label"  include {    phase: TRAIN  }  transform_param {    mirror: true    crop_size: 128    mean_file: "facenet/face_mean.binaryproto"  }  data_param {    source: "facenet/face_train_lmdb"    batch_size: 50    backend: LMDB  }}layer {  name: "data"  type: "Data"  top: "data"  top: "label"  include {    phase: TEST  }  transform_param {    mirror: false    crop_size: 128    mean_file: "facenet/face_mean.binaryproto"  }  data_param {    source: "facenet/face_val_lmdb"    batch_size: 50    backend: LMDB  }}layer {  name: "conv1/7x7_s2"  type: "Convolution"  bottom: "data"  top: "conv1/7x7_s2"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 40    pad: 3    kernel_size: 7    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0.2    }  }}layer {  name: "conv1/relu_7x7"  type: "ReLU"  bottom: "conv1/7x7_s2"  top: "conv1/7x7_s2"}layer {  name: "pool1/3x3_s2"  type: "Pooling"  bottom: "conv1/7x7_s2"  top: "pool1/3x3_s2"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}layer {  name: "pool1/norm1"  type: "LRN"  bottom: "pool1/3x3_s2"  top: "pool1/norm1"  lrn_param {    local_size: 5    alpha: 0.0001    beta: 0.75  }}layer {  name: "conv2/7x7_s2"  type: "Convolution"  bottom: "pool1/norm1"  top: "conv2/7x7_s2"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 40    pad: 2    kernel_size: 5    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0.2    }  }}layer {  name: "conv2/relu_7x7"  type: "ReLU"  bottom: "conv2/7x7_s2"  top: "conv2/7x7_s2"}layer {  name: "pool2/3x3_s2"  type: "Pooling"  bottom: "conv2/7x7_s2"  top: "pool2/3x3_s2"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}layer {  name: "loss1/classifier"  type: "InnerProduct"  bottom: "pool2/3x3_s2"  top: "loss1/classifier"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  inner_product_param {    num_output: 1000    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0    }  }}layer {  name: "loss1/loss"  type: "SoftmaxWithLoss"  bottom: "loss1/classifier"  bottom: "label"  top: "loss1/loss1"  loss_weight: 0.3}layer {  name: "loss1/top-1"  type: "Accuracy"  bottom: "loss1/classifier"  bottom: "label"  top: "loss1/top-1"  include {    phase: TEST  }}layer {  name: "loss2/conv"  type: "Convolution"  bottom: "pool1/norm1"  top: "loss2/conv"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 40    pad: 2    kernel_size: 5    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0.2    }  }}layer {  name: "loss2/relu_conv"  type: "ReLU"  bottom: "loss2/conv"  top: "loss2/conv"}layer {  name: "loss2/pool"  type: "Pooling"  bottom: "loss2/conv"  top: "loss2/pool"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}layer {  name: "loss2/classifier"  type: "InnerProduct"  bottom: "loss2/pool"  top: "loss2/classifier"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  inner_product_param {    num_output: 1000    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0    }  }}layer {  name: "loss2/loss"  type: "SoftmaxWithLoss"  bottom: "loss2/classifier"  bottom: "label"  top: "loss2/loss1"  loss_weight: 0.3}layer {  name: "loss2/top-1"  type: "Accuracy"  bottom: "loss2/classifier"  bottom: "label"  top: "loss2/top-1"  include {    phase: TEST  }}layer {  name: "loss3/conv"  type: "Convolution"  bottom: "loss2/pool"  top: "loss3/conv"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 40    pad: 2    kernel_size: 5    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0.2    }  }}layer {  name: "loss3/relu_conv"  type: "ReLU"  bottom: "loss3/conv"  top: "loss3/conv"}layer {  name: "loss3/pool"  type: "Pooling"  bottom: "loss3/conv"  top: "loss3/pool"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}layer {  name: "loss3/classifier"  type: "InnerProduct"  bottom: "loss3/pool"  top: "loss3/classifier"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  inner_product_param {    num_output: 1000    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0    }  }}layer {  name: "loss3/loss"  type: "SoftmaxWithLoss"  bottom: "loss3/classifier"  bottom: "label"  top: "loss3/loss1"  loss_weight: 0.3}layer {  name: "loss3/top-1"  type: "Accuracy"  bottom: "loss3/classifier"  bottom: "label"  top: "loss3/top-1"  include {    phase: TEST  }}layer {  name: "loss4/conv"  type: "Convolution"  bottom: "loss3/pool"  top: "loss4/conv"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  convolution_param {    num_output: 40    pad: 2    kernel_size: 5    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0.2    }  }}layer {  name: "loss4/relu_conv"  type: "ReLU"  bottom: "loss4/conv"  top: "loss4/conv"}layer {  name: "loss4/pool"  type: "Pooling"  bottom: "loss4/conv"  top: "loss4/pool"  pooling_param {    pool: MAX    kernel_size: 2    stride: 2  }}layer {  name: "loss4/fc"  type: "InnerProduct"  bottom: "loss4/pool"  top: "loss4/fc"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  inner_product_param {    num_output: 1024    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0.2    }  }}layer {  name: "loss4/relu_fc"  type: "ReLU"  bottom: "loss4/fc"  top: "loss4/fc"}layer {  name: "loss4/drop_fc"  type: "Dropout"  bottom: "loss4/fc"  top: "loss4/fc"  dropout_param {    dropout_ratio: 0.7  }}layer {  name: "loss4/classifier"  type: "InnerProduct"  bottom: "loss4/fc"  top: "loss4/classifier"  param {    lr_mult: 1    decay_mult: 1  }  param {    lr_mult: 2    decay_mult: 0  }  inner_product_param {    num_output: 1000    weight_filler {      type: "xavier"    }    bias_filler {      type: "constant"      value: 0    }  }}layer {  name: "loss4/loss"  type: "SoftmaxWithLoss"  bottom: "loss4/classifier"  bottom: "label"  top: "loss4/loss1"  loss_weight: 1}layer {  name: "loss4/top-1"  type: "Accuracy"  bottom: "loss4/classifier"  bottom: "label"  top: "loss4/top-1"  include {    phase: TEST  }}

4. 接下来就是写自己的solver.prototxt
solver1.prototxt

net: "facenet/train_val.prototxt"test_iter: 1000test_interval: 4000test_initialization: falsedisplay: 100average_loss: 100base_lr: 0.005lr_policy: "step"stepsize: 320000gamma: 0.96max_iter: 100000momentum: 0.9weight_decay: 0.0002snapshot: 4000snapshot_prefix: "facenet/face_model"solver_mode: GPU

solver2.prototxt

net: "facenet/train_val.prototxt"test_iter: 1000test_interval: 4000test_initialization: falsedisplay: 100average_loss: 100base_lr: 0.001lr_policy: "step"stepsize: 320000gamma: 0.96max_iter: 100000momentum: 0.9weight_decay: 0.0002snapshot: 4000snapshot_prefix: "facenet/face_model"solver_mode: GPU

solver3.prototxt

net: "facenet/train_val.prototxt"test_iter: 1000test_interval: 4000test_initialization: falsedisplay: 100average_loss: 100base_lr: 0.0001lr_policy: "step"stepsize: 320000gamma: 0.96max_iter: 100000momentum: 0.9weight_decay: 0.0002snapshot: 4000snapshot_prefix: "facenet/face_model"solver_mode: GPU

包括了三个solver.prototxt,三个solver.prototxt有不同的学习率,都学习了10w次迭代。

5.建立自己的训练脚本

./build/tools/caffe train \    --solver=facenet/solver.prototxt \./build/tools/caffe train \    --solver=facenet/solver.prototxt \    --weights=facenet/face_model_iter_100000.caffemodel -gpu=0./build/tools/caffe train \    --solver=facenet/solver.prototxt \    --weights=facenet/face_model_iter_200000.caffemodel -gpu=0

最后执行各个脚本就可以把自己的网络搭建起来了。当然我们可以根据自己的需求去搭建我们的网络,我们只要记住name,top,bottom这三个就可以轻松搭建任意的网络去完成我们的任务。

0 0
原创粉丝点击