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*2273通道彩色圖像,總之基本上跟Alexnet一樣。

網絡模型:

(1)第一層:採用96個卷積核,每個卷積核參數個數爲3*7*7,這個就相當於37*7大小的卷積核在每個通道進行卷積。激活函數採用ReLU,池化採用最大重疊池化,池化的size選擇3*3strides選擇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,這樣經過卷積後,然後pad2,這樣經過卷積後圖片的大小爲:(227-7)/4+1=56。然後經過3*3,且步長爲2的大小,進行重疊池化,可以得到:56/2=28*28大小的圖片,具體邊界需要補齊。下面是原文的第一層結構示意圖:

 

  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的結構。池化也是選擇跟上面的一樣的參數。

 

  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

 

  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。

  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

  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

 

  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 

**********************作者:hjimce   時間:2015.10.15  聯繫QQ:1393852684  原創文章,轉載請保留原文地址、作者等信息***************
發佈了13 篇原創文章 · 獲贊 17 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章