caffe入门-人脸检测1
最近刚入门caffe,跟着视频做了一个简单人脸检测。包括人脸二分类模型+方框框出人脸。
人脸二分类模型
1. 收集数据
我用的是lfw数据集,总共有13233张人脸图片。非人脸数据有两种选择。1. 用完全不是人脸的图片;2. 用与人脸重叠比例较小的图片。我用的是动物的图片作为负样本。负样本数据集。
2. 制作LMDB数据源(caffe非常支持的常用于分类的数据源)
首先需要写两个txt文档。train.txt 和 val.txt
主要保存的是图片的路径、名称、label。
形如:train.txt
0/xxx.jpg 0
1/xxx.jpg 1
val.txt
0/xxx.jpg 0
1/xxx.jpg 1
其中0文件夹表示正样本(人脸)、1文件夹表示负样本(非人脸)
如果是多分类,文件夹名称也是从0开始
生成txt文本的python代码(linux和Windows下的代码有点不同):
linux版。jupyter notebook作为编译器
import os
#定义Caffe根目录 caffe_root = '/home/z/work/face_detect/' # 制作训练标签数据 i = 0 # 标签 with open(caffe_root + 'train.txt', 'w') as train_txt: for root, dirs, files in os.walk(caffe_root + 'train/'): # 遍历文件夹 for dir in dirs: for root, dirs, files in os.walk(caffe_root + 'train/' + str(dir)): # 遍历每一个文件夹中的文件 for file in files: image_file = str(dir) + '/' + str(file) label = image_file + ' ' + str(i) + '\n' # 文件路径+空格+标签编号+换行 train_txt.writelines(label) # 写入标签文件中 i += 1 # 编号加1 # 制作测试标签数据 i = 0 # 标签 with open(caffe_root + 'val.txt', 'w') as val_txt: for root, dirs, files in os.walk(caffe_root + 'val/'): # 遍历文件夹 for dir in dirs: for root, dirs, files in os.walk(caffe_root + 'val/' + str(dir)): # 遍历每一个文件夹中的文件 for file in files: image_file = str(dir) + '/' + str(file) label = image_file + ' ' + str(i) + '\n' # 文件路径+空格+标签编号+换行 val_txt.writelines(label) # 写入标签文件中 i += 1 # 编号加1 print('成功生成文件列表')
两个txt文件创建后,使用caffe提供create_imagenet.sh。当然需要修改。前几行改成自己的安装目录。还要进行一个resize操作,比如ALEXNET或者VGG通常都是给它resize 227*227. 我的文件是face_lmdb.sh
EXAMPLE=/home/z/work/face_detect DATA=/home/z/work/face_detect TOOLS=/home/z/caffe/build/tools TRAIN_DATA_ROOT=/home/z/work/face_detect/train/ VAL_DATA_ROOT=/home/z/work/face_detect/val/ # 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=227 RESIZE_WIDTH=227 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 \ --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH \ --shuffle \ $TRAIN_DATA_ROOT \ $DATA/train.txt \ $EXAMPLE/face_train_lmdb echo "Creating val lmdb..." GLOG_logtostderr=1 $TOOLS/convert_imageset \ --resize_height=$RESIZE_HEIGHT \ --resize_width=$RESIZE_WIDTH \ --shuffle \ $VAL_DATA_ROOT \ $DATA/val.txt \ $EXAMPLE/face_val_lmdb echo "Done."
命令行输入:sh LMDB脚本文件。
3. 训练模型
使用的是AlEXNET,当然用其他的网络也可以,比如VGG。主要是电脑配置比较差,使用cpu跑的,人脸数据集也没有全部使用。
只是为了跑通上述流程。我的训练集使用了1000张人脸,1000张非人脸。测试集使用600张人脸,600张非人脸。生成的LMDB数据源。
1. 网络模型文件train_val.prototxt.
要改的地方不多。数据来源、batch_size、最后全连接层的num_output该为2(2分类)
name: "AlexNet" layer { name: "data" type: "Data" top: "data" top: "label" include { phase: TRAIN } transform_param { mirror: true crop_size: 227 #mean_file: "data/ilsvrc12/imagenet_mean.binaryproto" } data_param { source: "/home/z/work/face_detect/face_train_lmdb" batch_size: 16 backend: LMDB } } layer { name: "data" type: "Data" top: "data" top: "label" include { phase: TEST } transform_param { mirror: false crop_size: 227 #mean_file: "data/ilsvrc12/imagenet_mean.binaryproto" } data_param { source: "/home/z/work/face_detect/face_val_lmdb" batch_size: 16 backend: LMDB } }
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: 2 weight_filler { type: "gaussian" std: 0.01 } bias_filler { type: "constant" value: 0 } } }
2. 参数配置文件solver.prototxt
net: "/home/z/work/face_detect/train_val.prototxt" test_iter: 20 test_interval: 1000 base_lr: 0.001 lr_policy: "step" gamma: 0.1 stepsize: 2000 display: 20 max_iter: 450000 momentum: 0.9 weight_decay: 0.0005 snapshot: 1000 snapshot_prefix: "/home/z/work/face_detect/model" solver_mode: CPU
3. 训练脚本train.sh
#!/usr/bin/env sh /home/z/caffe/build/tools/caffe train --solver=/home/z/work/face_detect/solver.prototxt