PyTorch Taipei 2018 week10: Neural Style Transfer

講解影片連結在這裡。這篇論文內容比較簡單,所以講解重點擺在讓大家理解論文內容,若理解論文應該可以很快看懂code。

1. What’s Neural Style Transfer?

大家對Style Transfer這個詞可能很陌生,但應該很多人記得2016年在Apple Store和Google Play兩大平台皆奪下年度App的Prisma,將照片轉換成畫作的功能大受歡迎,或者你也可能記得或甚至使用過Facebook開發的real-time藝術畫風濾鏡

Fig. 1. Prisma範例圖片(Source: Prisma FB fanpage )

Neural Transfer就是這種將畫作上的藝術風格移植到其他圖片上的技巧,而這周要介紹的論文實作便是這項技術的開山之作《A Neural Algorithm of Artistic Style》(2015年發布於arXiv,2016年發表於CVPR上),作者為來自德國University of Tübingen的計算神經科學學者Leon A. Gatys, Alexander S. Ecker, Matthias Bethge,他們嘗試用CNN來實現這一項過去被認為是專屬於人類的技能並獲得廣大迴響,三人也憑此技術創立一家公司

Fig. 2. Style Transfer領域試圖將不同畫作風格融合進任意圖片中

2. How it works?

本篇論文的作法其實可以寫成簡單的一段話:

TL;DR: 使用一個pretrained CNN model,輸入內容圖(C)、風格圖(S)、輸出圖(G)三個圖片(其中輸出圖初始化為white noise或noisy內容圖),選定model中要使用哪幾層,再以三張圖在這幾層中的activation值設計出cost function,最後backprop更新輸出圖(G)上的pixel值。


下面為更詳盡的介紹:

2.0 Rewind: What does CNN captured?

首先,我們要回憶一下CNN架構實際上做了哪些事情,2013年ImageNet冠軍ZFNet論文(也是PyTorch Taipei第二周主題,可以參考士永社長提供之講解資料影片)中提到,他們嘗試將每層中activation值最大的部分,還原出是在原圖上的哪個區塊,並發現較為淺層的捲積層捕捉到的只是單純的線條與顏色,然而越深層的捲積層捕捉到的會越趨一個完整的物件。而本篇論文就是利用CNN架構能捕捉不同規模之特徵的特性,嘗試將不同的紋理與顏色融合到輸入圖中

Fig. 3. ZFNet中各層捕捉到的特徵

2.1 Methods

原作作法為輸入以下三張圖進一個已經train好的CNN model(原作使用VGG19,VGG論文可參考PyTorch Taipei第五周由陳峻廷所提供之講解資料影片)中:

  1. 內容圖(C): 想要將風格套用於其上的圖片
  2. 風格圖(S): 含有特殊風格的圖片
  3. 輸出圖(G): 初始化為和C一樣大的white noise圖片,或是也可以輸入有雜訊的內容圖

再選擇特定捲積層之activation值,分別計算C, G之間的cost function $J_{content}$ 和S, G之間的cost function $J_{style}$,以不同比例相加得到最後的cost function $J(G)$

透過backprop迭代更新輸出圖(G)上的pixel值以降低$J(G)$,其中$\alpha$和$\beta$的比值可以經調整得到不一樣的輸出效果。

Fig. 4. 以backprop更新輸出圖之範例(輸出圖G初始化為noisy的內容圖C)

2.2 Content Cost Function

內容圖(C)和輸出圖(G)之間的cost function為特定某一捲積層activation值的函數,這一層通常位在整體架構較中間的位置(原作使用VGG19的conv4_2):

其中 $ a^{[l]\left( C \right) }$ 和 $ a^{[l]\left( G \right) }$ 分別為內容圖(C)和輸出圖(G)在第$l$層的activation值。如果 $J_{content}$ 小代表內容圖(C)和輸出圖(G)在相同位置上具有相似的特徵。

2.3 Style Cost Function

風格圖(S)和輸出圖(G)之間的cost function較為複雜,是一個特定數層捲積層activation值的函數(原作使用VGG19的conv1_1, conv2_1, conv3_1, conv4_1, conv5_1),目的是要得到channels之間的correlation

首先要看其中一層的cost function $J_{style}^{[l]}(S,G)$,實際上為風格圖(S)和輸出圖(G)的Gram matrix之normalized mean-sqaured distance。

風格圖(S)和輸出圖(G)在model中第$l$層的Gram matrices $ g^{[l]} $ 大小為 $n_C^{[l]} \times n_C^{[l]}$,矩陣內entry值可列式為:

其中 $ a_{ijk}^{[l]} $ 表示該捲積層中位置(height, width, channel)=(i,j,k)的activation值。

不過gram matrix還是以圖來表示較容易理解:

Fig. 5. Gram matrix的entry為任兩個channel之間activation值的內積 (Source: Deeplearning.ai)

有了gram matrix便可得到該層style cost function:

而每一層的 $ J_{style}^{[l]} $ 再以不同weighting $ \lambda^{[l]} $ 相加得到 $ J_{style} $ (原作五層weighting都是0.2):

2.4 Overall Process

總而言之,$J_{content}$ 只運用CNN架構中的某一層的activation值,降低$J_{content}$會使輸出圖(G)在內容圖(C)相同位置上出現一樣的特徵,而$J_{style}$ 的計算涵蓋多層的activation值,降低$J_{style}$會使輸出圖(G)和風格圖(S)在CNN某層上不同channel所抓取到的特徵關係相近(不考慮特徵出現位置)。

CVPR論文內的一張圖(點擊放大)可以概括說明整個流程:

Fig. 7. Style Transfer 演算法流程

3. Result

論文有展示一些調整參數的效果,這裡只是撿過來放而已。

Fig. 8. 同一張內容圖施以不同風格之結果

圖8的A為原圖,B~E為施加不同風格圖的結果,而其所合適之$\alpha / \beta$值也不同: B為$1 × 10^{−3}$, C為$8 × 10^{−4}$, D為$5 × 10^{−3}$, E和F為$5 × 10^{−4}$。

Fig. 9. 不同參數之表現比較。

圖9左圖: 相同$\alpha / \beta$值與style cost function,但content cost function選取不同層的結果,哪個表現比較好應該是見仁見智(?)。

圖9右圖:橫軸為不同的 $\alpha / \beta$值,縱軸為style cost function涵蓋不同層數,row A為只計算conv1_1一層、row B為計算conv1_1和conv2_1兩層、row C涵蓋三層…依此類推。可見$\alpha / \beta$越小則輸出圖(G)和內容圖(C)相去越遠而只含有風格特徵。而當style cost function只計算conv1_1一層則表現出較細微的風格特徵,計算涵蓋越深層則有較大的風格特徵。

4. Sample Code

請移駕至講者的GitHub,有Tensorflow版本(吳恩達課程內的作業,使用VGG16),和PyTorch版本(論文第一作者的repo及官方教學文件)。

5. Discussion

本篇論文演算法較為簡單,然而實際運行結果有一些比較明顯的缺失:

  1. 未考慮空間、亮度等因素: 例如可能會把地面的特徵套用在天空之類的情況。不過第一作者後續有出了數篇針對改善這個缺點的論文,像是這篇這篇
  2. 又肥又慢: VGG在CNN發展歷史中曾獲得一時的勝利是因為增加了很多層的捲積層,造成model很佔空間、執行時間也比較久。不過在本文開頭就告訴大家已經有real-time的產品,代表已經有多篇關於能夠快速執行style transfer的論文被發表了。

目前已經有style transfer領域的review paper了,有興趣可以去看看學界後來又延伸發展了那些主題或改善方法。

Reference

  1. 本篇文章介紹之style transfer論文
  2. ZFNet
  3. VGG
  4. 吳恩達在Coursera上開設之深度學習線上課程
  5. PyTorch official tutorial
  6. Mark Chang’s slides & video (偏重實驗的講解,很值得一看)
  7. Neural Style Transfer: A Review


Wei-Hsiang Wang

Grad. student, Dept. of M.E., NTU, Taiwan

Updated:


Comments