社群瘋傳的AI繪畫技術,是怎麼煉成的?

近十年來,深度學習領域技術的快速發展,為人們帶來許多方便的應用,例如機器翻譯、影像識別、物體定位等,深度學習也成為許多軟體開發者必備的武器。越來越多工具的開發,也降低了學習的門檻,許多沒有資料科學相關背景的學習者,也可以透過Keras和TensorFlow等先進工具,快速建構有趣的深度學習應用。

Keras及TensorFlow有著極為深厚的關係,Keras是Python的深度學習API,建立在TensorFlow之上,提供了簡易的方法來定義及訓練深度學習模型。自2021年底,Keras的使用者已經超過百萬人,包括各大企業及新創公司的工程師、資料科學家及學術研究者。連Youtube的影片推薦系統,以及Waymo的自駕車都是利用Keras開發的,更是Kaggle上的熱門框架。

Keras比TensorFlow還早出現8個月,一開始,它是建立在Theano(由蒙特婁大學的蒙特婁學習算法研究所開發的函式庫),在TensorFlow發布後,使用者可以在兩者間切換。隨著TensorFlow技術的成熟,加上Theano已不再更新,Keras成為使用者在開發TensorFlow應用時,最好用的工具。多年來,Keras和TensorFlow也一直維持著深厚的共生關係,更進一步將更多使用者帶入TensorFlow的生態圈。

《Keras大神歸位:深度學習全面進化!用Python實作CNN、RNN、GRU、LSTM、GAN、VAE、Transformer》這本書是由Keras的創始者親自撰寫,沒有人比他更了解Keras這套工具。但是,這並不是一本Keras使用手冊,而是帶領學習者從頭開始探索深度學習的入門學習書,進而拓展對深度學習理解。從中了解解決機器學習問題的標準作業流程,以及未來實務上如何克服可能遇到的問題。透過以下精選的內容,我們先了解透過Keras可以實現哪些有趣的應用?


社群瘋傳的AI繪畫技術,是怎麼煉成的?

近期,有一群開發者製作出全新的AI算圖工具MidJourney。與目前主流的算圖工具相比,MidJourney的速度更快,品質也更好,完全分不出到底是電腦產生還是人類畫的。產生圖片的方法也很簡單:只要在MidJourney的服務器上輸入英文關鍵字,AI就會產生對應的作品,而且過程僅需1分鐘左右。因此,網路上有人戲稱:「繪師苦工10年的技術,AI只花60秒就辦到了」。

無可否認的,深度學習的出現,延伸出了許多有趣的技術。除了以上的圖片生成技術外,較為廣泛使用的另一類技術為圖片修改技術。在2015年夏季,Leon Gatys等人發表了神經風格轉換(neural style transfer)的技術。神經風格演算法自發表後經過多次改進,產生了許多功能變化,也已被引進到許多智慧手機的照片應用程式。

所謂的神經風格轉換,主要是將參考圖片的風格應用於內容圖片,同時保留內容圖片的內容:

(圖片來源:旗標科技提供)

風格轉換背後的關鍵概念,與所有深度學習演算法的核心相同:藉由定義一個損失函數來指定想要達成的目標,並最大化地減少損失。如果以數學來定義內容(content)和風格(style),那麼損失函數將如下所示:

此處,我們所用到的內容圖片及風格參考圖片如下所示:

(圖片來源:旗標科技提供)

↑內容圖片↑

(圖片來源:旗標科技提供)

↑風格參考圖片↑

我們可以使用任何預先訓練的CNN來實現神經風格轉換。在此我們將使用Gatys等人使用的VGG19網路。神經風格轉換的過程如下:

1.設定一個神經網路,同時為風格參考圖片、內容圖片和生成圖片計算VGG19 層的激活結果。
2.使用圖片的層激活結果來定義前面描述的損失函數(要最小化的值)。
3.設定梯度下降處理程序,並最小化損失函數。

現在,先來設定VGG19網路的程式碼,我們會用它來建立一個特徵萃取模型,以傳回中間層的結果:

計算內容損失

在卷積神經網路中,較低層的激活結果包含關於圖片的局部(local)資訊,而較高層的激活結果則包含較全局(global)且抽象的資訊。因此,我們期望透過CNN的上層,可以萃取出圖片內容中更為全局和抽象的表示法。

計算內容損失的一個好方法,是使用預先訓練的CNN(此處會使用VGG19網路)上層計算出「內容圖片的激活結果」與「生成圖片的激活結果」之間的L2 norm。這樣相對保證了從上層看起來,所生成的圖片會類似於原始內容圖片。以下為內容損失的相關程式碼:

計算風格損失

內容損失僅使用單一的CNN高階層,但Gatys等人定義的風格損失卻是使用CNN 的多個層,也就是嘗試以CNN對風格參考圖片萃取出「所有空間萃取比例」的整體樣貌,而不只是單一萃取比例的樣貌。對於風格損失,Gatys等人使用層的「激活結果的格拉姆矩陣」(Gram matrix),也就是對於層內的特徵圖進行內積。該內積可以理解為該層內各特徵之間的關聯性。這些特徵關聯性可呈現出在該空間萃取比例下的樣式統計數據,而這些數據通常可對應到在該空間比例下所辨識出的紋理外觀。

因此,風格損失的目的是在風格參考圖片和生成的圖片中,保存不同層激活結果的內部相似關聯性,確保了在不同空間比例中找到的紋理樣貌,在風格參考圖片和生成圖片中看起來很相似。以下為風格損失的相關程式碼:

簡言之,我們可以使用預先訓練的CNN(即:VGG19)執行以下程序以定義出損失:

1.透過維持內容圖片和生成圖片在CNN高階層激活結果的相似性,使得CNN在內容圖片和生成圖片間「看到」相同的內容:代表生成圖片中保留了內容 圖片的內容。2.透過在低階層和高階層的激活結果中,維持相似的關聯性(correlation)來保留風格。特徵關聯性可看成是某種紋理樣貌:生成圖片和風格參考圖片應該在不同的空間萃取比例中,有著相似的紋理樣貌。

除了這兩項損失外,我們還要增加第3項:總變異損失(total variation loss)。它主要是對生成圖片的像素進行計算,用於促進生成圖片的空間連續性,以避免過度像素顆粒化的結果(編註:概念上就是加總所有相鄰像素間的差異來做為損失, 如此就可讓相鄰像素間不會變化過大),請見以下程式:

我們要最小化這3種損失的加權平均值。在計算內容損失時,我們只會用到一個高階層:block5_conv2層。而對於風格損失,則會以串列將要使用到的低階層與高階層一起打包使用,最後再加上總變異損失。以下程式碼定義了要最小化的最終損失:

最後,我們來設定梯度下降的程序(請見以下程式碼)。Gatys等人在論文中是使用L-BFGS演算法進行優化,但在TensorFlow中無法使用,所以我們只會用SGD優化器來做小批次的梯度下降。我們還會運用學習率排程 (learning-rate schedule)在訓練過程中逐漸降低學習率,從很高的值(100)降到小很多的最終值(約20)。如此一來,我們就能在訓練早期快速取得進展,並在接近最低損失值時,用更謹慎的方式進行訓練。

下圖顯示了計算得到的結果。請記住,這項技術所實現的僅僅是圖片重構,或樣貌轉換的一種形式。它最適用於具有強烈紋理和高度一致性的風格參考圖片, 且內容圖片的內容不需要高階細節便可識別。

以上神經風格轉換的完整實作程式碼請見:https://pse.is/48a5gl,也鼓勵讀者自行嘗試不同的內容圖片和風格參考圖片,看看能嘗試什麼樣的有趣結果。

本文節錄自《Keras大神歸位!深度學習全面進化》,由旗標科技授權轉載。