女生看了會流淚 | 訓練一個會「卸妝」的深度學習模型

本文由集智小仙女發表在集智AI學園公眾號上,歡迎關注集智AI學園微信公眾號:swarmAI。

前言

從本期開始,我會陸續地給大家推送一些有趣的深度學習項目,並且我會附加上詳細的使用流程和免費的視頻教程!所以,即使你沒有太多深度學習的經驗,只要會使用 Python,知道怎麼配置 PyTorch 環境,都可以根據我的教程做出有趣好玩的深度學習模型。

今天,我要手把手的帶領大家親自訓練一個會「化妝和卸妝」的深度學習模型!

先看看它自動化妝美顏的效果:

再看看它自動卸妝的效果:

厲不厲害!

是不是想知道自己女朋友卸了妝到底長什麼樣!

那就親手訓練一個模型吧!

視頻教程:campus.swarma.org/gcou=

我現在就帶領大家,從「收集處理訓練數據」開始,一步步的訓練這個神奇的「化妝卸妝」模型!認真閱讀本教程,你不僅能掌握一個模型,還能學習到「從圖片中切割出人臉」的數據處理方法!

好,那下面就讓我們開始吧!

1. 確認軟體依賴環境

1.1 系統需求

  • 可運行 PyTorch 的操作系統
  • Python 3.x
  • CPU 最好有 NVIDIA GPU + CUDA CuDNN

1.2 軟體需求

  • 從官網獲取 PyTorch 及 vision
  • 安裝 visdom 和 dominate

PyTorch 及其附屬包 vison 可從官網獲取(pytorch.org)。

visdom 是 PyTorch 獨有的訓練過程中可視化工具。安裝 visdom 和 dominate 的命令如下:

pip install visdomnpip install dominaten

2. 收集和處理訓練數據

這一步重要了!我們今天要訓練的模型呀,它需要兩種圖片數據才可以訓練。哪兩種圖片嘞?根據功能,肯定是需要「化了妝的圖片」和「卸了妝的圖片」。我們把這兩種圖片「喂」給今天深度學習模型以後,模型會努力學習兩種圖片之間的關係與特徵,最終實現在兩種圖片之間進行轉換!

2.1 收集數據

其實化妝和卸妝圖片是非常好找的,只需要百度搜索「化妝前後對比」,即可找到大量圖片。我們只需要篩選一些圖片保存到本地即可。

我是採用純手動的方式把圖片保存到本地的,共收集了 168 張。有能力的同學還可以使用爬蟲「爬」出更多數據。

2.2 切分數據

從網上收集的圖片效果雜亂,所以在使用這些圖片訓練模型之前,先要對圖片進行處理。

從網上下載的圖片是「化了妝」和「沒化妝」的人臉在一張圖片上,所以第一步就是把「化了妝」和「沒化妝」的圖片切分開來。

其實分割演算法很簡單,只要從原圖一半寬度的位置把圖片「劈」開就好了。我們使用 Python 的 Pillow 包實現圖片的分割,代碼如下:

import Imagenndef cut_photo(filename, outputname):n im = Image.open(filename)n # 獲得原圖的寬高n im_wid, im_hei = im.sizen # 指定切分區域的位置,0,0為圖片左上角n box_a = (0, 0, im_wid/2, im_hei)n # 第二個切分區域n box_b = (im_wid/2, 0, im_wid, im_hei)n # 執行切分,保存圖片n region_a = im.crop(box_a)n region_a.save(outputname + _a.jpg)n region_b = im.crop(box_b)n region_b.save(outputname + _b.jpg)n

2.3 「收割」人臉

在上一步將圖片一分為二後,我們會得到兩張「長圖」。觀察兩張圖,可以發現圖中除了「人臉」之外還包含人物背景啊、上身啊等信息。我們是要做「化妝」和「卸妝」呀,所以除了人臉之外的信息都是多餘的,而多餘的信息傳入模型後會影響訓練的效果。所以,我們要把人臉單獨切割出來!

我從世界上最大的同性交友網站 GitHub 上找到了 cropman 這個工具來切割人臉。在使用時,cropman 可以自動定位人臉的中心位置,但仍需我們指定高寬,從而按照指定的大小把人臉切割出來。

執行切割的代碼很簡單,我是根據 cropman 的示例代碼修改的。

from cropman.cropper import Croppernimport cv2nn# 輸入、輸出圖片的路徑,以及指定的高寬ndef cut_face(inputImg, targetImg, targetWidth, targetHeight):n input_filename = inputImgn target_filename = targetImgn target_width = int(targetWidth)n target_height = int(targetHeight)n # 人臉收割者!n cropper = Cropper()n # 下面的程序是切割圖片後保存n input_image = cv2.imread(input_filename)n if input_image is None:n print Invalid input image. Please check %s % input_filenamen else:n target_image = cropper.crop(input_image, target_width, target_height)n if target_image is None:n print Cropping failed.n else:n cv2.imwrite(target_filename, target_image)n print nDone. nResult: %s % target_filenamen

有時候以固定的大小切割解析度較大的圖片時會出現無法切割完整的情況。如果這樣的圖片佔少數,則可以手動 PS 進行調整,如果這樣的圖片較多,建議大家先使用程序把圖片縮放到相似的大小再進行人臉切割。

2.4 通過「圖片增強」增加數據量!

經過上面的處理,我們已經擁有了高質量的人臉圖片,但是嘞,化妝卸妝的圖片各有168張,這對訓練深度學習模型來說太少了。

對於這種情況,我們可以使用圖片增強技術生成數據集。什麼是圖像增強嘞?其實就是對圖片進行旋轉、鏡像、調整對比度、亮度、飽和度、銳度等處理,將經過處理過的圖片當成「新數據」,原有的圖片一起傳入神經網路進行訓練。

這樣做的原理是人工模擬自然存在的圖片的多樣性,雖然效果比不上真正的數據,但是還是能在一定程度上提高深度學習模型的「普適性」,讓模型學習的效果更好。

我是使用 Pillow 實現的圖片增強,隨機選擇效果對圖片進行處理:

import ImageEnhancenn# 對圖片隨機進行旋轉和左右置換ndef photo_transform(filename, savename, trans_type):n im = Image.open(filename)n #旋轉與平移的量也是隨機的n rand = random.randrange(15, 46)n rand_choice = random.randrange(0, 2)nn if trans_type == 0:n # 旋轉n out = im.rotate(rand)n if rand_choice == 0:n #左右置換n out = out.transpose(Image.FLIP_LEFT_RIGHT)n out.save(savename)n elif trans_type == 1:n out = im.transpose(Image.FLIP_LEFT_RIGHT)n if rand_choice == 0:n rand = random.randrange(0, 15)n out = im.rotate(rand)n out.save(savename)n elif trans_type == 2:n out = im.rotate(-rand)n if rand_choice == 0:n out = out.transpose(Image.FLIP_LEFT_RIGHT)n out.save(savename)n else:n passnn# 隨機調整圖片的對比度、色彩等屬性ndef photo_enhance(filename, savename, enhance_type):n im = Image.open(filename)n if enhance_type == 0:n enh_bri = ImageEnhance.Brightness(im)n brightness = random.uniform(0.7, 1.2)n out = enh_bri.enhance(brightness)n out.save(savename)n elif enhance_type == 1:n enh_col = ImageEnhance.Color(im)n color = random.uniform(0.7, 1.5)n out = enh_col.enhance(color)n out.save(savename)n elif enhance_type == 2:n enh_con = ImageEnhance.Contrast(im)n contrast = random.uniform(0.7, 1.5)n out = enh_con.enhance(contrast)n out.save(savename)n elif enhance_type == 3:n enh_sha = ImageEnhance.Sharpness(im)n sharpness = random.uniform(0.7, 3.0)n out = enh_sha.enhance(sharpness)n out.save(savename)n else:n passn

至此,包括原有的168張圖片,我共有1008張「上妝/卸妝」圖片,可以運行模型進行訓練了。

3. 使用數據,開始訓練!

3.1 將訓練數據放入指定位置

在訓練前要把訓練數據放到指定位置以方便使用。

  • 在 CycleGAN 源碼目錄中找到./datasets目錄.
  • 在 datasets 目錄下創建「上妝/卸妝」數據文件夾:makeup2
  • 在 makeup2 中創建子目錄
  • trainA 訓練數據A(素顏圖片)
  • trainB 訓練數據B(美妝圖片)
  • testA 測試數據A(測試用素顏圖片)
  • testB 測試數據B(測試用美妝圖片)
  • 將之前加工過的數據放置在相應文件夾中即可。

3.2 開始訓練

運行實時訓練監控程序

python -m visdom.server &n

運行命令後,訪問下面的網址,即可打開訓練過程實時監控平台。

http://localhost:8097n

然後再運行開始訓練的命令:

python train.py --dataroot ./datasets/makeup2 --name makeup_cyclegan --model cycle_gan --no_dropoutn

其中:

  • dataroot 表示訓練數據目錄
  • name 表示模型訓練完成後的名字
  • model 表示要使用的基本模型框架

命令運行後即開始訓練,我在一塊 Titan X 平台上訓練了12個小時左右,在 Floyd 平台上會需要更多一點時間。

4. 使用模型!

訓練結束後,即可測試驗證模型,在保證測試圖片已經放在相應目錄的情況下,運行命令:

python test.py --dataroot ./datasets/makeup2 --name makeup_cyclegan --model cycle_gan --phase testn--no_dropoutn

在這裡注意,訓練好的模型都在 ./checkpoints 目錄下,測試結果生成在 ./results 目錄下。

讓我們看一下效果!

可以看到給素顏圖片化妝的效果非常好!而對於卸妝,儘管這位藝人進行了極誇張的美顏,但是我們的模型還是在一定程度上進行了還原!

總體來說,我們這次訓練的模型,成功!

如果你不想錯過更多的有趣的深度學習應用,那就快快關注 集智AI學園 公眾號吧!

api.swarma.org體驗模型效果

(PS:可能會有些慢,且效果並沒有某些APP那麼理想,我們本次實驗的重點是模型的實現

下面是本次項目的小教程

有興趣的同學可以跟著做一下~

campus.swarma.org/gcou= (二維碼自動識別)


如果您有任何關於Pytorch方面的問題,歡迎進【集智—清華】火炬群與大家交流探討,添加集智小助手微信swarmaAI,備註(pytorch交流群),小助手會拉你入群。

關注集智AI學園公眾號

獲取更多更有趣的AI教程吧!

搜索微信公眾號:swarmAI

集智AI學園QQ群:426390994

學園網站: campus.swarma.org

weixin.qq.com/r/FzpGXp3 (二維碼自動識別)

推薦閱讀:

DeepLearning-風格遷移
Pytorch如何更新版本與卸載
Pytorch源碼與運行原理淺析--網路篇(一)
深度學習新手必學:使用 Pytorch 搭建一個 N-Gram 模型
項目推薦:自然場景中文文字檢測和不定長中文OCR識別

TAG:PyTorch | 深度学习DeepLearning | 人工智能 |