深度学习(三十一)——Style Transfer
Style Transfer
上圖是Style Transfer問(wèn)題的效果圖:將圖片B的風(fēng)格遷移到另一張圖片A上。
上圖是圖像風(fēng)格遷移所涉及的科技樹(shù)。
在繼續(xù)討論之前,我們有必要指出Style Transfer和其他傳統(tǒng)的有監(jiān)督學(xué)習(xí)的CV問(wèn)題之間的差異。
1.風(fēng)格這種抽象的概念,該如何定義?藝術(shù)領(lǐng)域的很多東西,通常都是很難量化的。如果要采用有監(jiān)督學(xué)習(xí)的方法的話,怎么獲得學(xué)習(xí)的標(biāo)簽?zāi)?#xff1f;
2.就算解決了第1個(gè)問(wèn)題,如何生成一批同一風(fēng)格的圖片也是一個(gè)大問(wèn)題。畫(huà)家可是稀缺資源啊。
因此,Style Transfer問(wèn)題的關(guān)鍵點(diǎn)就在于:如何利用僅有的1張風(fēng)格圖片,將其風(fēng)格遷移到其他圖片上。
早期方法
圖像風(fēng)格遷移這個(gè)領(lǐng)域,在2015年之前,連個(gè)合適的名字都沒(méi)有,因?yàn)槊總€(gè)風(fēng)格的算法都是各管各的,互相之間并沒(méi)有太多的共同之處。
比如油畫(huà)風(fēng)格遷移,里面用到了7種不同的步驟來(lái)描述和遷移油畫(huà)的特征。又比如頭像風(fēng)格遷移里用到了三個(gè)步驟來(lái)把一種頭像攝影風(fēng)格遷移到另一種上。以上十個(gè)步驟里沒(méi)一個(gè)重樣的。
可以看出這時(shí)的圖像風(fēng)格處理的研究,基本都是各自為戰(zhàn),搗鼓出來(lái)的算法也沒(méi)引起什么注意。
上圖是一個(gè)油畫(huà)風(fēng)格遷移的pipe line。
在實(shí)踐過(guò)程中,人們又發(fā)現(xiàn)圖像的紋理可以在一定程度上代表圖像的風(fēng)格。下文如無(wú)特指,紋理/風(fēng)格均為同義詞。
這又引入了和風(fēng)格遷移相關(guān)的另一個(gè)領(lǐng)域——紋理生成。這個(gè)時(shí)期,該領(lǐng)域雖然已經(jīng)有了一些成果,但是通用性也比較差。
早期紋理生成的主要思想:**紋理可以用圖像局部特征的統(tǒng)計(jì)模型來(lái)描述。**然而手工建模畢竟耗時(shí)耗力。。。
CNN的紋理特征
在進(jìn)行神經(jīng)風(fēng)格遷移之前,我們先來(lái)從可視化的角度看一下卷積神經(jīng)網(wǎng)絡(luò)每一層到底是什么樣子?它們各自學(xué)習(xí)了哪些東西。
遍歷所有訓(xùn)練樣本,找出讓該層激活函數(shù)輸出最大的9塊圖像區(qū)域;然后再找出該層的其它單元(不同的濾波器通道)激活函數(shù)輸出最大的9塊圖像區(qū)域;最后共找9次,得到9×99 \times 99×9的圖像如下所示,其中每個(gè)3×33 \times 33×3區(qū)域表示一個(gè)運(yùn)算單元。
可以看出隨著層數(shù)的增加,CNN捕捉的區(qū)域更大,特征更加復(fù)雜,從邊緣到紋理再到具體物體。
Deep Visualization
上述的CNN可視化的方法一般被稱作Deep Visualization。
論文:
《Understanding Neural Networks Through Deep Visualization》
這篇論文是Deep Visualization的經(jīng)典之作。作者是Jason Yosinski。
Jason Yosinski,Caltech本科+Cornell博士?,F(xiàn)為Uber AI Labs的科學(xué)家。
個(gè)人主頁(yè):
http://yosinski.com/
該文提出了如下公式:
V(Fil)=arg?max?XAil(X),X←X+η?Ail(X)?XV(F_i^l)=\mathop{\arg\max}_{X}A_i^l(X), X \leftarrow X + \eta\frac{\partial A_i^l(X)}{\partial X}V(Fil?)=argmaxX?Ail?(X),X←X+η?X?Ail?(X)?
X初始化為一張?jiān)肼晥D片,然后按照上述公式,優(yōu)化得到激活函數(shù)輸出最大的X。
Deep Visualization除了用于提取紋理之外,還可用于模型壓縮。
論文:
《Demystifying Neural Network Filter Pruning》
https://github.com/yosinski/deep-visualization-toolbox
這是作者Jason Yosinski提供的Deep Visualization的工具的代碼。
https://github.com/antkillerfarm/antkillerfarm_crazy/tree/master/deep-visualization-toolbox
原始版本是基于python 2編寫(xiě)的,這是我修改的python 3版本
https://github.com/Sunghyo/revacnn
這是另一個(gè)CNN可視化工具
參考:
https://zhuanlan.zhihu.com/p/24833574
Deep Visualization:可視化并理解CNN
http://www.cnblogs.com/jesse123/p/7101649.html
Tool-Deep Visualization
https://mp.weixin.qq.com/s/dflEAOELK0f19y4KuVd_dQ
40行Python代碼,實(shí)現(xiàn)卷積特征可視化
DL方法
受到上述事實(shí)的啟發(fā),2015年德國(guó)University of Tuebingen的Leon A. Gatys寫(xiě)了如下兩篇論文:
《Texture Synthesis Using Convolutional Neural Networks》
《A Neural Algorithm of Artistic Style》
代碼:
https://github.com/jcjohnson/neural-style
torch版本
https://github.com/anishathalye/neural-style
tensorflow版本
在第一篇論文中,Gatys使用Gramian matrix從各層CNN中提取紋理信息,于是就有了一個(gè)不用手工建模就能生成紋理的方法。
Gramian matrix(由J?rgen Pedersen Gram提出)中的元素定義如下:
Gij=?vi,vj?G_{ij}=\langle v_i, v_j \rangleGij?=?vi?,vj??
這里的viv_ivi?表示向量,GijG_{ij}Gij?是向量的內(nèi)積。可以看出Gramian matrix是一個(gè)半正定的對(duì)稱矩陣。
在第二篇論文中,Gatys更進(jìn)一步指出:紋理能夠描述一個(gè)圖像的風(fēng)格。
既然第一篇論文解決了從圖片B中提取紋理的任務(wù),那么還有一個(gè)關(guān)鍵點(diǎn)就是:如何只提取圖片內(nèi)容而不包括圖片風(fēng)格?
Cost Function
神經(jīng)風(fēng)格遷移生成圖片G的cost function由兩部分組成:C與G的相似程度和S與G的相似程度。
J(G)=α?Jcontent(C,G)+β?Jstyle(S,G)J(G)=\alpha \cdot J_{content}(C,G)+\beta \cdot J_{style}(S,G)J(G)=α?Jcontent?(C,G)+β?Jstyle?(S,G)
其中,α,β\alpha, \betaα,β是超參數(shù),用來(lái)調(diào)整Jcontent(C,G)J_{content}(C,G)Jcontent?(C,G)與Jstyle(S,G)J_{style}(S,G)Jstyle?(S,G)的相對(duì)比重。
神經(jīng)風(fēng)格遷移的基本算法流程是:首先令G為隨機(jī)像素點(diǎn),然后使用梯度下降算法,不斷修正G的所有像素點(diǎn),使得J(G)不斷減小,從而使G逐漸有C的內(nèi)容和S的風(fēng)格,如下圖所示:
換句話來(lái)說(shuō)就是:每次迭代只更新圖片G,而不更新網(wǎng)絡(luò)的參數(shù)。
我們先來(lái)看J(G)的第一部分Jcontent(C,G)J_{content}(C,G)Jcontent?(C,G),它表示內(nèi)容圖片C與生成圖片G之間的相似度。
使用的CNN網(wǎng)絡(luò)是之前預(yù)訓(xùn)練好的模型,例如Alex-Net。C,S,G共用相同模型和參數(shù)。
首先,需要選擇合適的層數(shù)l來(lái)計(jì)算Jcontent(C,G)J_{content}(C,G)Jcontent?(C,G)。
如前所述,CNN的每個(gè)隱藏層分別提取原始圖片的不同深度特征,由簡(jiǎn)單到復(fù)雜。如果l太小,則G與C在像素上會(huì)非常接近,沒(méi)有遷移效果;如果l太深,則G上某個(gè)區(qū)域?qū)⒅苯訒?huì)出現(xiàn)C中的物體。因此,l既不能太淺也不能太深,一般選擇網(wǎng)絡(luò)中間層。
若C和G在l層的激活函數(shù)輸出a[l](C)a^{[l](C)}a[l](C)與a[l](G)a^{[l](G)}a[l](G),則相應(yīng)的Jcontent(C,G)J_{content}(C,G)Jcontent?(C,G)的表達(dá)式為:
Jcontent(C,G)=12∣∣a[l](C)?a[l](G)∣∣2J_{content}(C,G)=\frac12||a^{[l](C)}-a^{[l](G)}||^2Jcontent?(C,G)=21?∣∣a[l](C)?a[l](G)∣∣2
接下來(lái),我們定義圖片的風(fēng)格矩陣(style matrix)為:
Gkk′[l]=∑i=1nH[l]∑j=1nW[l]aijk[l]aijk′[l]G_{kk'}^{[l]}=\sum_{i=1}^{n_H^{[l]}}\sum_{j=1}^{n_W^{[l]}}a_{ijk}^{[l]}a_{ijk'}^{[l]}Gkk′[l]?=i=1∑nH[l]??j=1∑nW[l]??aijk[l]?aijk′[l]?
風(fēng)格矩陣Gkk′[l]G_{kk'}^{[l]}Gkk′[l]?計(jì)算第l層隱藏層不同通道對(duì)應(yīng)的所有激活函數(shù)輸出和。若兩個(gè)通道之間相似性高,則對(duì)應(yīng)的Gkk′[l]G_{kk'}^{[l]}Gkk′[l]?較大。從數(shù)學(xué)的角度來(lái)說(shuō),這里的風(fēng)格矩陣實(shí)際上就是兩個(gè)tensor的互相關(guān)矩陣,也就是上面提到的Gram矩陣。
Gram矩陣描述的是全局特征的自相關(guān),如果輸出圖與風(fēng)格圖的這種自相關(guān)相近,那么差不多是我們所理解的”風(fēng)格”。當(dāng)然,其實(shí)也可以用很多其他的統(tǒng)計(jì)信息進(jìn)行描繪風(fēng)格。比如有用直方圖的, 甚至還可以直接簡(jiǎn)化成”均值+方差”的。
風(fēng)格矩陣Gkk′[l][S]G_{kk'}^{[l][S]}Gkk′[l][S]?表征了風(fēng)格圖片S第l層隱藏層的“風(fēng)格”。相應(yīng)地,生成圖片G也有Gkk′[l][G]G_{kk'}^{[l][G]}Gkk′[l][G]?。那么,Gkk′[l][S]G_{kk'}^{[l][S]}Gkk′[l][S]?與Gkk′[l][G]G_{kk'}^{[l][G]}Gkk′[l][G]?越相近,則表示G的風(fēng)格越接近S。這樣,我們就可以定義出Jstyle[l](S,G)J^{[l]}_{style}(S,G)Jstyle[l]?(S,G)的表達(dá)式:
Jstyle[l](S,G)=1(2nH[l]nW[l]nC[l])∑k=1nC[l]∑k′=1nC[l]∣∣Gkk′[l][S]?Gkk′[l][G]∣∣2J^{[l]}_{style}(S,G)=\frac{1}{(2n_H^{[l]}n_W^{[l]}n_C^{[l]})}\sum_{k=1}^{n_C^{[l]}}\sum_{k'=1}^{n_C^{[l]}}||G_{kk'}^{[l][S]}-G_{kk'}^{[l][G]}||^2Jstyle[l]?(S,G)=(2nH[l]?nW[l]?nC[l]?)1?k=1∑nC[l]??k′=1∑nC[l]??∣∣Gkk′[l][S]??Gkk′[l][G]?∣∣2
為了提取的“風(fēng)格”更多,也可以使用多層隱藏層,然后相加,表達(dá)式為:
Jstyle(S,G)=∑lλ[l]?Jstyle[l](S,G)J_{style}(S,G)=\sum_l\lambda^{[l]}\cdot J^{[l]}_{style}(S,G)Jstyle?(S,G)=l∑?λ[l]?Jstyle[l]?(S,G)
實(shí)現(xiàn)細(xì)節(jié)
這是原始論文的插圖,其符號(hào)表示和本文有所差異。其中的A、F、P各層的output,都是使用預(yù)訓(xùn)練好的Alex-Net生成的。
可以看出A和P,在整個(gè)迭代過(guò)程中,只需要進(jìn)行一次Alex-Net的前向計(jì)算,因此可以事先計(jì)算好。
為了在迭代過(guò)程中,不修改Alex-Net的權(quán)重,而只修改F,我們可以使用tf.constant來(lái)創(chuàng)建Alex-Net的各個(gè)參數(shù),進(jìn)而建立Alex-Net。這樣在backward的時(shí)候,梯度就只會(huì)修正到tf.Variable,也就是F上。
缺點(diǎn)
Gatys的方法雖然是里程碑式的進(jìn)步,但仍然有如下缺點(diǎn):
1.渲染速度緩慢。渲染一張圖片需要從隨機(jī)噪聲開(kāi)始,反復(fù)迭代若干次,才能得到最終的結(jié)果。
2.需要根據(jù)風(fēng)格的不同,調(diào)整不同的超參數(shù)。換句話說(shuō),就是一個(gè)Style Transfer的模型就只能用于轉(zhuǎn)換一種Style,通用型不強(qiáng)。
因此,之后的研究主要集中在對(duì)這兩方面的改進(jìn)上。針對(duì)前者的改進(jìn)可稱作fast style transfer,而后者可稱作Universal Style Transfer。
此外,不是所有的style transfer都是DL方法,很多新特效往往還是用傳統(tǒng)的濾鏡實(shí)現(xiàn)的。比如最近比較火的“新海誠(chéng)風(fēng)格”。
參考:
https://blog.csdn.net/Trent1985
一個(gè)濾鏡/美顏方面的blog
https://www.zhihu.com/question/29594460
新海誠(chéng)風(fēng)格的畫(huà)面是手繪的還是Photoshop就可以達(dá)到的?后期過(guò)程是怎樣的?
總結(jié)
以上是生活随笔為你收集整理的深度学习(三十一)——Style Transfer的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Ubuntu使用技巧(二)
- 下一篇: 深度学习(三十二)——AlphaGo,