基于人脸识别+IMDB-WIFI+Caffe的性别识别
本文用记录基于Caffe的人脸性别识别过程。基于imdb-wiki模型做finetune,imdb-wiki数据集合模型可从这里下载:https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/。
准备训练环境
(1)准备OS:Ubuntu16.04
(2)安装Nvidia GPU Driver
https://www.nvidia.com/Download/index.aspx?lang=en-us
(3)安装CUDA
https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html
查看cuda版本的方法:
cat /usr/local/cuda/version.txt
(4)安装cnDNN(可选)
https://docs.nvidia.com/deeplearning/sdk/cudnn-install/index.html
查看cudnn版本的方法:
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
(5)安装Docker(可选)
https://docs.docker.com/install/linux/docker-ce/ubuntu/#set-up-the-repository
(6)安装Nvidia Docker(可选)
https://github.com/NVIDIA/nvidia-docker
(7)准备Docker Image(可选)
进入Container的方式之一:,
nvidia-docker exec -it $ContainerID /bin/bash
用nvidia-docker ps查看ContainerID。
准备模型及训练数据集
(1) 下载Imdb-wiki模型
https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/static/gender.caffemodel
https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/static/gender_train.prototxt
如果下载了imdb-wiki的数据集,可以通过如下方式读取数据集的描述文件:
import scipy.io as sio
mat_contents = sio.loadmat('wiki.mat')
(2) 下载celeba数据集
CelebA是CelebFaces Attribute的缩写,意即名人人脸属性数据集,其包含10,177个名人身份的202,599张人脸图片,每张图片都做好了特征标记,包含人脸bbox标注框、5个人脸特征点坐标以及40个属性标记,CelebA由香港中文大学开放提供,广泛用于人脸相关的计算机视觉训练任务,可用于人脸属性标识训练、人脸检测训练以及landmark标记等,可以从http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html下载img_align_celeba.zip即可。
(3) 生成celeba数据集的训练和测试描述文件
删除list_attr_celeba文件第一行后,提取性别属性:
cat list_attr_celeba | awk -F ' ' '{print $1,$22}' >gender.txt
计算图片文件数量:
cat list_attr_celeba | wc -l
对gender.txt文件行做shuffle:
cat gender.txt | awk -F"\3" 'BEGIN{srand();}{value=int(rand()*图片文件数量); print value"\3"$0 }' | sort | awk -F"\3" '{print $2}' >> shuffled
生成训练集:
head -n 图片文件数量*0.9 shuffled > train.txt
tail -n 图片文件数量*0.1 shuffled > test.txt
修改图片路径可能用到的VI命令:1,$ s/old/new/g
(4) 为了更好的识别亚洲人的性别,还可以通过爬取等方式收集标注来补充亚洲人的数据。
训练模型
(1)准备solver.prototxt
Solver文件解释可参考:
https://github.com/BVLC/caffe/wiki/Solver-Prototxt
(更全面)https://zhuanlan.zhihu.com/p/48462756
net: “gender.prototxt” test_iter: 100 test_interval: 500 test_compute_loss: true base_lr: 0.00001 momentum: 0.95 type: “SGD” weight_decay: 0.0005 lr_policy: “step” gamma: 0.9 stepsize: 200 display: 100 max_iter: 20000 snapshot: 2000 snapshot_prefix: “gender” solver_mode: GPU
(2) 修改gender.prototxt
name: "VGG_ILSVRC_16_layers"
layer {
top: "data"
type: "ImageData"
top: "label"
name: "data"
transform_param {
mirror: true
crop_size: 224
mean_file: "imagenet_mean.binaryproto"
}
image_data_param {
source: "train.txt"
batch_size: 32
new_height: 256
new_width: 256
}
include: { phase: TRAIN }
}
layer {
top: "data"
top: "label"
name: "data"
type: "ImageData"
image_data_param {
new_height: 256
new_width: 256
source: "train.txt"
batch_size: 10
}
transform_param {
crop_size: 224
mirror: false
mean_file: "imagenet_mean.binaryproto"
}
include: { phase: TEST }
}
layer {
bottom: "data"
top: "conv1_1"
name: "conv1_1"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv1_1"
top: "conv1_1"
name: "relu1_1"
type: "ReLU"
}
layer {
bottom: "conv1_1"
top: "conv1_2"
name: "conv1_2"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv1_2"
top: "conv1_2"
name: "relu1_2"
type: "ReLU"
}
layer {
bottom: "conv1_2"
top: "pool1"
name: "pool1"
type: "Pooling"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
bottom: "pool1"
top: "conv2_1"
name: "conv2_1"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 128
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv2_1"
top: "conv2_1"
name: "relu2_1"
type: "ReLU"
}
layer {
bottom: "conv2_1"
top: "conv2_2"
name: "conv2_2"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 128
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv2_2"
top: "conv2_2"
name: "relu2_2"
type: "ReLU"
}
layer {
bottom: "conv2_2"
top: "pool2"
name: "pool2"
type: "Pooling"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
bottom: "pool2"
top: "conv3_1"
name: "conv3_1"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 256
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv3_1"
top: "conv3_1"
name: "relu3_1"
type: "ReLU"
}
layer {
bottom: "conv3_1"
top: "conv3_2"
name: "conv3_2"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 256
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv3_2"
top: "conv3_2"
name: "relu3_2"
type: "ReLU"
}
layer {
bottom: "conv3_2"
top: "conv3_3"
name: "conv3_3"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 256
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv3_3"
top: "conv3_3"
name: "relu3_3"
type: "ReLU"
}
layer {
bottom: "conv3_3"
top: "pool3"
name: "pool3"
type: "Pooling"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
bottom: "pool3"
top: "conv4_1"
name: "conv4_1"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 512
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv4_1"
top: "conv4_1"
name: "relu4_1"
type: "ReLU"
}
layer {
bottom: "conv4_1"
top: "conv4_2"
name: "conv4_2"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 512
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv4_2"
top: "conv4_2"
name: "relu4_2"
type: "ReLU"
}
layer {
bottom: "conv4_2"
top: "conv4_3"
name: "conv4_3"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 512
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv4_3"
top: "conv4_3"
name: "relu4_3"
type: "ReLU"
}
layer {
bottom: "conv4_3"
top: "pool4"
name: "pool4"
type: "Pooling"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
bottom: "pool4"
top: "conv5_1"
name: "conv5_1"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 512
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv5_1"
top: "conv5_1"
name: "relu5_1"
type: "ReLU"
}
layer {
bottom: "conv5_1"
top: "conv5_2"
name: "conv5_2"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
type: "Convolution"
convolution_param {
num_output: 512
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv5_2"
top: "conv5_2"
name: "relu5_2"
type: "ReLU"
}
layer {
bottom: "conv5_2"
top: "conv5_3"
name: "conv5_3"
type: "Convolution"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 512
pad: 1
kernel_size: 3
}
}
layer {
bottom: "conv5_3"
top: "conv5_3"
name: "relu5_3"
type: "ReLU"
}
layer {
bottom: "conv5_3"
top: "pool5"
name: "pool5"
type: "Pooling"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
bottom: "pool5"
top: "fc6"
name: "fc6"
param {
lr_mult: 10
decay_mult: 1
}
param {
lr_mult: 20
decay_mult: 0
}
type: "InnerProduct"
inner_product_param {
num_output: 4096
}
}
layer {
bottom: "fc6"
top: "fc6"
name: "relu6"
type: "ReLU"
}
layer {
bottom: "fc6"
top: "fc6"
name: "drop6"
type: "Dropout"
dropout_param {
dropout_ratio: 0.5
}
}
layer {
bottom: "fc6"
top: "fc7"
name: "fc7"
param {
lr_mult: 10
decay_mult: 1
}
param {
lr_mult: 20
decay_mult: 0
}
type: "InnerProduct"
inner_product_param {
num_output: 4096
}
}
layer {
bottom: "fc7"
top: "fc7"
name: "relu7"
type: "ReLU"
}
layer {
bottom: "fc7"
top: "fc7"
name: "drop7"
type: "Dropout"
dropout_param {
dropout_ratio: 0.5
}
}
layer {
bottom: "fc7"
top: "fc8-2"
name: "fc8-2"
param {
lr_mult: 10
decay_mult: 1
}
param {
lr_mult: 20
decay_mult: 0
}
type: "InnerProduct"
inner_product_param {
num_output: 2
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
layer {
bottom: "fc8-2"
bottom: "label"
name: "loss"
type: "SoftmaxWithLoss"
include: { phase: TRAIN }
}
layer {
name: "prob"
type: "Softmax"
bottom: "fc8-2"
top: "prob"
include {
phase: TEST
}
}
layer {
name: "accuracy_train_top01"
type: "Accuracy"
bottom: "fc8-2"
bottom: "label"
top: "accuracy_train_top01"
include {
phase: TEST
}
}
imagenet_mean.binaryproto 文件的生成可参考https://github.com/BVLC/caffe/blob/master/examples/imagenet/make_imagenet_mean.sh
或直接从网上下载。
(3)启动训练
caffe train –sovler=pathto/solver.prototxt –weight=pathtto/gender.caffemodel –gpu all
(4)使用训练的模型
实际应用中,我们首先采用人脸检测技术检测人脸,将图片中的人脸取裁剪出来送入训练好的模型进行性别识别。人脸检测技术可以采用dlib库,dlib库人脸检测支持根据具体应用场景进行finetune。
基于人脸识别+IMDB-WIFI+Caffe的性别识别的更多相关文章
- C++开发人脸性别识别教程(5)——通过FaceRecognizer类实现性别识别
在之前的博客中已经攻克了人脸检測的问题,我们计划在这篇博客中介绍人脸识别.性别识别方面的相关实现方法. 事实上性别识别和人脸识别本质上是相似的,由于这里仅仅是一个简单的MFC开发,主要工作并不在算法研 ...
- C++开发人脸性别识别教程(16)——视频人脸性别识别
在之前的博文中我们已经可以顺利驱动摄像头来採集源图像.在这篇博文中将正式为其加入性别识别的代码,实现摄像头视频的人脸性别识别. 一.人脸检測 在得到摄像头採集的源图像之后,首先要做的就是对其进行人脸检 ...
- C++开发人脸性别识别教程(12)——加入性别识别功能
经过之前几篇博客的解说,我们已经成功搭建了MFC应用框架,并实现了主要的图像显示和人脸检測程序,在这篇博文中我们要向当中加入性别识别代码. 关于性别识别,之前已经专门拿出两篇博客的篇幅来进行解说.这里 ...
- 基于深度学习的人脸性别识别系统(含UI界面,Python代码)
摘要:人脸性别识别是人脸识别领域的一个热门方向,本文详细介绍基于深度学习的人脸性别识别系统,在介绍算法原理的同时,给出Python的实现代码以及PyQt的UI界面.在界面中可以选择人脸图片.视频进行检 ...
- 人脸和性别识别(基于OpenCV)
描写叙述 人脸识别包含四个步骤 人脸检測:定位人脸区域,仅仅关心是不是脸: 人脸预处理:对人脸检測出来的图片进行调整优化. 收集和学习人脸:收集要识别的人的预处理过的人脸,然后通过一些算法去学习怎样识 ...
- 基于OpenCV性别识别
叙述性说明 所谓的性别识别推断检测到的面部是男性还是女性.它是一个二值分类问题. 识别算法可以用于SVM,BP神经网络.LDA,PCA,PCA+LDA等等.OpenCV官网给出的文档是基于Fisher ...
- C++开发人脸性别识别教程(7)——搭建MFC框架之界面绘制
在之前的博客中我们已经将项目中用到的算法表述完成,包含人脸检測算法以及四种性别识别算法,在这篇博客中我们将着手搭建主要的MFC框架. 一.框架概况 在这篇博文中我们将搭建最主要的MFC框架.绘制MFC ...
- python手写bp神经网络实现人脸性别识别1.0
写在前面:本实验用到的图片均来自google图片,侵删! 实验介绍 用python手写一个简单bp神经网络,实现人脸的性别识别.由于本人的机器配置比较差,所以无法使用网上很红的人脸大数据数据集(如lf ...
- C++开发人脸性别识别总结
历时一个月,最终在昨天把<C++开发人脸性别识别总结>系列博客完毕了,第一篇博客发表在2015年12月29日,截止昨天2016年2月29日最后一篇完毕,去除中间一个月的寒假,正好一个月,首 ...
随机推荐
- 【P2629】好消息,坏消息(前缀和+单调队列优化DP)
一激动一颓就会忘了总结... 前面的大黄题就不总结了. 这个题我只想说一声艹,一开始的思路就是正确的,然后计算的时候有了一个瑕疵,不过很快也就改过来了.然后却一直连样例都过不了.仔仔细细看了老半天,经 ...
- 【bzoj1925】地精部落[SDOI2010](dp)
题目传送门:1925: [Sdoi2010]地精部落 这道题,,,首先可以一眼看出他是要我们求由1~n的排列组成,并且抖来抖去的序列的方案数.然后再看一眼数据范围,,,似乎是O(n^2)的dp?然后各 ...
- CentOS 7 安装 docker-machine
https://github.com/docker/machine/releases/ 指令: curl -L https://github.com/docker/machine/releases/d ...
- 考勤助手ER图2.0版本所存在的问题
如图所示,考勤助手ER图2.0版本中,缺少个人信箱这一问题虽然不具有逻辑层面的问题,但是它是不满足需求的,也就是说这样的设计无法满足小组对考勤助手最初的设计.其次,就设计层面来分析,弱联系是数据库查询 ...
- Java基础(7)-集合类3
list集合的特点 1)有序(存储和取出的元素一直) 2)可重复 List子类的特点 ArrayList 有序,可重复 底层数据结构是数组 查询快,增删慢 线程不安全,效率高 Vector 有序,可重 ...
- Spark性能优化指南--基础篇
前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能复用同一个RDD 原则三:对多次使用的RDD进行持久化 原则四:尽量避免使用shuffle类算子 原则五:使用map-side预聚 ...
- 【转】Android ImageView的scaleType属性与adjustViewBounds属性
ImageView的scaleType的属性有好几种,分别是matrix(默认).center.centerCrop.centerInside.fitCenter.fitEnd.fitStart.fi ...
- Windows 配置Apache以便在浏览器中运行Python script的CGI模式
打开httpd.conf,找到”#ScriptInterpreterSource Registry “,移除前面的注释# (如果找不到这行,就自己添加进去) 找到“Options Indexes Fo ...
- Spring初学之annotation实现AOP前置通知和后置通知
实现两个整数的加减乘除,并在每个计算前后打印出日志. ArithmeticCalculator.java: package spring.aop.impl; public interface Arit ...
- review20
Pattern与Matcher类 模式匹配就是检索和指定模式匹配的字符串.java提供了专门用来进行模式匹配的Pattern类和Matcher类,这些类在java.util.regex包中. 模式对象 ...