CNN应用之性别、年龄识别

原文地址:http://blog.csdn.net/hjimce/article/details/49255013

作者:hjimce

一、相关理论

  本篇博文主要讲解2015年一篇paper《Age and Gender Classification using Convolutional Neural Networks》,个人感觉这篇文献没啥难度,只要懂得Alexnet,实现这篇文献的算法,会比较容易。其实读完这篇paper之后,我一直在想paper的创新点在哪里?因为我实在没有看出paper的创新点在哪里,估计是自己水平太lower了,看文献没有抓到文献的创新点。难道是因为利用CNN做年龄和性别分类的paper很少吗?网上搜索了一下,性别预测,以前很多都是用SVM算法,用CNN搞性别分类就只搜索到这一篇文章。个人感觉利用CNN进行图片分类已经不是什么新鲜事了,年龄、和性别预测,随便搞个CNN网络,然后开始训练跑起来,也可以获得不错的精度。

  性别分类自然而然是二分类问题,然而对于年龄怎么搞?年龄预测是回归问题吗?paper采用的方法是把年龄划分为多个年龄段,每个年龄段相当于一个类别,这样性别也就多分类问题了。所以我们不要觉得现在的一些APP,功能好像很牛逼,什么性别、年龄、衣服类型、是否佩戴眼镜等识别问题,其实这种识别对于CNN来说,基本上是松松搞定的事,当然你如果要达到非常高的识别精度,是另外一回事了,就需要各种调参了。

言归正传,下面开始讲解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)第一层:采用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大小的图片,具体边界需要补齐。下面是原文的第一层结构示意图:

[python] view plaincopy
  1. layers {
  2. name: "conv1"
  3. type: CONVOLUTION
  4. bottom: "data"
  5. top: "conv1"
  6. blobs_lr: 1
  7. blobs_lr: 2
  8. weight_decay: 1
  9. weight_decay: 0
  10. convolution_param {
  11. num_output: 96
  12. kernel_size: 7
  13. stride: 4
  14. weight_filler {
  15. type: "gaussian"
  16. std: 0.01
  17. }
  18. bias_filler {
  19. type: "constant"
  20. value: 0
  21. }
  22. }
  23. }
  24. layers {
  25. name: "relu1"
  26. type: RELU
  27. bottom: "conv1"
  28. top: "conv1"
  29. }
  30. layers {
  31. name: "pool1"
  32. type: POOLING
  33. bottom: "conv1"
  34. top: "pool1"
  35. pooling_param {
  36. pool: MAX
  37. kernel_size: 3
  38. stride: 2
  39. }
  40. }
  41. layers {
  42. name: "norm1"
  43. type: LRN
  44. bottom: "pool1"
  45. top: "norm1"
  46. lrn_param {
  47. local_size: 5
  48. alpha: 0.0001
  49. beta: 0.75
  50. }
  51. }
(2)第二层:第二层的输入也就是96*28*28的单通道图片,因为我们上一步已经把三通道合在一起进行卷积了。第二层结构,选择256个滤波器,滤波器大小为5*5,卷积步长为1,这个也可以参考AlexNet的结构。池化也是选择跟上面的一样的参数。
[python] view plaincopy
  1. layers {
  2. name: "conv2"
  3. type: CONVOLUTION
  4. bottom: "norm1"
  5. top: "conv2"
  6. blobs_lr: 1
  7. blobs_lr: 2
  8. weight_decay: 1
  9. weight_decay: 0
  10. convolution_param {
  11. num_output: 256
  12. pad: 2
  13. kernel_size: 5
  14. weight_filler {
  15. type: "gaussian"
  16. std: 0.01
  17. }
  18. bias_filler {
  19. type: "constant"
  20. value: 1
  21. }
  22. }
  23. }
  24. layers {
  25. name: "relu2"
  26. type: RELU
  27. bottom: "conv2"
  28. top: "conv2"
  29. }
  30. layers {
  31. name: "pool2"
  32. type: POOLING
  33. bottom: "conv2"
  34. top: "pool2"
  35. pooling_param {
  36. pool: MAX
  37. kernel_size: 3
  38. stride: 2
  39. }
  40. }
  41. layers {
  42. name: "norm2"
  43. type: LRN
  44. bottom: "pool2"
  45. top: "norm2"
  46. lrn_param {
  47. local_size: 5
  48. alpha: 0.0001
  49. beta: 0.75
  50. }
  51. }

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

[python] view plaincopy
  1. layers {
  2. name: "conv3"
  3. type: CONVOLUTION
  4. bottom: "norm2"
  5. top: "conv3"
  6. blobs_lr: 1
  7. blobs_lr: 2
  8. weight_decay: 1
  9. weight_decay: 0
  10. convolution_param {
  11. num_output: 384
  12. pad: 1
  13. kernel_size: 3
  14. weight_filler {
  15. type: "gaussian"
  16. std: 0.01
  17. }
  18. bias_filler {
  19. type: "constant"
  20. value: 0
  21. }
  22. }
  23. }
  24. layers {
  25. name: "relu3"
  26. type: RELU
  27. bottom: "conv3"
  28. top: "conv3"
  29. }
  30. layers {
  31. name: "pool5"
  32. type: POOLING
  33. bottom: "conv3"
  34. top: "pool5"
  35. pooling_param {
  36. pool: MAX
  37. kernel_size: 3
  38. stride: 2
  39. }
  40. }

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

[python] view plaincopy
  1. layers {
  2. name: "fc6"
  3. type: INNER_PRODUCT
  4. bottom: "pool5"
  5. top: "fc6"
  6. blobs_lr: 1
  7. blobs_lr: 2
  8. weight_decay: 1
  9. weight_decay: 0
  10. inner_product_param {
  11. num_output: 512
  12. weight_filler {
  13. type: "gaussian"
  14. std: 0.005
  15. }
  16. bias_filler {
  17. type: "constant"
  18. value: 1
  19. }
  20. }
  21. }
  22. layers {
  23. name: "relu6"
  24. type: RELU
  25. bottom: "fc6"
  26. top: "fc6"
  27. }
  28. layers {
  29. name: "drop6"
  30. type: DROPOUT
  31. bottom: "fc6"
  32. top: "fc6"
  33. dropout_param {
  34. dropout_ratio: 0.5
  35. }
  36. }


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

[python] view plaincopy
  1. layers {
  2. name: "fc7"
  3. type: INNER_PRODUCT
  4. bottom: "fc6"
  5. top: "fc7"
  6. blobs_lr: 1
  7. blobs_lr: 2
  8. weight_decay: 1
  9. weight_decay: 0
  10. inner_product_param {
  11. num_output: 512
  12. weight_filler {
  13. type: "gaussian"
  14. std: 0.005
  15. }
  16. bias_filler {
  17. type: "constant"
  18. value: 1
  19. }
  20. }
  21. }
  22. layers {
  23. name: "relu7"
  24. type: RELU
  25. bottom: "fc7"
  26. top: "fc7"
  27. }
  28. layers {
  29. name: "drop7"
  30. type: DROPOUT
  31. bottom: "fc7"
  32. top: "fc7"
  33. dropout_param {
  34. dropout_ratio: 0.5
  35. }
  36. }

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

[python] view plaincopy
  1. layers {
  2. name: "fc8"
  3. type: INNER_PRODUCT
  4. bottom: "fc7"
  5. top: "fc8"
  6. blobs_lr: 10
  7. blobs_lr: 20
  8. weight_decay: 1
  9. weight_decay: 0
  10. inner_product_param {
  11. num_output: 2
  12. weight_filler {
  13. type: "gaussian"
  14. std: 0.01
  15. }
  16. bias_filler {
  17. type: "constant"
  18. value: 0
  19. }
  20. }
  21. }
  22. layers {
  23. name: "accuracy"
  24. type: ACCURACY
  25. bottom: "fc8"
  26. bottom: "label"
  27. top: "accuracy"
  28. include: { phase: TEST }
  29. }
  30. layers {
  31. name: "loss"
  32. type: SOFTMAX_LOSS
  33. bottom: "fc8"
  34. bottom: "label"
  35. top: "loss"
  36. }

网络方面,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张图片进行预测,最后对预测结果进行平均。

三、实际应用

  文献作者给我们提供,可以到Caffe zoo model:https://github.com/BVLC/caffe/wiki/Model-Zoo  或者文献的主页:http://www.openu.ac.il/home/hassner/projects/cnn_agegender/。下载相关训练好的模型,paper性别、年龄预测的应用场景比较复杂,都是一些非常糟糕的图片,比较模糊的图片等,所以如果我们想要直接利用paper训练好的模型,用到我们自己的项目上,可能精度会比较低。我测试了一下,直接使用paper给的模型,在我的数据上进行测试,我的数据是中国人、,然后也比较清晰,直接用作者训练好的模型,精度为0.82左右,这个精度对于我们实际的工程应用还差很远。后面就要发挥自己的调参、技巧把精度提高上去,才能达到95%以上的精度,具体因为项目保密,所以不再啰嗦。最后预测结果如下:

       

测试精度:

总结:看完这篇文献,感觉没看到什么比较牛逼的创新点,只是把Alexnet网络改一改而已,个人感觉AlexNet的一些算法已经过时了,现在各种最新牛逼文献的算法一大堆,随便找一个,调一调参,应该可以得到更高的精度,因为毕竟图片分类的算法更新太快了。年龄预测方面,因为自己的项目用不到,而且年龄预测这个东西,精度一向很低,很容易受光照、拍摄角度等因素影响,即便是我们人类,也很难精确判断一个人的年龄,有的人五十几岁了,但是看起来却很年轻……

PS:赶紧研究深度学习算法去,现在大部分深度学习的文章,有的文献只是稍微改一下参数、改一下结构,然后发现精度state-of-art,于是发表paper,很容易就被录用了。

参考文献:

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

2、《ImageNet Classification with Deep Convolutional Neural Networks》

3、http://www.openu.ac.il/home/hassner/projects/cnn_agegender/

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

【Caffe实践】基于CNN的性别、年龄识别相关推荐

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

    一.相关理论 本篇博文主要讲解2015年一篇paper<Age and Gender Classification using Convolutional Neural Networks> ...

  2. 基于CNN的象棋棋子识别

    基于CNN的象棋棋子识别 数据集 数据集介绍 数据预处理 卷积神经网络 什么是卷积神经网络 举个例子 本篇博客用到的卷积神经网络模型 代码及结果展示 代码 结果展示 数据集 数据集介绍 本篇博客采用的 ...

  3. 基于CNN的人脸表情识别系统

    基于CNN的人脸表情识别系统 主要功能: 1)图片识别,可以通过上传本地图片,进行表情识别 2)拍照识别,点击拍照识别按钮,可以调用摄像头实现拍照,并进 行表情识别 实现原理: 1.表情库的建立 fe ...

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

    CNN应用之性别.年龄识别 原文地址:http://blog.csdn.net/hjimce/article/details/49255013 作者:hjimce 一.相关理论 本篇博文主要讲解201 ...

  5. Tensorflow + 基于CNN神经网络的面部表情识别

    最近在学习使用Tensorflow框架,在学习到了CNN卷积神经网络的时候,跟着书上写了一个基于CNN网络的一个面部表情识别的小项目. 说一下我的硬件设备: CPU:G4560,,这什么年代了,我还在 ...

  6. 基于CNn的MINIST手写体识别

    深度学习的上机作业: 基于CNN卷积神经网络的MINIST手写体识别 版本:python-3.9,tensorflow-2.9 目录 MINIST数据集 训练CNN卷积神经网络 使用训练好的模型进行预 ...

  7. opencv学习笔记六十三:基于CNN的性别、年龄预测

    来自于2015年CVPR的一篇paper<Age and Gender Classification using Convolutional Neural Networks>. Paper ...

  8. 毕业设计 基于深度学习的人脸性别年龄识别 - 图像识别 opencv

    文章目录 0 前言 1 课题描述 课题意义 2 实现效果 3 算法实现原理 3.1 数据集 3.2 深度学习识别算法 3.3 特征提取主干网络 3.4 总体实现流程 4 具体实现 4.1 预训练数据格 ...

  9. 基于CNN的店铺LOGO识别

    人工智能之父John McCarthy将AI视为科学和工程的结合,而机器学习是AI已经实现的部分,利用机器学习技术,计算机能够通过体验(数据)来像人类一样学习,而不需要被显式地编程.这篇文章将详细介绍 ...

  10. 深度学习碰上古文献,西南大学提出基于CNN的古彝文识别方法

    在论文<A Recognition Method of Ancient Yi Character Based on Deep Learning>中,西南大学计算机与信息科学学院陈善雄副教授 ...

最新文章

  1. 把canvas放在盒子内_如何将您的专业知识放在盒子中并出售
  2. 灵异事件 !同一个代码在code::blocks和Dev上面运行结果不一样!(一番分析后找到原因!)
  3. CNN模型 int8量化实现方式(二)
  4. PowerShell 6.2 PSCommandNotFoundSuggestion
  5. java socket编程(转)
  6. std::string的拷贝赋值研究
  7. 开源导入导出库Magicodes.IE 多sheet导入教程
  8. 中南大学计算机网.doc,中南大学计算机网络习题2014-2.doc
  9. mysql+keepalived实现双主自由切换
  10. Hackintosh 黑苹果安装 基于Thinkpad x201(i5-560M,集显) Legacy Boot Mode安装macOS 10.14 Mojave
  11. 正点原子阿尔法linux开发板USB烧录裸机例程
  12. 华三路由交换配置命令_华为-华三交换机路由器命令大全
  13. 调手表(蓝桥杯2018年B组真题)
  14. SymPy学习之Plotting Module
  15. 光纤跳线接口_2分钟让你搞懂跳线架和配线架的区别
  16. JTextArea:文本域组件
  17. Android初学者需掌握的几点经验:该如何自学Android开发?(Android自学资料大全)
  18. 高校wifi认证登录
  19. 锐龙R3-3100配什么主板
  20. PHP 获取当天凌晨时间戳

热门文章

  1. String类两种实例化方式的区别
  2. zookeeper安装和基本操作
  3. Python中List,tuple,Dictionary之间的区别
  4. hexo sever端口占用,localhost:4000无响应
  5. 关于浏览器兼容的问题
  6. NFS网络文件系统配置
  7. 两个json对象合并为一个json对象
  8. Codeforces Round #555 (Div. 3) E. Minimum Array
  9. Oracle 分析函数row_number() over (partition by order by )
  10. 智能戒指,一个新鲜智能穿戴产物