影像風格遷移(Neural Style)簡史

演算法與數學之美發表於2018-02-04

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1 影像風格遷移科技樹


什麼是影像風格遷移?

先上一組圖。

以下每一張圖都是一種不同的藝術風格。作為非藝術專業的人,我就不扯藝術風格是什麼了,每個人都有每個人的見解,有些東西大概藝術界也沒明確的定義。如何要把一個影像的風格變成另一種風格更是難以定義的問題。

對於程式設計師,特別是對於機器學習方面的程式設計師來說,這種模糊的定義簡直就是噩夢。到底怎麼把一個說都說不清的東西變成一個可執行的程式,是困擾了很多影像風格遷移方面的研究者的問題。

640?wx_fmt=png

在神經網路之前,影像風格遷移的程式有一個共同的思路:分析某一種風格的影像,給那一種風格建立一個數學或者統計模型,再改變要做遷移的影像讓它能更好的符合建立的模型。

這樣做出來效果還是不錯的,比如下面的三張圖中所示,但一個很大的缺點:一個程式基本只能做某一種風格或者某一個場景。因此基於傳統風格遷移研究的實際應用非常有限。

640?wx_fmt=png

景色照片時間遷移

改變了這種現狀的是兩篇Gatys的論文,在這之前讓程式模仿任意一張圖片畫畫是沒法想象的。

640?wx_fmt=png第一個基於神經網路的影像風格遷移演算法,生成時間:5-20分鐘

我想試著從頭開始講起,從Gatys et al., 2015a和Gatys et al., 2015b中用到的一些技術的歷史開始講起,用最簡單的方法說清楚基於神經網路的影像風格遷移的思路是什麼,以及Gatys為什麼能夠想到使用神經網路來實現影像風格遷移。

如果大家對這個感興趣的話,我將來可以繼續寫一些關於Neural Style最新的一些研究的進展,或者其他相關的一些影像生成類的研究,對抗網路之類的。寫的有錯誤的不到位的地方請隨意指正。

Neural Style元年前20年-前3年

要理解對於計算機來說圖片的風格是什麼,只能追根溯源到2000年以及之前的圖片紋理生成的研究上。明明是影像風格遷移的文章,為什麼要說到圖片紋理?在這兒我先賣個關子吧。

據我所知,在2015年前所有的關於影像紋理的論文都是手動建模的,其中用到的最重要的一個思想是:紋理可以用影像區域性特徵的統計模型來描述。沒有這個前提一切模型無從談起。什麼是統計特徵呢,簡單的舉個例子——

640?wx_fmt=jpeg早期紋理生成結果

與此同時,影像風格遷移也並無建樹,甚至比紋理生成還慘。

因為紋理生成至少不管生成什麼樣子的紋理都叫紋理生成,然而影像風格遷移這個領域當時連個合適的名字都沒有,因為每個風格的演算法都是各管各的,互相之間並沒有太多的共同之處。

比如油畫風格遷移,裡面用到了7種不同的步驟來描述和遷移油畫的特徵。又比如頭像風格遷移裡用到了三個步驟來把一種頭像攝影風格遷移到另一種上。

以上十個步驟裡沒一個重樣的,可以看出影像風格處理的研究在2015年之前基本都是各自為戰,搗鼓出來的演算法也沒引起什麼注意。相比之下Photoshop雖然要手動修圖,但比大部分演算法好用多了。

640?wx_fmt=png 頭像風格遷移

640?wx_fmt=png油畫風格遷移

同一個時期,計算機領域進展最大的研究之一可以說是計算機圖形學了。簡單的來說計算機圖形學就是現在幾乎所有遊戲的基礎,不論是男友1(戰地1)裡穿越回一戰的戰鬥場景,還是FGO之類的手遊,背後都少不了一代又一代的圖形學研究者的工作。

在他們整日整夜忙著研究如何能讓程式裡的妹紙變成有血有肉的樣子的時候,點科技樹點出了一個重要的分支:顯示卡(GPU)。

遊戲機從剛誕生開始就伴隨著顯示卡。顯示卡最大的功能當然是處理和顯示影像。不同於CPU的是,CPU早期是單執行緒的,也就是一次只能處理一個任務,GPU可以一次同時處理很多工,雖然單個任務的處理能力和速度比CPU差很多。

比如一個128x128的超級馬里奧遊戲, 用CPU處理的話,每一幀都需要執行128x128=16384歩,而GPU因為可以同時計算所有畫素點,時間上只需要1步,速度比CPU快很多。

為了讓遊戲越來越逼近現實,顯示卡在過去20年內也變得越來越好。巧合的是,顯示卡計算能力的爆炸性增長直接導致了被放置play十幾年的神經網路的復活和深度學習的崛起,因為神經網路和遊戲圖形計算的相似處是兩者都需要對大量資料進行重複單一的計算。

可以說如果沒有遊戲界就沒有深度學習,也就沒有Neural Style。所以想學機器學習先得去steam買東西,支援顯示卡研究。

640?wx_fmt=jpeg ImageNet物體識別比賽中使用GPU的隊伍數量逐年上升,錯誤率逐年下降

提到神經網路我想稍微講一下神經網路(特別是卷積神經網路)和傳統做法的區別,已經有了解的可以跳過本段。卷積神經網路分為很多層,每一層都是由很多單個的人工神經元組成的。可以把每個神經元看作一個識別器,用剛剛的栗子來說的話,每一個或者幾個神經元的組合都可以被用來識別某個特徵,比如栗子的開口。

在訓練前它們都是隨機的,所以啥都不能做,訓練的過程中它們會自動的被變成一個個不同的識別器並且相互組合起來,大量的識別器組合起來之後就可以識別物體了。整個過程除了一開始的神經網路的設計和引數的調整之外其他全是自動的。

640?wx_fmt=png

卷積神經網路圖例

Neural Style元年前3年-前1年

2012-2014年的時候深度學習剛開始火,火的一個主要原因是因為人們發現深度學習可以用來訓練物體識別的模型。

之前的物體識別模型有些是用幾何形狀和物體的不同部分比較來識別,有些按顏色,有些按3d建模,還有一些按照區域性特徵。

傳統物體識別演算法中值得一提的是按照比較區域性特徵來識別物體,其原理如下。比如我們的目標是在圖片之中找到這個人:

640?wx_fmt=jpeg

目標物體

對於程式而言這個人就是一堆畫素嘛,讓它直接找的話它只能一個個畫素的去比較然後返回最接近的了(近鄰演算法)。

但是現實中物體的形狀顏色會發生變化,如果手頭又只有這一張照片,直接去找的速度和正確率實在太低。

有研究者想到,可以把這個人的照片拆成許多小塊,然後一塊一塊的比較(方法叫Bag of Features)。最後哪一塊區域相似的塊數最多就把那片區域標出來。這種做法的好處在於即使識別一個小塊出了問題,還有其他的小塊能作為識別的依據,發生錯誤的風險比之前大大降低了。

640?wx_fmt=jpeg

 Bag of Features

這種做法最大的缺點就是它還是把一個小塊看成一坨畫素然後按照畫素的數值去比較,之前提到的改變光照改變形狀導致物體無法被識別的問題根本上並沒有得到解決。

用卷積神經網路做的物體識別器其實原理和bag of features差不了太多,只是把有用的特徵(feature)都裝到了神經網路裡了。

剛提到了神經網路經過訓練會自動提取最有用的特徵,所以特徵也不再只是單純的把原來的物體一小塊一小塊的切開產生的,而是由神經網路選擇最優的方式提取。

640?wx_fmt=jpeg

卷積神經網路提取的特徵示意圖,每一格代表一個神經元最會被哪種圖片啟用
卷積神經網路當時最出名的一個物體識別網路之一叫做VGG19,結構如下:

640?wx_fmt=jpegVGG19網路結構

每一層神經網路都會利用上一層的輸出來進一步提取更加複雜的特徵,直到複雜到能被用來識別物體為止,所以每一層都可以被看做很多個區域性特徵的提取器。VGG19在物體識別方面的精度甩了之前的演算法一大截,之後的物體識別系統也基本都改用深度學習了。

因為VGG19的優秀表現,引起了很多興趣和討論,但是VGG19具體內部在做什麼其實很難理解,因為每一個神經元內部引數只是一堆數字而已。每個神經元有幾百個輸入和幾百個輸出,一個一個去梳理清楚神經元和神經元之間的關係太難。

於是有人想出來一種辦法:雖然我們不知道神經元是怎麼工作的,但是如果我們知道了它的啟用條件,會不會能對理解神經網路更有幫助呢?

於是他們編了一個程式,(用的方法叫back propagation,和訓練神經網路的方法一樣,只是倒過來生成圖片。)把每個神經元所對應的能啟用它的圖片找了出來,之前的那幅特徵提取示意圖就是這麼生成的。

有人在這之上又進一步,覺得既然我們能找到一個神經元的啟用條件,那能不能把所有關於“狗’的神經元找出來,讓他們全部被啟用,然後看看對於神經網路來說”狗“長什麼樣子的?

長得其實是這樣的:

640?wx_fmt=jpeg神經網路想象中的狗

這是神經網路想象中最完美的狗的樣子,非常迷幻,都可以自成一派搞個藝術風格出來了。而能把任何圖片稍作修改讓神經網路產生那就是狗的幻覺的程式被稱作deep dream。

640?wx_fmt=jpegDeep Dream

Neural Style元年

有了這麼多鋪墊,一切的要素已經湊齊,前置科技樹也都已經被點亮了,現在進入正題了。基於神經網路的影像風格遷移在2015年由Gatys et al. 在兩篇論文中提出:Gatys et al., 2015a和Gatys et al., 2015b。

Gatys et al., 2015a論文地址:

http://t.cn/R9cnTeQ

Gatys et al., 2015b論文地址:

https://arxiv.org/abs/1508.06576

我們先說第一篇。第一篇比起之前的紋理生成演算法,創新點只有一個:它給了一種用深度學習來給紋理建模的方法。之前說到紋理生成的一個重要的假設是紋理能夠通過區域性統計模型來描述,而手動建模方法太麻煩。

於是Gatys看了一眼隔壁的物體識別論文,發現VGG19說白了不就是一堆區域性特徵識別器嘛。他把事先訓練好的網路拿過來一看,發現這些識別器還挺好用的。

於是Gatys套了個Gramian matrix上去算了一下那些不同區域性特徵的相關性,把它變成了一個統計模型,於是就有了一個不用手工建模就能生成紋理的方法。

640?wx_fmt=png基於神經網路的紋理生成演算法

從紋理到圖片風格其實只差兩步。

第一步也是比較神奇的,是Gatys發現紋理能夠描述一個影像的風格。嚴格來說文理只是圖片風格的一部分,但是不仔細研究紋理和風格之間的區別的話,乍一看給人感覺還真差不多。第二步是如何只提取圖片內容而不包括圖片風格。

這兩點就是他的第二篇論文做的事情:Gatys又偷了個懶,把物體識別模型再拿出來用了一遍,這次不拿Gramian算統計模型了,直接把區域性特徵看做近似的圖片內容,這樣就得到了一個把圖片內容和圖片風格(說白了就是紋理)分開的系統,剩下的就是把一個圖片的內容和另一個圖片的風格合起來。

合起來的方法用的正是之前提到的讓神經網路“夢到”狗的方法,也就是研究員們玩出來的Deep Dream,找到能讓合適的特徵提取神經元被啟用的圖片即可。

640?wx_fmt=png基於神經網路的影像風格遷移

至此,我們就把關於基於神經網路的影像風格遷移(Neural Style)的重點解釋清楚了。背後的每一步都是前人研究的結果,不用因為名字裡帶深度啊神經網路啊而感覺加了什麼特技,特別的高階。

Gatys所做的改進是把兩個不同領域的研究成果有機的結合了起來,做出了令人驚豔的結果。其實最讓我驚訝的是紋理竟然能夠和人們心目中認識到的圖片的風格在很大程度上相吻合。(和真正的藝術風格有很大區別,但是看上去挺好看的。)從那之後對neural style的改進也層出不窮,在這裡就先放一些圖,技術細節暫且不表。

640?wx_fmt=jpeg改進後的影像風格遷移演算法

左:輸入影像,中:改進前,右:改進後。生成時間:5-20分鐘

640?wx_fmt=jpeg多個預設風格的融合,生成時間:少於1秒,訓練時間:每個風格1-10小時

640?wx_fmt=jpeg最新的實時任意風格遷移演算法之一,生成時間:少於10秒(少於一秒的演算法也有,但個人認為看上去沒這個好看),訓練時間:10小時

640?wx_fmt=jpeg圖片類比,生成時間:5-20分鐘

最後安利一篇與本文無關的文章,Research Debt 是我寫本文的動機,希望對相關閱讀有所幫助。

Research Debt 地址(英文):

https://distill.pub/2017/research-debt/


作者:李嘉銘
Northwestern University | CS

知乎專欄:

https://zhuanlan.zhihu.com/p/26746283

∑編輯 | Gemini

來源 | 烏鎮智庫

640?wx_fmt=gif

演算法數學之美微信公眾號歡迎賜稿

稿件涉及數學、物理、演算法、計算機、程式設計等相關領域
稿件一經採用,我們將奉上稿酬。

投稿郵箱:math_alg@163.com


相關文章