還記得火爆全網的圖解Transformer嗎?
最近這位大佬部落客Jay Alammar在部落格上對大火的Stable Diffusion模型也寫了一篇圖解,讓你從零開始徹底搞懂影像生成模型的原理,還配有超詳細的視訊講解!
文章連結:https://jalammar.github.io/illustrated-stable-diffusion/
#影片連結:https://www.youtube.com/watch?v=MXmacOUJUaw
#AI模型最新展現出的圖像生成能力遠遠超出人們的預期,直接根據文字描述就能創造出具有驚人視覺效果的圖像,其背後的運行機制顯得十分神秘與神奇,但確實影響了人類創造藝術的方式。
Stable Diffusion的發布是AI影像生成發展過程中的一個里程碑,相當於為大眾提供了一個可用的高效能模型,不僅生成的影像品質非常高,運行速度快,並且有資源和記憶體的要求也較低。
相信只要試過AI圖像生成的人都會想了解它到底是如何運作的,這篇文章就將為你揭開Stable Diffusion工作原理的神秘面紗。
Stable Diffusion從功能上來說主要包括兩個面向:1)其核心功能為僅根據文字提示作為輸入來產生的圖像(text2img );2)你也可以用它對圖像根據文字描述進行修改(即輸入為文字圖像)。
下面將使用圖示來輔助解釋Stable Diffusion的元件,它們之間如何交互,以及圖像生成選項及參數的含義。
Stable Diffusion是一個由多個元件和模型組成的系統,而不是單一的模型。
當我們從模型整體的角度向模型內部觀察時,可以發現,其包含一個文本理解組件用於將文本信息翻譯成數字表示(numeric representation),以捕捉文本中的語意訊息。
雖然目前還是從宏觀角度分析模型,後面才有更多的模型細節,但我們也可以大致推測這個文本編碼器是一個特殊的Transformer語言模型(具體來說是CLIP模型的文字編碼器)。
模型的輸入為一個文字字串,輸出為一個數字列表,用來表徵文字中的每個單字/token,即將每個token轉換為一個向量。
然後這些資訊會被提交到圖像產生器(image generator)中,它的內部也包含多個元件。
映像產生器主要包含兩個階段:
1. Image information creator
這個元件是Stable Diffusion的獨家秘方,相較於之前的模型,它的許多效能增益都是在這裡實現的。
此元件運行多個steps來產生映像訊息,其中steps也是Stable Diffusion介面和庫中的參數,通常預設為50或100。
影像資訊建立器完全在影像資訊空間(或潛空間)中運行,這一特性使得它比其他在像素空間工作的Diffusion模型運作得更快;從技術上來看,該元件由一個UNet神經網路和一個調度(scheduling)演算法組成。
擴散(diffusion)這個詞描述了在該元件內部運行期間發生的事情,即對資訊進行一步步地處理,並最終由下一個元件(圖像解碼器)生成高品質的圖像。
2. 圖像解碼器
#圖像解碼器根據從圖像資訊創建器中獲取的資訊畫出一幅畫,整個過程只運行一次即可生成最終的像素圖像。
可以看到,Stable Diffusion總共包含三個主要的元件,其中每個元件都有一個獨立的神經網路:
1)Clip Text用於文字編碼。
輸入:文字
輸出:77個token嵌入向量,其中每個向量包含768個維度
2)UNet Scheduler在訊息(潛)空間中逐步處理/擴散訊息。
輸入:文字嵌入和一個由雜訊組成的初始多維數組(結構化的數字列表,也叫張量tensor)。
輸出:一個經過處理的資訊陣列
#3)自編碼解碼器(Autoencoder Decoder),使用處理過的資訊矩陣繪製最終影像的解碼器。
輸入:處理過的資訊矩陣,維度為(4, 64, 64)
輸出:結果影像,各維度為( 3,512,512),即(紅/綠/藍,寬,高)
擴散是在下圖中粉紅色的圖像資訊創建器組件中發生的過程,過程中包含表徵輸入文字的token嵌入,和隨機的初始圖像資訊矩陣(也稱之為latents ),過程會還需要用到影像解碼器來繪製最終影像的資訊矩陣。
整個運行過程是step by step的,每一步都會增加更多的相關資訊。
為了更直觀地感受整個過程,可以中途查看隨機latents矩陣,並觀察它是如何轉化為視覺噪聲的,其中視覺檢查(visual inspection)是通過圖像解碼器進行的。
整個diffusion過程包含多個steps,其中每個step都是基於輸入的latents矩陣進行操作,並產生另一個latents矩陣以更貼合「輸入的文字」和從模型影像集中獲取的「視覺資訊」。
#將這些latents視覺化可以看到這些資訊是如何在每個step中相加的。
整個過程就是從無到有,看起來相當激動人心。
步驟2和4之間的過程轉變看起來特別有趣,就好像圖片的輪廓是從雜訊中出現的。
使用擴散模型產生影像的核心思路還是基於已存在的強大的電腦視覺模型,只要輸入足夠大的資料集,這些模型可以學習任意複雜的操作。
假設我們已經有了一張圖像,生成產生一些雜訊加入到圖像中,然後就可以將該圖像視為一個訓練樣例。
使用相同的操作可以產生大量訓練樣本來訓練影像產生模型中的核心元件。
上述範例展示了一些可選的雜訊量值,從原始影像(級別0,不含雜訊)到雜訊全部新增(級別4) ,從而可以輕鬆控制有多少雜訊添加到影像中。
所以我們可以將這個過程分散在幾十個steps中,對資料集中的每張影像都可以產生數十個訓練樣本。
基於上述資料集,我們就可以訓練出一個效能極佳的雜訊預測器,每個訓練step和其他模型的訓練相似。當以某一種確定的配置運作時,雜訊預測器就可以產生影像。
#經過訓練的雜訊預測器可以對一幅添加雜訊的影像進行去噪,也可以預測添加的噪音量。
由於取樣的雜訊是可預測的,所以如果從影像中減去噪聲,最後得到的影像就會更接近模型訓練得到的圖像。
所得到的影像並非是精確的原始影像,而是分佈(distribution),也就是世界的像素排列,例如天空通常是藍色的,人有兩隻眼睛,貓有尖耳朵等等,生成的具體圖像風格完全取決於訓練資料集。
不只Stable Diffusion透過去噪進行影像生成,DALL-E 2和Google的Imagen模型都是如此。
要注意的是,到目前為止描述的擴散過程還沒有使用任何文字資料來產生圖像。因此,如果我們部署這個模型的話,它能夠產生很好看的映像,但使用者沒有辦法控制生成的內容。
在接下來的部分中,將會對如何將條件文字合併到流程中進行描述,以便控制模型產生的圖像類型。
為了加速影像產生的過程,Stable Diffusion並沒有選擇在像素影像本身上運行擴散過程,而是選擇在在圖像的壓縮版本上運行,論文中也稱之為“Departure to Latent Space”。
整個壓縮過程,包括後續的解壓縮、繪製影像都是透過自編碼器完成的,將影像壓縮到潛空間中,然後僅使用解碼器使用壓縮後的訊息來重構。
前向擴散(forward diffusion)過程是在壓縮latents完成的,噪聲的切片(slices)是應用於latents上的噪聲,而非像素影像,所以雜訊預測器實際上是被訓練用來預測壓縮表示(潛空間)中的雜訊。
前向過程,即使用使用自編碼器中的編碼器來訓練雜訊預測器。一旦訓練完成後,就可以透過運行反向過程(自編碼器中的解碼器)來產生影像。
前向和後向過程如下所示,圖中還包含了一個conditioning元件,用來描述模型應該產生圖像的文字提示。
模型中的語言理解元件使用的是Transformer語言模型,可以將輸入的文字提示轉換為token嵌入向量。發布的Stable Diffusion模型使用 ClipText (基於 GPT 的模型) ,這篇文章中為了方便講解選擇使用 BERT模型。
Imagen論文中的實驗表明,相較於選擇更大的圖像生成元件,更大的語言模型可以帶來更多的圖像品質提升。
早期的Stable Diffusion模型使用的是OpenAI發布的經過預訓練的ClipText 模型,而在Stable Diffusion V2中已經轉向了最新發布的、更大的CLIP模型變體OpenClip.
CLIP是怎麼訓練的?
CLIP所需的資料為圖像及其標題,資料集中大約包含4億張圖像及描述。
資料集透過從網路上抓取的圖片以及對應的「alt」標籤文字來收集的。
CLIP 是影像編碼器和文字編碼器的組合,其訓練過程可簡化為拍攝影像和文字說明,使用兩個編碼器分別對資料進行編碼。
然後使用餘弦距離比較結果嵌入,剛開始訓練時,即使文字描述與圖像是相匹配的,它們之間的相似性肯定也是很低的。
隨著模型的不斷更新,在後續階段,編碼器對影像和文字編碼得到的嵌入會逐漸相似。
透過在整個資料集中重複這個過程,並使用大batch size的編碼器,最終能夠產生一個嵌入向量,其中狗的圖像和句子「一條狗的圖片」之間是相似的。
就像在 word2vec 中一樣,訓練過程也需要包含不匹配的圖片和說明的負樣本,模型需要給它們一個較低的相似度分數。
為了將文字條件融入成為圖像生成過程的一部分,必須調整雜訊預測器的輸入為文字。
所有的操作都是在潛空間上,包括編碼後的文字、輸入影像和預測雜訊。
為了更了解文字token在 Unet 中的使用方式,也需要先了解 Unet模型。
Unet 雜訊預測器中的層(無文字)
一個不使用文字的diffusion Unet,其輸入輸出如下所示:
#在模型內部,可以看到:
1. Unet模型中的層主要用於轉換latents;
2. 每層都是在先前層的輸出上進行操作;
#3. 某些輸出(透過殘差連接)將其饋送到網路後面的處理中
4. 將時間步轉換為時間步長嵌入向量,可以在層中使用。
Unet 雜訊預測器中的層(帶文字)
現在就需要將先前的系統改裝成有文字版本的。
主要的修改部分是增加對文字輸入(術語:text conditioning)的支持,即在ResNet塊之間添加一個注意力層。
要注意的是,ResNet區塊並沒有直接看到文字內容,而是透過注意力層將文字在latents中的表徵合併起來,然後下一個ResNet就可以在這過程中利用上文字資訊。
以上是Jay Alammar再發新作:超高品質圖解Stable Diffusion,看完徹底搞懂「影像生成」原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!