基于CNN的性别、年龄识别及Demo实现

一、相关理论


  本篇博文主要讲解2015年一篇paper《Age and Gender Classification using Convolutional Neural Networks》paper的创新点在哪里。难道是因为利用CNN做年龄和性别分类的paper很少吗?网上搜索了一下,性别预测,以前很多都是用SVM算法,用CNN搞性别分类就只搜索到这一篇文章。

  性别分类自然而然是二分类问题,然而对于年龄怎么搞?年龄预测是回归问题吗?paper采用的方法是把年龄划分为多个年龄段,每个年龄段相当于一个类别,这样性别也就多分类问题了。

言归正传,下面开始讲解2015年paper《Age and Gender Classification using Convolutional Neural Networks》的网络结构,这篇文章没有什么新算法,只有调参,改变网络层数、卷积核大小等……所以如果已经对Alexnet比较熟悉的,可能会觉得看起来没啥意思,这篇papar的相关源码和训练数据,文献作者有给我们提供,可以到Caffe zoo model:https://github.com/BVLC/caffe/wiki/Model-Zoo 或者文献的主页:http://www.openu.ac.il/home/hassner/projects/cnn_agegender/。下载相关训练好的模型,paper性别、年龄预测的应用场景比较复杂,都是一些非常糟糕的图片,比较模糊的图片等,所以如果我们想要直接利用paper训练好的模型,用到我们自己的项目上,可能精度会比较低,后面我将会具体讲一下利用paper的模型进行fine-tuning,以适应我们的应用,提高我们自己项目的识别精度。


二、算法实现


因为paper的主页,有提供网络结构的源码,我将结合网络结构文件进行讲解。


1、 网络结构


这里写图片描述


Paper所用的网络包含:3个卷积层,还有2个全连接层。这个算是层数比较少的CNN网络模型了,这样可以避免过拟合。对于年龄的识别,paper仅仅有8个年龄段,相当于8分类模型;然后对于性别识别自然而然是二分类问题了。

然后图像处理直接采用3通道彩色图像进行处理,图片6都统一缩放到256*256,然后再进行裁剪,为227*227(训练过程随机裁剪,验证测试过程通过矩形的四个角+中心裁剪),也就是说网络的输入时227*227的3通道彩色图像,总之基本上跟Alexnet一样。

网络模型:
1、 网络结构

(1)第一层:采用96个卷积核,每个卷积核参数个数为3*7*7,这个就相当于3个7*7大小的卷积核在每个通道进行卷积。激活函数采用ReLU,池化采用最大重叠池化,池化的size选择3*3,strides选择2。然后接着再来一个局部响应归一化层。什么叫局部响应归一化,自己可以查看一下文献:《ImageNet Classification with Deep Convolutional Neural Networks》,局部响应归一化可以提高网络的泛化能力。

这里写图片描述

局部响应归一化,这个分成两种情况,一种是3D的归一化,也就是特征图之间对应像素点的一个归一化。还有一种是2D归一化,就是对特征图的每个像素的局部做归一化。局部响应归一化其实这个可有可无,精度提高不了多少,如果你还不懂上面那个公式也没有关系。我们可以利用最新的算法:Batch Normalize ,这个才牛逼呢,2015年,我觉得最牛逼的算法之一,不仅提高了训练速度,连精度也提高了。过程:通过7*7大小的卷积核,对227*227图片卷积,然后特征图的个数为96个,每个特征图都是三通道的,这个作者没有讲到卷积层的stride大小,不过我们大体可以推测出来,因为paper的网络结构是模仿:ImageNet Classification with Deep Convolutional Neural Networks的网络结构的,连输入图片的大小也是一样的,这篇文献的第一层如下所示:

这里写图片描述

我们可以推测出,paper选择的卷积步长为4,这样经过卷积后,然后pad为2,这样经过卷积后图片的大小为:(227-7)/4+1=56。然后经过3*3,且步长为2的大小,进行重叠池化,可以得到:56/2=28*28大小的图片,具体边界需要补齐。下面是原文的第一层结构示意图:

这里写图片描述

layers {  name: "conv1"  type: CONVOLUTION  bottom: "data"  top: "conv1"  blobs_lr: 1  blobs_lr: 2  weight_decay: 1  weight_decay: 0  convolution_param {  num_output: 96  kernel_size: 7  stride: 4  weight_filler {  type: "gaussian"  std: 0.01  }  bias_filler {  type: "constant"  value: 0  }  }  
}  
layers {  name: "relu1"  type: RELU  bottom: "conv1"  top: "conv1"  
}  
layers {  name: "pool1"  type: POOLING  bottom: "conv1"  top: "pool1"  pooling_param {  pool: MAX  kernel_size: 3  stride: 2  }  
}  
layers {  name: "norm1"  type: LRN  bottom: "pool1"  top: "norm1"  lrn_param {  local_size: 5  alpha: 0.0001  beta: 0.75  }  
}  

(2)第二层:


第二层的输入也就是96*28*28的单通道图片,因为我们上一步已经把三通道合在一起进行卷积了。第二层结构,选择256个滤波器,滤波器大小为5*5,卷积步长为1,这个也可以参考AlexNet的结构。池化也是选择跟上面的一样的参数。

layers {  name: "conv2"  type: CONVOLUTION  bottom: "norm1"  top: "conv2"  blobs_lr: 1  blobs_lr: 2  weight_decay: 1  weight_decay: 0  convolution_param {  num_output: 256  pad: 2  kernel_size: 5  weight_filler {  type: "gaussian"  std: 0.01  }  bias_filler {  type: "constant"  value: 1  }  }  
}  
layers {  name: "relu2"  type: RELU  bottom: "conv2"  top: "conv2"  
}  
layers {  name: "pool2"  type: POOLING  bottom: "conv2"  top: "pool2"  pooling_param {  pool: MAX  kernel_size: 3  stride: 2  }  
}  
layers {  name: "norm2"  type: LRN  bottom: "pool2"  top: "norm2"  lrn_param {  local_size: 5  alpha: 0.0001  beta: 0.75  }  
}  

(3)第三层:滤波器个数选择384,卷积核大小为3*3


layers {  name: "conv3"  type: CONVOLUTION  bottom: "norm2"  top: "conv3"  blobs_lr: 1  blobs_lr: 2  weight_decay: 1  weight_decay: 0  convolution_param {  num_output: 384  pad: 1  kernel_size: 3  weight_filler {  type: "gaussian"  std: 0.01  }  bias_filler {  type: "constant"  value: 0  }  }  
}  
layers {  name: "relu3"  type: RELU  bottom: "conv3"  top: "conv3"  
}  
layers {  name: "pool5"  type: POOLING  bottom: "conv3"  top: "pool5"  pooling_param {  pool: MAX  kernel_size: 3  stride: 2  }  
}  

(4)第四层:第一个全连接层,神经元个数选择512

layers {  name: "fc6"  type: INNER_PRODUCT  bottom: "pool5"  top: "fc6"  blobs_lr: 1  blobs_lr: 2  weight_decay: 1  weight_decay: 0  inner_product_param {  num_output: 512  weight_filler {  type: "gaussian"  std: 0.005  }  bias_filler {  type: "constant"  value: 1  }  }  
}  
layers {  name: "relu6"  type: RELU  bottom: "fc6"  top: "fc6"  
}  
layers {  name: "drop6"  type: DROPOUT  bottom: "fc6"  top: "fc6"  dropout_param {  dropout_ratio: 0.5  }  
}  

(5)第五层:第二个全连接层,神经元个数也是选择512


layers {  name: "fc7"  type: INNER_PRODUCT  bottom: "fc6"  top: "fc7"  blobs_lr: 1  blobs_lr: 2  weight_decay: 1  weight_decay: 0  inner_product_param {  num_output: 512  weight_filler {  type: "gaussian"  std: 0.005  }  bias_filler {  type: "constant"  value: 1  }  }  
}  
layers {  name: "relu7"  type: RELU  bottom: "fc7"  top: "fc7"  
}  
layers {  name: "drop7"  type: DROPOUT  bottom: "fc7"  top: "fc7"  dropout_param {  dropout_ratio: 0.5  }  
}  

(6)第六层:输出层,对于性别来说是二分类,输入神经元个数为2


layers {  name: "fc8"  type: INNER_PRODUCT  bottom: "fc7"  top: "fc8"  blobs_lr: 10  blobs_lr: 20  weight_decay: 1  weight_decay: 0  inner_product_param {  num_output: 2  weight_filler {  type: "gaussian"  std: 0.01  }  bias_filler {  type: "constant"  value: 0  }  }  
}  
layers {  name: "accuracy"  type: ACCURACY  bottom: "fc8"  bottom: "label"  top: "accuracy"  include: { phase: TEST }  
}  
layers {  name: "loss"  type: SOFTMAX_LOSS  bottom: "fc8"  bottom: "label"  top: "loss"  
}  

网络方面,paper没有什么创新点,模仿AlexNet结构。

2、网络训练

(1)初始化参数:权重初始化方法采用标准差为0.01,均值为0的高斯正太分布。(2)网络训练:采用dropout,来限制过拟合。Drop out比例采用0.5,还有就是数据扩充,数据扩充石通过输入256*256的图片,然后进行随机裁剪,裁剪为227*227的图片,当然裁剪要以face中心为基础,进行裁剪。(3)训练方法采用,随机梯度下降法,min-batch 大小选择50,学习率大小0.001,然后当迭代到10000次以后,把学习率调为0.0001。(4)结果预测:预测方法采用输入一张256*256的图片,然后进行裁剪5张图片为227*227大小,其中四张图片的裁剪方法分别采用以256*256的图片的4个角为基点点,进行裁剪。然后最后一张,以人脸的中心为基点进行裁剪。然后对这5张图片进行预测,最后对预测结果进行平均。

三、Age and Gender Classification Using Convolutional Neural Networks - Demo

下载 cnn_age_gender_models_and_data.0.0.2.zip

cd caffe-master/python/cnn_age_gender_models_and_data.0.0.2
ipython notebook

接着修改一下 caffe所在的位置

caffe_root = '../../../caffe-master/'  #为caffe所在目录

出现的问题1

#Loading the age network
age_net_pretrained='./age_net.caffemodel'
age_net_model_file='./deploy_age.prototxt'
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,mean=mean,channel_swap=(2,1,0),raw_scale=255,image_dims=(256, 256))

报错

File "/home/XXX/caffe-master/python/caffe/io.py", line 255, in set_mean
raise ValueError('Mean shape incompatible with input shape.')
ValueError: Mean shape incompatible with input shape.

解决方案

gedit ./caffe-master/python/caffe/io.py

if ms != self.inputs[in_][1:]:
    print(self.inputs[in_])
    in_shape = self.inputs[in_][1:]
    m_min, m_max = mean.min(), mean.max()
    normal_mean = (mean - m_min) / (m_max - m_min)
    mean = resize_image(normal_mean.transpose((1,2,0)),in_shape[1:]).transpose((2,0,1)) * (m_max - m_min) + m_min
    #raise ValueError('Mean shape incompatible with input shape.')

替代

if ms != self.inputs[in_][1:]:
    raise ValueError('Mean shape incompatible with input shape.')

出现的问题2

feat = age_net.blobs['conv1'].data[4, :49]
vis_square(feat, padval=1)

报错

IndexError: index 4 is out of bounds for axis 0 with size 1

解决方案

feat = age_net.blobs['conv1'].data[0, :49]
vis_square(feat, padval=1)

代码示例

# coding=utf-8
import os
import numpy as np
import matplotlib.pyplot as plt 
%matplotlib inline
import cv2
import shutil
import time#设置caffe源码所在的路径set the path where the Caffe source code     
caffe_root = '../../../caffe-master/'  
import sys  
sys.path.insert(0, caffe_root + 'python')  
import caffe plt.rcParams['figure.figsize'] = (10, 10)  
plt.rcParams['image.interpolation'] = 'nearest'  
plt.rcParams['image.cmap'] = 'gray'#加载均值文件mean file loading   
mean_filename='./imagenet_mean.binaryproto'  
proto_data = open(mean_filename, "rb").read()  
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)  
mean  = caffe.io.blobproto_to_array(a)[0]  #创建网络,并加载已经训练好的模型文件 create a network, and have good training model file loading     
gender_net_pretrained='./mytask_train_iter_8000.caffemodel'  
gender_net_model_file='./deploy.prototxt'  
gender_net = caffe.Classifier(gender_net_model_file, gender_net_pretrained,  mean=mean,  channel_swap=(2,1,0),#RGB通道与BGR   raw_scale=255,#把图片归一化到0~1之间  image_dims=(256, 256))#设置输入图片的大小 #载入年龄网络,并加载已经训练好的模型文件
age_net_pretrained='./age_net.caffemodel'
age_net_model_file='./deploy_age.prototxt'
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,mean=mean,channel_swap=(2,1,0),raw_scale=255,image_dims=(256, 256))#Label类别
age_list=['(0, 2)','(4, 6)','(8, 12)','(15, 20)','(25, 32)','(38, 43)','(48, 53)','(60, 100)']
gender_list=['Male','Female']  #类别#Reading and plotting the input image
example_image = './example_image.jpg'
input_image = caffe.io.load_image(example_image) # read pictures 读取图片
_ = plt.imshow(input_image)    #显示原图片#预测结果  
prediction = age_net.predict([input_image]) 
print 'predicted age:', age_list[prediction[0].argmax()]prediction = gender_net.predict([input_image]) 
print 'predicted gender:', gender_list[prediction[0].argmax()]for k, v in gender_net.params.items:print 'weight'
# in blob parameters of each layer, using vector to store two blob variable Caffe, v[0] weight print (k, v[0].data.shape)print bprint (k, v[1].data.shape) v[1] # bias#预测分类及其特征可视化#Filters visualizations 滤波可视化
def showimage(im):  if im.ndim == 3:  im = im[:, :, ::-1]  plt.set_cmap('jet')  plt.imshow(im) #Display # feature visualization, padval is used to adjust the brightness
def vis_square(data, padsize=1, padval=0):  data -= data.min()  data /= data.max() # force the number of filters to be square  n = int(np.ceil(np.sqrt(data.shape[0])))  padding = ((0, n ** 2 - data.shape[0]), (0, padsize), (0, padsize)) + ((0, 0),) * (data.ndim - 3)  data = np.pad(data, padding, mode='constant', constant_values=(padval, padval))  # tile the filters into an image  data = data.reshape((n, n) + data.shape[1:]).transpose((0, 2, 1, 3) + tuple(range(4, data.ndim + 1)))  data = data.reshape((n * data.shape[1], n * data.shape[3]) + data.shape[4:])   showimage(data)   #Loading the gender network without the mean image - just for better visualizations
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,channel_swap=(2,1,0),raw_scale=255,image_dims=(256, 256))prediction = age_net.predict([input_image]) #Input image
_ = plt.imshow(input_image)#The first conv layer filters, conv1
filters = gender_net.params['conv1'][0].data[:49] #conv1滤波器可视化  conv1 filter visualization
vis_square(filters.transpose(0, 2, 3, 1))  #conv2 filter visualization  
filters = gender_net.params['conv2'][0].data[:49] #conv2滤波器可视化  conv2 filter visualization
vis_square(filters.transpose(0, 2, 3, 1))  #feat map
feat = gender_net.blobs['conv1'].data[4, :49]  #The first Conv layer output, conv1 (rectified responses of the filters above)  
vis_square(feat, padval=1) for k, v in gender_net.blobs.items: print (k, v.data.shape);  
Feat = gender_net.blobs[k].data[0,0:4]# shows the name of the K network layer, the first picture generated by the 4 maps feature  
Vis_square (feat, padval=1)  # shows the original image, and the classification results  
Str_gender=gender_list[prediction_gender[0].argmax ()]  
print Str_gender   plt.imshow (input_image)  
plt.title (str_gender)  
plt.show ()  

参考文献

1、《Age and Gender Classification using Convolutional Neural Networks》

2、《ImageNet Classification with Deep Convolutional Neural Networks》

3、caffe finetune predict and classify the lung nodule( 肺结节的分类)

4、https://github.com/BVLC/caffe/wiki/Model-Zoo

5、深度学习(十四)基于CNN的性别、年龄识别

6、 http://stackoverflow.com/questions/30808735/error-when-using-classify-in-caffe

7、Age and Gender Classification Using Convolutional Neural Networks - Demo-ipynb

8、 caffe预测、特征可视化python接口调用

9、Deep learning (nine) Caffe prediction, feature visualization Python interface call

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Faster R-CNN的安装及测试(Python版本和Matlab版本)

rbg的Python版本 一、拉取源码 git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git 拉取完成后,在/home/cmwang/目录下增加了py-faster-rcnn文件夹【cmwang是我的ubuntu用户名】 二、安装依赖 sudo apt-get install python-opencvsudo pip…

Faste R-CNN的安装及测试

一、拉取源码 下载 fast-rcnn 因下载解压后 caffe-fast-rcnn是空文件夹,故需要单独下 caffe-fast-rcnn-bcd9b4eadc7d8fbc433aeefd564e82ec63aaf69c.zip unzip caffe-fast-rcnn-bcd9b4eadc7d8fbc433aeefd564e82ec63aaf69c.zip cp ./caffe-fast-rcnn-bcd9b4eadc7d8…

6 areas of artificial intelligence to watch closely 需要密切关注的六大人工智能/机器学习领域

近段时间,有许多关于人工智能公认定义的争论。有些人认为人工智能就是“认知计算”或是“机器智能”,而另一些人则把它与“机器学习”的概念混淆了。然而,人工智能并不是特指某种技术,它实际上是一个由多门学科组成的广阔领域&…

2016 亚洲共识指南:肺结节的评估

2016 年 2 月,亚洲肺部疾病和胸外科多学科专家小组在美国胸科医师学会(ACCP)制定的肺结节评估指南的基础上结合亚洲患者的自身特点制订了亚洲肺结节患者的评估指南。 亚洲肺结节的评估与 APCC 指南中所指出的重要注意事项大致相同。但该指南…

Ubuntu 15.04 安装TensorFlow(源码编译) 及测试梵高作画

介绍Google的TensorFlow机器学习开源库,在UbuntuKylin上的安装和和源码编译。 原始官方文档参见:http://www.tensorflow.org. 本电脑配置如下: 3.19.0-15-generic #15-Ubuntu x86_64 GNU/Linux NVIDIA Corporation GK110BGL [Tesla K40c] …

Ubuntu 15.04 安装 boost-python

1. 安装依赖库 sudo apt-get install python-dev sudo apt-get install mpi-default-dev #安装mpi库 sudo apt-get install libicu-dev #支持正则表达式的UNICODE字符集 sudo apt-get install …

python 常见问题汇总(待续)

1. No module named skimage pip install scikit-image --upgrade 2. No module named dicom sudo pip install pydicom 3. python name ‘os’ is not defined import os This will import the python’s module os, which apparently is used later in the code of your m…

如何将 ipynb 发布到 blog 中(html, markdown格式)

相关文章链接 如何向IPython Notebook中导入.py文件 如何将 ipynb 发布到 blog 中(html, markdown格式) Introducing IPython Notebook Beginner’s IPython Notebook Tutorial Example notebook showing how to do statistics in IPython Notebook next generation slide…

HP Z840 工作站配sSAS Raid 安装 Ubuntu 16.04 系统

惠普Z840工作站配SAS RAID安装win7系统加载驱动 安装ubuntu的最低版本版本要求是01.25,请更新到官方最新的02.31测试 1. BIOS系统更新 1. 准备好一个空的U盘,格式化成FAT32,在U盘上建立\Hewlett-Packard\BIOS\New 2. 下载链接http://ftp.hp…

Ubuntu SSH Algorithm negotiation failed

问题 解决方法 chmod 777 /etc/ssh/sshd_configgedit /etc/ssh/sshd_config添加如下 Ciphers aes128-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr,3des-cbc,arcfour128,arcfour256,arcfour,blowfish-cbc,cast128-cbcMACs hmac-md5,hmac-sha1,umac-64openssh.…

不同matlab版本所支持的gcc g+版本

问题 关于 GCC 和 G 版本问题 Matlab 2014a gcc/g 4.7.x, Matlab 2016a gcc/g 4.9.x Matlab 2017a gcc/g 4.9.x Ubuntu 15.04 gcc/g 4.9.x, Ubuntu 16.04 gcc/g 5.4.x 原则上Matlab需要和Ubuntu版本一致,由于CUDA 8只支持16.04,而且需要GCC 5.4.x 进行编译&#…

Linux系统中添加硬盘,并挂载到已有的目录,比如/home/user

备份用户下数据 cd home ls newuser tar cvf newuser.tar newuser  #创建一个tar归档 rm -rf newuser mkdir newuser备注:newuser为home下的用户。 分区和挂载 #查看硬盘分区 fdisk -l#分区 fdisk /dev/sdbCommand (m for help):m#新建一个分区 Comman…

高性能Numpy/Scipy加速:使用Intel MKL和Intel Compilers或OpenBLAS(待续)

Numpy/Scipy加速:使用Intel MKL和Intel Compilers 1.获取Intel Parallel Studio XE Intel免费软件工具提供免费的软件包,其中包括完整的Intel编译器和计算库及其激活码,软件和激活码一一对应。注意需要使用教育邮箱注册,否则不予通过。 2.安装…

Linux 安装卸载软件及管理软件仓库

软件仓库 Linux的软件包都存放在一个地方,叫做软件仓库,repository。 因为Linux是在Windows之后诞生的(1991年前后),所以为了避免Windows的这个“弊端”,Linux选择创建一个集中存放软件的地方。 当然了&a…

Linux 终端配置

一般Linux中的配置文件大多以点开头,而且多以rc结尾。比如vim的配置文件 .vimrc,bash shell的配置文件.bashrc,等等。 像这样的配置文件,如果用ls -l命令是列不出来的,需要用ls -a来列出。 “rc”,它是“…

Caffe2 Compilation Error gflags.cc' is being linked both statically and dynamically into this execut

问题描述 python -c from caffe2.python import core 2>/dev/null && echo "Success" || echo "Failure" 出现这个问题 ERROR: something wrong with flag flagfile in file /home/bids/softwares/gflags-2.2.0/src/gflags.cc. One possibil…

值得关注的医疗 AI 公司(待续)

医疗成像 Clearview Diagnostics 是一家开发辅助医生诊断疾病的工具的 AI 软件公司。该公司最初的重点是乳腺癌。 Butterfly Network 是一家医疗成像技术公司,该公司创建了一个集成了深度学习技术的便携式医疗成像设备,帮助缺乏医疗机构或医生不够专业的…

caffe2 介绍

Caffe2的特性 Caffe2框架可以通过一台机器上的多个GPU或具有一个及多个GPU的多台机器来进行分布式训练。 也可以在iOS系统、Android系统和树莓派(Raspberry Pi)上训练和部署模型。只需要运行几行代码即可调用Caffe2中预先训练好的Model Zoo模型。Caffe2…

如何向IPython Notebook中导入.py文件

相关文章链接 如何向IPython Notebook中导入.py文件 如何将 ipynb 发布到 blog 中(html, markdown格式) Introducing IPython Notebook Beginner’s IPython Notebook Tutorial Example notebook showing how to do statistics in IPython Notebook next generation sli…

Python 中的numpy 库

待总结 用scikit-learn和pandas学习线性回归 用scikit-learn和pandas学习Ridge回归 待整理的 Numpy & Pandas numpy——主要对其 N 维数组对象有用 http://www.numpy.org/ Pandas数据转为 numpy数据 df_numpyMatrix df.as_matrix() df_numpyMatrixdf.values a([3.23…