用深度學習技術FCN自動生成口紅
- 2019 年 10 月 3 日
- 筆記
1 這個是什麼?
基於全卷積神經網路(FCN)的自動生成口紅Python程式。

圖1 FCN生成口紅的效果(注:此兩張人臉圖來自人臉公開資料庫LFW)
2 怎麼使用了?
首先能從這個Github (https://github.com/Kalafinaian/ai_lips_makeup) 中下載這個python項目。下載解壓後你得到這樣一個程式。

圖2 口紅Python程式
本項目的運行環境為Python3.6,需要的深度學習包tensorflow , 臉部圖形處理包dlib,通用電腦視覺處理包cv2,以上三個python軟體包都可以通過如下pip命令按照
pip install opencv-python
pip instll dlib=19.16.0
pip install tensorflow=1.12.0
安裝好必要的python包後,就直奔主題說如何給一張人臉圖加上口紅,用pycharm打開項目運行main_predict.py。按照提示選擇口紅效果,再輸入人臉圖片的地址,最後加上口紅的照片會在test_out文件夾中存儲。

圖3 FCN口紅運行演示
同理類似處理test_in文件夾下的002.jpg,那麼在test_out文件夾下可以獲得加上亮面口紅的人臉照片了。

圖4 FCN口紅的預測輸出
3 程式的原理
這個基於全卷積神經網路的FCN口紅的工作原理如下 (釉面口紅為例)
(1) 訓練集輸入為沒有口紅的人臉,訓練集輸出為有釉面口紅人臉,共170
個訓練集。(因版權原因本程式不提供完整人臉,只提供口紅照片)

圖5 沒有口紅的人臉

圖6 有釉面口紅的人臉(誠如所見,訓練集口紅都是人工PS的?)
(2)使用dlib自帶的模型提取出人臉嘴唇,將所有嘴唇圖片resize到90×30的大小那麼訓練的輸入和輸出

圖7 訓練集原始嘴唇

圖8 訓練集對應釉面口紅輸出
(3)構建一個三層全卷積神經網路
(3.1)第一層輸入為30×90×3 (RGB三通道)的多維數組,所以第一層卷積輸入通道為3個,另定義輸出通道為24個,採用elu激活函數,沒有下取樣
(3.2)根據第一層輸出通道可知第二層輸入為30×90×24的多維數組,另定義第二層輸出通道為45個,同樣採用elu激活函數,沒有下取樣
(3.3)根據第二層輸出通道可知第三層輸入為30×90×45的多維數組,另定義第二層輸出通道為3個,同樣採用elu激活函數,沒有下取樣
(3.4)定義損失函數為均方差損失,即loss等於第三次輸出和訓練輸出每個像素點差的平方求平均數。
(4) 迭代訓練100詞,將模型參數保持為model文件夾中model_brightening
(詳細過程可見程式碼)
(5) 高興的使用模型參數進行口紅生成
4 延伸閱讀(全卷積神經網路和ELU激活函數)
簡單來說FCN將傳統CNN中的全連接層轉化成一個個的卷積層(本文中程式連pooling也省略了)。在傳統的CNN結構中,前N層是卷積層,倒數第二層是一個長度為4096的一維向量,倒數第一層是長度為1000的一維向量,對應1000個類別的概率。FCN將這3層表示為卷積層,卷積核的大小(通道數,寬,高)分別為(4096,1,1)、(4096,1,1)、(1000,1,1)。所有的層都是卷積層,故稱為全卷積網路。簡單來說FCN與CNN的區別在於FCN把CNN最後的全連接層換成卷積層,輸出一張已經label好的圖。

圖9 FCN演示圖
關於FCN具體只是可參見UC Berkeley的Jonathan Long等人提出了Fully Convolutional Networks (FCN)[1]。
然後再介紹一下ELU激活函數[2],這個函數長這樣的
[fleft( x right) = left{ begin{array}{l} x;;;;;;;;;;;;;;x > 0 \ alpha left( {{e^x} – 1} right);;;x le 0 \ end{array} right.,;f'left( x right) = left{ begin{array}{l} 1;;;;;;;;;;;;;;;x > 0 \ fleft( x right) + alpha ;;;x le 0 \ end{array} right.]
在tensorflow中alpha默認取1(https://www.tensorflow.org/api_docs/
python/tf/nn/elu)。

圖10 ELU函數和其他幾個激活函數的影像
Elu函數可以加速訓練並且可以提高分類的準確率。它有以下特徵:
(1) elu由於其正值特性,可以像relu,lrelu,prelu一樣緩解梯度消失
(2相比relu,elu存在負值,可以將激輸出均值往0推近,輸出均值接近0可以減少偏移效應進而使梯 度接近於自然梯度。
(3) Lrelu和prelu雖然有負值存在,但是不能確保是一個雜訊穩定的去激活狀態。Elu在負值時是一個指數函數,對於輸入特徵只定性不定量
5 總結
詳細過程看程式碼,具體原理讀論文。
推薦論文:
[1] Fully Convolutional Networks for Semantic Segmentation
(https://arxiv.org/abs/1411.4038)
[2] Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)
(https://arxiv.org/abs/1511.07289v5)
推薦資源
http://vis-www.cs.umass.edu/lfw/
https://github.com/shelhamer/fcn.berkeleyvision.org