深度解密換臉應用Deepfake

前言

Deepfake就是前一陣很火的換臉App,從技術的角度而言,這是深度圖像生成模型的一次非常成功的應用,這兩年雖然湧現出了很多圖像生成模型方面的論文,但大都是能算是Demo,沒有多少的實用價值,除非在特定領域(比如醫學上),哪怕是英偉達的神作:漸進生成高清人臉PGGAN好像也是學術意義大於實用價值。其實人們一直都在追求更通用的生成技術,我想Deepfake算是一例,就讓我們由此出發,看看能否從中獲取些靈感。

一、基本框架

我們先看看Deepfake到底是個何方神聖,其原理一句話可以概括:用監督學習訓練一個神經網路將張三的扭曲處理過的臉還原成原始臉,並且期望這個網路具備將任意人臉還原成張三的臉的能力。

說了半天這好像是一個自編碼模型嘛~,沒錯,原始版本的deepfake就是這樣的,公式如下:

X = Decoder(Encoder(XW))

Loss = L1Loss(X - X)

這裡的XW是經過扭曲處理過的圖片,用過Deepfake的童鞋可能會有人提出質疑,「要讓代碼跑起來好像必須要有兩個人的人臉數據吧」。沒錯,之所以要同時用兩個人的數據並不是說演算法只能將A與B互換,而是為提高穩定性,因為Encoder網路是共享的,Deocder網路是分開的,上公式:

A = Decoder_A(Encoder(AW))

B = Decoder_B(Encoder(BW))

為了方便理解我照搬項目二(加了Gan的版本)上的說明圖片:

特別注意:原版是沒有Mask的~

版本二我不打算討論,僅介紹一下,簡而言之就是增加了Adversarial Loss和Perceptual Loss,後者是用訓練好的VGGFace網路(該網路不做訓練)的參數做一個語義的比對。

二、技術細節

Deepfake的整個流程包括三步,一是提取數據,二是訓練,三是轉換。其中第一和第三步都需要用到數據預處理,另外第三步還用到了圖片融合技術。所以我在技術上主要分三個方面來剖析:圖像預處理、網路模型、圖像融合。

1. 圖像預處理

從大圖(或視頻)中識別,並摳出人臉圖像,原版用的是dlib中的人臉識別庫(這個識別模塊可替換),這個庫不僅能定位人臉,而且還可以給出人臉的36個關鍵點坐標,根據這些坐標能計算人臉的角度,最終摳出來的人臉是擺正後的人臉。

2. 網路模型

Encoder: 64x64x3->8x8x512x = input_x = conv(128)(x)x = conv(256)(x)x = conv(512)(x)x = conv(1024)(x)x = Dense(ENCODER_DIM)(Flatten()(x))x = Dense(4 * 4 * 1024)(x)x = Reshape((4, 4, 1024))(x)x = upscale(512)(x)Decoder:8x8x512->64x64x3x = input_x = upscale(256)(x)x = upscale(128)(x)x = upscale(64)(x)x = Conv2D(3, kernel_size=5, padding=same, activation=sigmoid)(x)

整個網路並不複雜,無非就是卷積加全連接,編碼->解碼,但是仔細研究後發現作者其實是匠心獨運的,為什麼我不急著說,我們先看看con和upscale的內部實現:

def conv(filters): def block(x): x = Conv2D(filters, kernel_size=5, strides=2, padding=same)(x) x = LeakyReLU(0.1)(x) return x return blockdef upscale(filters): def block(x): x = Conv2D(filters * 4, kernel_size=3, padding=same)(x) x = LeakyReLU(0.1)(x) x = PixelShuffler()(x) return x return block

conv是中規中矩的卷積加lrelu激活函數,upscale中有個函數叫PixelShuffler,這個函數很有意思,其功能是將filter的大小變為原來的1/4,讓後讓高h、寬w各變為原來的兩倍,這也就是為什麼前面的卷積層的filtere要乘以4的原因。

經過測試對比,比如拿掉upscale換成步長為2的反卷機,或者簡單resize為原來的兩倍,實驗的效果都大打折扣,結果是網路只能自編碼,而得不到需要的人臉。雖然作者沒有說這樣設計是引用那篇論文的思想,筆者也未讀到過直接討論這個問題的論文,但是有一篇論文可以佐證:Deep Image Prior,包括Encoder中的全連接層都是人為打亂圖像的空間依賴性,增加學習的難度,從而使網路能夠更加充分地理解圖像。所以Encoder中的全連接層和PixelShuffler都是必不可少的。經筆者測試,在不加Gan的情況下,去掉這兩個要素,網路必定失敗。

3. 圖像融合

圖像融合放在技術難點分析中討論。

三、難點分析

1. 清晰度問題

原版的人臉像素是64*64,顯然偏低,但要提高人臉清晰度,並不能僅靠提高圖片的解析度,還應該在訓練方法和損失函數上下功夫。眾所周知,簡單的L1Loss是有數學上的均值性的,會導致模糊。解決方案個人比較傾向在L1Loss的基礎上加入GAN,因為強監督下的GAN具有區分更細微區別的能力,很多論文都提到這一點,比如較早的一篇超解析度的文章。但是GAN也有很多問題,這個後面討論。還有一個思路就是用PixelCNN來改善細節的,但經實踐,這種方法不僅生成速度慢(雖然速度可以通過加入緩存機制,一定程度上優化),而且在質量上也不如GAN。

2. 人臉識別問題

由於第一個環節是對人臉做預處理,演算法必須首先能識別出人臉,然後才能處理它,而dlib中的人臉檢測演算法,必須是「全臉」,如果臉的角度比較偏就無法識別,也就無法「換臉」。所以項目二就用了MTCNN作為識別引擎。

3. 人臉轉換效果問題

原版的演算法人臉轉換的效果,筆者認為還不夠好,比如由A->B的轉換,B的質量和原圖A是有一定關聯的,這很容易理解,因為演算法本身的原因,由XW->X,中不管X如何扭曲總會有一個限度。所以導致由美女A生成美女B的效果要遠遠優於由醜男A生成美女B。這個問題的解決筆者認為最容易想到的還是Gan,類似Cycle-Gan這樣框架可以進行無監督的語義轉換。另外原版的演算法僅截取了人臉的中間部分,下巴還有額頭都沒有在訓練圖片之內,因此還有較大的提高空間。

4. 圖片融合問題

由於生成出來的是一個正方形,如何與原圖融合就是一個問題了,原始項目有很多種融合方法,包括直接覆蓋遮罩覆蓋,還有就是泊松克隆「Seamless cloning」,從效果上而言,遮罩覆蓋的效果與泊松克隆最好,二者各有千秋,遮罩覆蓋邊緣比較生硬,泊松克隆很柔和,其的單圖效果要優於遮罩覆蓋,但是由於泊松克隆會使圖片發生些許位移,因此在視頻合成中會產生一定的抖動。圖片融合問題的改進的思路,筆者認為還是要從生成圖片本身著手,項目二引入了遮罩,是一個非常不錯的思路,也是一個比較容易想到的思路,就是最終生成的是一個RAGB的帶通明度的圖片。筆者還嘗試過很多方法,其中效果比較好的是,在引入Gan的同時加入非常小的自我還原的L1Loss,讓圖片「和而不同」。經測試,這種方法能夠使圖片的邊緣和原圖基本融合,但是這種方法也有弊端,那就是像臉型不一樣這樣的比較大的改動,網路就不願意去嘗試了,網路更趨向於小修小補,僅改變五官的特徵。

5. 視頻抖動問題

視頻抖動是一個很關鍵的問題。主要源自兩點,第一點是人臉識別中斷的問題,比如1秒鐘視頻的連續30幀的圖片中間突然有幾幀由於角度或是清晰度的問題而無法識別產生了中斷。第二點是演算法本身精確度問題會導致人臉的大小發生變化。這是由演算法本身帶來的,因為總是讓XW->X,而XW是被扭曲過的,當XW是被拉大時,演算法要由大還原小,當XW被縮小時,要由小還原大。也就是說同一張人臉圖片,讓他合成大於自己的或小於自己的臉都是有道理的,另外當人臉角度變化較大時,這種抖動就會更明顯。視頻抖動目前尚未有很好的解決方案,唯有不斷提高演算法的精確度,同時提高人臉識別和人臉轉換的精確度。

四、關於Gan改進版的Deepfake

在原始版本上加入Gan,項目二是這麼做的,筆者也進行過較深入的研究。

Gan的優點是能比較快進行風格轉換,相同參數下Gan訓練2w次就生成比較清晰目標人臉,而原始演算法大概需要5w以上,Gan生成的人臉較清晰,而且能減少對原圖的依賴等,同時加入Gan之後,可以減少對特定網路模型的依賴,完全可以去掉原網路中的FC和Shuffer。

Gan的缺點也很突出,其訓練難以把控,這是眾所周知的。Gan會帶來許多不可控的因子。比如一個人的膚色偏白,則生成的人臉也會變白,而忘記要與原圖的膚色保持一致,比如有的人有流海,訓練數據中大部分都是有劉海的圖片,則Gan也會認為這個人必須是有劉海的,而不考慮原圖是否有劉海。即使加入了Condition,Gan這種「主觀臆斷」和「自以為是」的特點也無法得到根除,總而言之,加入Gan以後經常會「過訓練」。 這種情況在筆者之前做的字體生成項目中也出現過,比如在由黑體字合成宋體字時,Gan經常會自以為是地為「忄」的那一長豎加上一鉤(像「刂」一樣的鉤)。另外Gan有一個最大的弊端就是他會過分趨近訓練集的樣本,而不考慮表情因素,比如原圖的人是在大笑,但是訓練集中很少有這類圖片,因此生成的圖片也許只是在微笑。我不禁聯想到了Nvidia的那篇論文,沒有條件的Gan雖然可以生成高清的圖片,但是沒法人為控制隨機因子z,無法指定具體要生成生成什麼樣的臉,而有條件的Gan樣本又過於昂貴。Gan的這一大缺點會使生成的視頻中人物表情很刻板,而且畫面抖動的情況也更劇烈,即使加入了強監督的L1Loss,GAN還是會有上述弊端。總之在原版的基礎上加入Gan還需要進一步地研究,2017年Gan的論文很多,但沒有多少令人眼前一亮的東西,Google甚者發了一篇論文說,這麼多改進的版本與原版的差別並不顯著,經測試,筆者得到的結論是Gan困最難的地方是抖動較大,合成視頻時效果不太好,也許是Gan力量太強的原故。

五、結束語

單純從技術的層面上來看,Deepfake是一個很不錯的應用,筆者更期望它能用在正途上,能在電影製作,錄製回憶片,紀錄片中發揮作用,真實地還原歷史人物的原貌,這可能是無法僅由演員和化妝師做到的,筆者也期望在2018年,基於圖像的生成模型能湧現出更多可以落地的應用。


推薦閱讀:

麻省理工媒體實驗室:面部識別軟體「更喜歡」白人男性用戶
計算機視覺技術
平台現漏洞被盜刷28萬,「人臉識別」真的這麼容易被破解?
人臉識別出手!讓號販子再無可趁之機!
一門跟四億人相關的生意

TAG:生成對抗網路GAN | 人臉識別 | 神經網路 |