fast neural style transfer圖像風格遷移基於tensorflow實現


一、風格遷移簡介

風格遷移(Style Transfer)是深度學習眾多應用中非常有趣的一種,如圖,我們可以使用這種方法把一張圖片的風格“遷移”到另一張圖片上:

 

然而,原始的風格遷移(論文地址:)的速度是非常慢的。在GPU上,生成一張圖片都需要10分鍾左右,而如果只使用CPU而不使用GPU運行程序,甚至需要幾個小時。這個時間還會隨着圖片尺寸的增大而迅速增大。

 

這其中的原因在於,在原始的風格遷移過程中,把生成圖片的過程當做一個“訓練”的過程。每生成一張圖片,都相當於要訓練一次模型,這中間可能會迭代幾百幾千次。如果你了解過一點機器學習的知識,就會知道,從頭訓練一個模型要比執行一個已經訓練好的模型要費時太多。而這也正是原始的風格遷移速度緩慢的原因。

二、快速風格遷移簡介

那有沒有一種方法,可以不把生成圖片當做一個“訓練”的過程,而當成一個“執行”的過程呢?答案是肯定的。這就這篇快速風格遷移(fast neural style transfer):Perceptual Losses for Real-Time Style Transfer and Super-Resolution

快速風格遷移的網絡結構包含兩個部分。一個是“生成網絡”(原文中為Transformation Network),一個是“損失網絡”(Loss Network)。生成網絡接收一個圖片當做輸入,然后輸出也是一張圖片(即風格遷移后的結果)。如下圖,左側是生成網絡,右側為損失網絡:

訓練階段:訓練的目標是讓生成網絡可以有效生成圖片。目標由損失網絡定義。

具體過程:選定一張風格圖片。訓練過程中,將數據集中的圖片輸入網絡,生成網絡生成結果圖片y,損失網絡提取圖像的特征圖,將生成圖片y分別與目標風格圖片ys和目標輸入圖片(內容圖片)yc做損失計算,根據損失值來調整生成網絡的權值,通過最小化損失值來達到目標效果。

執行階段:給定一張圖片,將其輸入生成網絡,輸出這張圖片風格遷移后的結果。

我們可以發現,在模型的“執行”階段我們就可以完成風格圖片的生成。因此生成一張圖片的速度非常塊,在GPU上一般小於1秒,在CPU上運行也只需要幾秒的時間。

生成網絡     

       對於生成網絡,本質上是一個卷積神經網絡,這里的生成網絡是一個深度殘差網絡,不用任何的池化層,取而代之的是用步幅卷積或微步幅卷積做網絡內的上采樣或者下采樣。這里的神經網絡有五個殘差塊組成。除了最末的輸出層以外,所有的非殘差卷積層都跟着一個空間性的instance-normalization,和RELU的非線性層,instance-normalization正則化是用來防止過擬合的。最末層使用一個縮放的Tanh來確保輸出圖像的像素在[0,255]之間。除開第一個和最后一個層用9x9的卷積核(kernel),其他所有卷積層都用3x3的卷積核。

 

損失網絡

       

        損失網絡φ是能定義一個內容損失(content loss)和一個風格損失(style loss),分別衡量內容和風格上的差距。對於每一張輸入的圖片x我們有一個內容目標yc一個風格目標ys,對於風格轉換,內容目標yc是輸入圖像x,輸出圖像y,應該把風格ys結合到內容x=yc上。系統為每一個目標風格訓練一個網絡。

        為了明確逐像素損失函數的缺點,並確保所用到的損失函數能更好的衡量圖片感知及語義上的差距,需要使用一個預先訓練好用於圖像分類的CNN,這個CNN已經學會感知和語義信息編碼,這正是圖像風格轉換系統的損失函數中需要做的。所以使用了一個預訓練好用於圖像分類的網絡φ,來定義系統的損失函數。之后使用同樣是深度卷積網絡的損失函數來訓練我們的深度卷積轉換網絡。

        這里的損失網絡雖然也是卷積神經網絡(CNN),但是參數不做更新,只用來做內容損失和風格損失的計算,訓練更新的是前面的生成網絡的權值參數。所以從整個網絡結構上來看輸入圖像通過生成網絡得到轉換的圖像,然后計算對應的損失,整個網絡通過最小化這個損失去不斷更新前面的生成網絡權值。

 

感知損失

      

       對於求損失的過程,不用逐像素求差構造損失函數,轉而使用感知損失函數,從預訓練好的損失網絡中提取高級特征。在訓練的過程中,感知損失函數比逐像素損失函數更適合用來衡量圖像之間的相似程度。

(1)內容損失

        上面提到的論文中設計了兩個感知損失函數,用來衡量兩張圖片之間高級的感知及語義差別。內容的損失計算用VGG計算來高級特征(內容)表示,因為VGG模型本來是用於圖像分類的,所以一個訓練好的VGG模型可以有效的提取圖像的高級特征(內容)。計算的公式如下:

 

        找到一個圖像 y使較低的層的特征損失最小,往往能產生在視覺上和y不太能區分的圖像,如果用高層來重建,內容和全局結構會被保留,但是顏色紋理和精確的形狀不復存在。用一個特征損失來訓練我們的圖像轉換網絡能讓輸出非常接近目標圖像y,但並不是讓他們做到完全的匹配

 

       (2)風格損失

       內容損失懲罰了輸出的圖像(當它偏離了目標y時),所以同樣的,我們也希望對輸出的圖像去懲罰風格上的偏離:顏色,紋理,共同的模式,等方面。為了達成這樣的效果,一些研究人員等人提出了一種風格重建的損失函數:讓φj(x)代表網絡φ的第j層,輸入是x。特征圖譜的形狀就是Cj x Hj x Wj、定義矩陣Gj(x)為Cj x Cj矩陣(特征矩陣)其中的元素來自於:

 

       如果把φj(x)理解成一個Cj維度的特征,每個特征的尺寸是Hj x Wj,那么上式左邊Gj(x)就是與Cj維的非中心的協方差成比例。每一個網格位置都可以當做一個獨立的樣本。這因此能抓住是哪個特征能帶動其他的信息。梯度矩陣可以很高效的計算,通過調整φj(x)的形狀為一個矩陣ψ,形狀為Cj x HjWj,然后Gj(x)就是ψψT/CjHjWj。風格重建的損失是定義的很好的,甚至當輸出和目標有不同的尺寸是,因為有了梯度矩陣,所以兩者會被調整到相同的形狀。

三、快速風格遷移的Tensorflow實現

話不多說,直接上我的代碼的Github地址:hzy46/fast-neural-style-tensorflow

還有變換效果如下。

原始圖片:

 

風格遷移后的圖片:

 

 

以上圖片在GPU(Titan Black)下生成約需要0.8s,CPU(i7-6850K)下生成用時約2.9s。

 

關於快速風格遷移,其實之前在Github上已經有了Tensorflow的兩個實現:

但是第一個項目只提供了幾個訓練好的模型,沒有提供訓練的代碼,也沒有提供具體的網絡結構。所以實際用處不大。

而第二個模型做了完整的實現,可以進行模型的訓練,但是訓練出來的效果不是很好,在作者自己的博客中,給出了一個范例,可以看到生成的圖片有很多噪聲點:

我的項目就是在OlavHN/fast-neural-style的基礎上做了很多修改和調整。

四、一些實現細節

1、與Tensorflow Slim結合

在原來的實現中,作者使用了VGG19模型當做損失網絡。而在原始的論文中,使用的是VGG16。為了保持一致性,我使用了Tensorflow Slim(地址:tensorflow/models)對損失網絡重新進行了包裝。

Slim是Tensorflow的一個擴展庫,提供了很多與圖像分類有關的函數,已經很多已經訓練好的模型(如VGG、Inception系列以及ResNet系列)。

下圖是Slim支持的模型:

 

使用Slim替換掉原先的網絡之后,在損失函數中,我們不僅可以使用VGG16,也可以方便地使用VGG19、ResNet等其他網絡結構。具體的實現請參考源碼。

 

2、改進轉置卷積的兩個Trick

原先我們需要使用網絡生成圖像的時候,一般都是采用轉置卷積直接對圖像進行上采樣。

這篇文章指出了轉置卷積的一些問題,認為轉置卷積由於不合理的重合,使得生成的圖片總是有“棋盤狀的噪聲點”,它提出使用先將圖片放大,再做卷積的方式來代替轉置卷積做上采樣,可以提高生成圖片的質量,下圖為兩種方法的對比:

對應的Tensorflow的實現:

 

以上為第一個Trick。

第二個Trick是文章 Instance Normalization: The Missing Ingredient for Fast Stylization 中提到的,用 Instance Normalization來代替通常的Batch Normalization,可以改善風格遷移的質量。

3、注意使用Optimizer和Saver

這是關於Tensorflow實現的一個小細節。

在Tensorflow中,Optimizer和Saver是默認去訓練、保存模型中的所有變量的。但在這個項目中,整個網絡分為生成網絡和損失網絡兩部分。我們的目標是訓練好生成網絡,因此只需要去訓練、保存生成網絡中的變量。在構造Optimizer和Saver的時候,要注意只傳入生成網絡中的變量。

找出需要訓練的變量,傳遞給Optimizer:

 

五、總結

總之是做了一個還算挺有趣的項目。代碼不是特別多,如果只是用訓練好的模型生成圖片的話,使用CPU也可以在幾秒內運行出結果,不需要去搭建GPU環境。建議有興趣的同學可以自己玩一下。(再貼下地址吧:hzy46/fast-neural-style-tensorflow

關於訓練,其實也有一段比較坎(dan)坷(teng)的調參經歷,下次有時間再分享一下,今天就先寫到這兒。謝謝大家!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM