竇亞玲,周武彬,季人煌
(湖南師范大學信息科學與工程學院,長沙 410081)
圖像風格遷移可以被看成是圖像紋理轉移的問題。大量成熟的算法通過對原始圖像的重新采樣來合成相似的人造紋理[1]。已有的紋理轉換算法通過非線性的參數(shù)化的紋理合成方法達到保護目標圖像結構的目的[2,3]。然而圖像的內容與風格的處理仍然是一個艱巨任務。近年來,卷積神經網絡[4]迅速崛起。一個卷積神經網絡由若干的卷積層、池化層、全連接層構成。通過這種模式,可以搭建出不同層數(shù)的卷積神經網絡。局部連接和權值共享是卷積層的操作方法,在處理圖像過程中讓不同的窗口的數(shù)據(jù)與一組固定的權重做內積(依次讓每個元素相乘之后再求和),每次計算后得到的一個特征圖傳入到池化層。池化層對結果進行縮減,去掉特征圖中不重要的部分,減少過擬合情況,同時也用于降低維度。大量的實踐結果證實,卷積神經網絡使用足夠多的數(shù)據(jù)進行訓練,能在通用的特征表示中得到圖像內容,進而推廣到紋理識別和風格區(qū)分的應用中。
本文以Python作為開發(fā)語言,采用Keras框架及大量第三方庫實現(xiàn)卷積神經網絡方法和Neural Style算法對圖像風格遷移的處理,達到藝術化的效果。同時對Neural Style算法進行一些改進,以提高其實際應用的效果。
Neural style算法理論中包括三部分:圖像內容表示、圖像風格表示、圖像風格遷移。其中,圖像風格研究結果表明圖像紋理可以用于描述圖像風格,在感知上它們所表達的就是相同的,從而圖像風格的表述就轉為圖像紋理的表述。采用圖像局部的特征統(tǒng)計模型來構造紋理,得到圖像風格。
一般而言,卷積神經網絡中的每層都會有過濾器。對于圖像x→,卷積神經網絡中的不同層會利用這些過濾器對圖像處理。假設在l層擁有Nl個過濾器,那么就會生成Nl個大小為Ml的特征圖,其中Ml表示的是對應的特征圖的面積。這樣一來,每一層生成的特征圖集合就可以運用矩陣Fl∈RNl×Ml來存儲,其中代表在l層的j位置上的第i個過濾器的激活值。通過在一幅白噪聲圖像上使用梯度下降算法,尋找與輸入圖像的特征響應結果相符合的另外一幅圖像,以此將圖像信息在層級結構的不同層上進行編碼。
和分別代表為初始圖像和處理后新的圖像,再令Pl和Fl分別代表它們在l層中的特征表示。如此一來,就可以確定它們兩個之間的殘差平方和損失函數(shù):
在這里還可以利用均方根誤差的反向傳遞來得到對應的圖像的梯度。于是,我們可以通過修改圖像直到它與初始圖像在某個卷積神經網絡層得到相同的反饋。
利用一個特定的紋理信息特征空間,可以從風格圖像中獲取到想要的風格。該特征空間可以建立在卷積神經網絡任意層的過濾器處理后的輸出之上。其中的期望值則是取決于特征映射的空間范圍[5]。
對于特征關系,運用格萊姆矩陣Gl∈RNl×Nl來表示。其中有多個不同網絡層之間的相互關系。利用它可以得到一個有關輸入圖像的準確的、多角度的表示。還能夠取到紋理信息,不過圖像的整體結構信息不在其中。其中表示的是在l層的特征圖中i和j之間的點積:
通過選定圖像的風格表示構建新的圖像,在卷積神經網絡不同層級之間構造風格的特征空間上獲取信息實現(xiàn)風格重建。白噪聲圖像中原始圖像的格拉姆矩陣與生成圖像的格拉姆矩陣之間的均方距離的最優(yōu)化也是通過梯度下降算法實現(xiàn)。和分別代表源圖像和產成的新圖像,Al和Gl則分別代表l層的風格表示,則l層所占的比重相較于總損失而言,為:
總的風格損失函數(shù)是:
El相對于像素→的梯度可以利用均方根誤差反向傳遞得到。
為了將風格圖像的風格在內容圖像→上表現(xiàn)出來,需要同時糅合圖像里的內容表示與→圖像中的風格表示,從而得到一個嶄新的圖像。最小化距離通過白色噪聲圖像的特征表示,從某層中圖像的內容表示以及在多個層上定義的風格表示獲得。最小化的函數(shù)是:
根據(jù)算法理論,將圖像風格轉換的設計如圖1:
圖1 圖像風格遷移設計圖
算法程序實現(xiàn)分步進行,具體步驟描述如下:
Step 1:導入需要使用到的第三方庫以及卷積神經網絡。
Step 2:獲取得到內容圖像和風格圖像并進行初步處理。獲取兩幅圖像采用Python提供的控件及其內部代碼針對控件的響應事件編寫處理代碼即可。讀取圖像時將其路徑分別以字符串格式保留下來,并與其他字符結合起來,構成一條可調用的命令行。
Step 3:將輸入圖像進行轉換來滿足卷積神經網絡的輸入規(guī)范。因為網絡處理后的返回值也是它自身定義的格式,而這種格式不能在系統(tǒng)中表示,所以也需要將其反向轉變?yōu)橄到y(tǒng)能夠表述的格式。因此定義了兩個函數(shù),代碼如下:
在圖像預處理函數(shù)中,傳入圖片的路徑名,使用Keras框架中的預置方法來讀取圖片。同時,因為不需要使用到全連接層,函數(shù)中最后一個參數(shù)的值并不會影響結果,這里使用圖像的行數(shù)和列數(shù)組合成的元組傳入為最后一個參數(shù)。調用img_to_array函數(shù)進一步將圖片格式轉換為numpy數(shù)組??紤]到在Keras中,彩色圖像的表示是四階張量,而先載入的圖像是三階張量,為了消除兩者的差異,使用Keras內置函數(shù)通過維度擴展將圖像擴展為四階張量。最后,完成去均值、將RGB色彩表示轉換為BGR色彩表示(這是因為最早的Cafffe框架中定義的色彩表示為BGR)以及維度調整(依據(jù)Keras框架后端設定的維度順序,將通道維等調整正確)三項工作。另一個函數(shù)deprocess_image則是上述步驟的反操作,是為了將最后的輸出圖像的格式能夠在系統(tǒng)中表示出來。
Step 4:將內容、風格、白噪聲三幅圖像經過預處理函數(shù)處理之后,組合成為一個張量當做卷積網絡的輸入,關鍵處理代碼如下:
Step 5:通過將內容圖像的內容表示和風格圖像的風格表示抽離出來,構造一個損失函數(shù),目標則是盡量縮小損失的數(shù)值。其中風格損失和內容損失見計算公式(1)和(5),再加上一個正則化的參數(shù)(為了避免過擬合,使圖像線條柔和),最后將這幾個數(shù)值經過某種加權計算,得到最終的損失值。
在定義這三部分之前,需要先定義格萊姆矩陣的計算方式(調用函數(shù)將得到的特征圖進行降維,然后與轉置矩陣相乘)。風格損失函數(shù)的輸入為風格圖片與待優(yōu)化圖片的表示;內容損失函數(shù)的輸入與之相似。平滑處理則是通過施加整體變分正則化,使得生成的圖像線條更加柔和。函數(shù)定義如下:
損失函數(shù)的計算過程就是相關張量之間的映射關系,輸入是由內容圖像,風格圖像以及白噪聲圖像組成,那么輸出就是損失函數(shù)將輸入張量進行處理后得到相對應的梯度。核心代碼如下:
其中的變量content_weight和style_weight分別是公式(6)的參數(shù),目前設定的比例為10-3。最后,將全變差約束也加入到損失計算,得到總損失。
Step 6:獲取反向梯度。在得到損失值和輸入之后,可以利用梯度函數(shù)來獲取反向梯度:這里處理的圖像,只用到白噪聲圖像,便于之后圖像的迭代和優(yōu)化。在這之前,前面一切的操作步驟都只是調節(jié)各種差異,滿足處理要求,在這之后,定義的這張噪聲圖才具有了真正價值。使用優(yōu)化方法時,需要設置4個參數(shù):第一個是待優(yōu)化的函數(shù);第二個是開始的白噪聲圖;第三個是一個可調用的函數(shù),返回得到梯度;最后一個是待優(yōu)化函數(shù)需要迭代的次數(shù)。
Step 7:完成上面的所有操作。接下來只需要通過循環(huán):對于給定輸入圖像x,獲取反向梯度,再根據(jù)反向梯度更新x。在迭代完成后得到一幅風格遷移圖像。
核心代碼如下:
選擇一幅風景圖片,之后選擇不同的風格(本測試程序設定了四種不同藝術畫作風格)。圖2、3分別展示了原圖像以梵高星空、莫奈花園畫作進行圖像遷移后的效果圖。通過對已經轉換好的風景圖片的前后對比,發(fā)現(xiàn)風景圖片和藝術圖像所畫的內容相近的轉換效果更好。例如,同樣是小橋流水對上花園就可以比較好的將藝術照的風格轉換到風景圖像上;相反,若是將有關人物描寫的藝術圖像的風格強行轉換到自然風格的風景圖像上時,雖然也能起到部分效果,但是會給人一種不是很協(xié)調的感覺。此外,光線的不同也會導致所要的效果出現(xiàn)一定的差異。例如,將梵高的星空藝術圖像的風格轉換到一幅的白天時間下的風景圖像,經過轉換后得到的效果圖像的意境會發(fā)生很大變化。不過這樣也使得圖像產生了別樣的美感。
圖2 圖像經過星空處理前后對比
圖3 圖像岳王亭經過花園處理前后對比
我們以圖2中的星空風格為例,測試了程序迭代過程不同迭代次數(shù)的圖像風格遷移效果,圖4-6分別是第1次、第5次和最終優(yōu)化后的圖像效果。從這幾幅圖的對比中可以看到,隨著損失值不斷縮小,得到的效果圖也愈加清晰。
圖4 第1次迭代生成圖
圖5 第5次迭代生成圖
圖6 最后生成效果圖
本文運用卷積神經網絡方法實現(xiàn)了圖像風格遷移,所設計實現(xiàn)的程序能將多種油畫風格遷移到待遷移風格的原圖像上生成新的藝術化圖像。由于卷積神經網絡需要從初始狀態(tài)開始重新學習,導致每一次圖像風格轉換的處理時間較長;而噪聲處理以及計算過于復雜等原因,造成生成后的圖像效果在局部的細節(jié)方面有些模糊,這些都是需要改進的問題。