人脸识别---利用caffe实现多层特征学习人脸识别网络
2016-10-31 10:13
736 查看
摘要:本文主要讲解如何利用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
求均值文件
make_mean.sh
这样可以得到face_mean.binaryproto
3.根据上图搭建自己的框架
我搭建的是分层式的网络,可以得到卷积层具有区分性的特征
train_val.prototxt
4. 接下来就是写自己的solver.prototxt
solver1.prototxt
solver2.prototxt
solver3.prototxt
包括了三个solver.prototxt,三个solver.prototxt有不同的学习率,都学习了10w次迭代。
5.建立自己的训练脚本
最后执行各个脚本就可以把自己的网络搭建起来了。当然我们可以根据自己的需求去搭建我们的网络,我们只要记住name,top,bottom这三个就可以轻松搭建任意的网络去完成我们的任务。
数据库: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 dirs EXAMPLE=facenet DATA=facenet TOOLS=./build/tools TRAIN_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=true if $RESIZE; then RESIZE_HEIGHT=128 RESIZE_WIDTH=128 else RESIZE_HEIGHT=0 RESIZE_WIDTH=0 fi if [ ! -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 1 fi if [ ! -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 1 fi echo "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_lmdb1 echo "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_lmdb1 echo "Done."
求均值文件
make_mean.sh
EXAMPLE=facenet DATA=facenet TOOLS=./build/tools $TOOLS/compute_image_mean $EXAMPLE/face_train_lmdb \ $DATA/face_mean.binaryproto echo "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: 1000 test_interval: 4000 test_initialization: false display: 100 average_loss: 100 base_lr: 0.005 lr_policy: "step" stepsize: 320000 gamma: 0.96 max_iter: 100000 momentum: 0.9 weight_decay: 0.0002 snapshot: 4000 snapshot_prefix: "facenet/face_model" solver_mode: GPU
solver2.prototxt
net: "facenet/train_val.prototxt" test_iter: 1000 test_interval: 4000 test_initialization: false display: 100 average_loss: 100 base_lr: 0.001 lr_policy: "step" stepsize: 320000 gamma: 0.96 max_iter: 100000 momentum: 0.9 weight_decay: 0.0002 snapshot: 4000 snapshot_prefix: "facenet/face_model" solver_mode: GPU
solver3.prototxt
net: "facenet/train_val.prototxt" test_iter: 1000 test_interval: 4000 test_initialization: false display: 100 average_loss: 100 base_lr: 0.0001 lr_policy: "step" stepsize: 320000 gamma: 0.96 max_iter: 100000 momentum: 0.9 weight_decay: 0.0002 snapshot: 4000 snapshot_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这三个就可以轻松搭建任意的网络去完成我们的任务。
相关文章推荐
- 深度学习项目示例-采用caffe实现LENET网络实现铲齿识别-并可视化过程
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图 .
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图
- 利用OpenCV的Haar特征目标检测方法进行人脸识别的尝试(一)
- AdaBoost利用haar-like特征做人脸识别(2)
- 深度学习(十七)基于改进Coarse-to-fine CNN网络的人脸特征点定位-ICCV 2013
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结2——级联分类器与检测过程
- PCA人脸识别学习及C语言实现
- 【Caffe实践】基于Caffe的人脸识别实现
- Haar特征原理与icvCreateIntHaarFeatures方法的具体实现附详细注释—— 人脸识别的尝试系列(二)
- 【Caffe实践】基于Caffe的人脸识别实现
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结2——级联分类器与检测过程 .
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结2——级联分类器与检测过程
- (链接) AdaBoost中利用Haar特征进行人脸识别算法分析与总结
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图
- 利用网络短信验证码接口实现手机短信轰炸 (历史代码,贴出学习)
- 深度学习系列(八):自编码网络多层特征学习
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结2——级联分类器与检测过程