一、前言(可跳過)
hello,大家好我是 Tian-Feng,今天介紹一些stable diffusion的原理,內容通俗易懂,因為我平時也玩Ai繪畫嘛,所以就像寫一篇文章說明它的原理,這篇文章寫了真滴挺久的,如果對你有用的話,希望點個贊,謝謝。
stable diffusion作為Stability-AI開源圖像生成模型,其出現也是不遜于ChatGPT,其發(fā)展勢頭絲毫不差于midjourney,加上其眾多插件的加持,其上線也是無線拔高,當然,手法上也稍微比midjourney復雜點。
至于為什么開源,創(chuàng)始人:我這么做的原因是,我認為這是共同敘事(shared narrative)的一部分,有人需要公開展示發(fā)生了什么。再次強調,這應該默認就是開源的。因為價值不存在于任何專有模型或數據中,我們將構建可審計(auditable)的開源模型,即使其中包含有許可數據。?話不多說,開整。
二、stable diffusion
對于上面原論文的圖片可能小伙伴理解有困難,但是不打緊,我會把上面圖片分成一個個單獨的模塊進行解讀,最后組合在一起,相信你們一定可以理解圖片每一步干了什么事。
首先,我會畫一個簡化模型圖對標原圖,以方便理解。讓我們從訓練階段開始,可能你們發(fā)現少了VAEdecoder,這是因為我們訓練過程是在潛空間完成,decoder我們放在第二階段采樣階段說,我們所使用的stablediffusion webui畫圖通常是在采樣階段,至于訓練階段,目前我們大多數普通人是根本完成不了的,它所需要訓練時間應該可以用GPUyear來計量,(單V100的GPU要一年時間),如果你有100張卡,應該可以一個月完成。至于ChatGPT光電費上千萬美金,上萬GPU集群,感覺現在AI拼的就是算力。又扯遠了,come back。
1.clip
我們先從提示詞開始吧,我們輸入一段提示詞a black and white striped cat(一條黑白條紋的貓),clip會把文本對應一個詞表,每個單詞標點符號都有相對應的一個數字,我們把每個單詞叫做一個token,之前stablediffusion輸入有限制只能75個單詞(現在沒了),也就是75個token,看上面你可能發(fā)現6個單詞怎么對應8個token,這是因為還包含了起始token和結束token,每個數字又對應這一個768維的向量,你可以看作每個單詞的身份證,而且意思非常相近的單詞對應的768維向量也基本一致。經過clip我們得到了一個(8,768)的對應圖像的文本向量。
stable diffusion所使用的是openAi的clip的預訓練模型,就是別人訓練好的拿來用就行,那clip是怎么訓練出來的呢?他是怎么把圖片和文字信息對應呢?(下面擴展可看可跳過,不影響理解,只需要知道它是用來把提示詞轉成對應生成圖像的文本向量即可)。
CLIP需要的數據為圖像及其標題,數據集中大約包含4億張圖像及描述。應該是直接爬蟲得來,圖像信息直接作為標簽,訓練過程如下:
CLIP 是圖像編碼器和文本編碼器的組合,使用兩個編碼器對數據分別進行編碼。然后使用余弦距離比較結果嵌入,剛開始訓練時,即使文本描述與圖像是相匹配的,它們之間的相似性肯定也是很低的。
隨著模型的不斷更新,在后續(xù)階段,編碼器對圖像和文本編碼得到的嵌入會逐漸相似。在整個數據集中重復該過程,并使用大batch size的編碼器,最終能夠生成一個嵌入向量,其中狗的圖像和句子「一條狗的圖片」之間是相似的。
給一些提示文本,然后每種提示算相似度,找到概率最高的即可。
2.diffusion model
上面我們已經得到了unet的一個輸入了,我們現在還需要一個噪聲圖像的輸入,假如我們輸入的是一張3x512x512的貓咪圖像,我們不是直接對貓咪圖像進行處理,而是經過VAE encoder把512x512圖像從pixel space(像素空間)壓縮至latent space(潛空間)4x64x64進行處理,數據量小了接近64倍。
潛在空間簡單的說是對壓縮數據的表示。所謂壓縮指的是用比原始表示更小的數位來編碼信息的過程。維度降低會丟失一部分信息,然而在某些情況下,降維不是件壞事。通過降維我們可以過濾掉一些不太重要的信息你,只保留最重要的信息。
得到潛空間向量后,現在來到擴散模型,為什么圖像加噪后能夠還原,秘密都在公式里,這里我以DDPM論文作為理論講解,論文,當然還有改進版本DDIM等等,感興趣自己看。
forward diffusion (前向擴散)
-
首先是forward diffusion (前向擴散),也就是加噪過程,最后就快變成了個純噪聲
-
每一個時刻都要添加高斯噪聲,后一時刻都是由前一刻是增加噪聲得到
那么是否我們每一次加噪聲都要從前一步得到呢,我們能不能想要第幾步加噪圖像就能得到呢?答案是YES,作用是:我們訓練過程中對圖像加噪是隨機的,假如 我們隨機到100步噪聲,(假設設置時間步數200步),如果要從第一步加噪,得到第二步,循環(huán)往復,太費時間了,其實這些加的噪聲有規(guī)律的,我們現在的目標就是只要有原始圖像X0,就可以得到任意時刻圖像加噪聲的圖像,而不必一步一步得到想要的噪聲圖像。
我來對上述作講解,其實該標住的我都標的很清楚了,
第一,αt范圍0.9999-0.998,
第二,圖像加噪是符合高斯分布的,也就是在潛空間向量加的噪聲是符合均值為0,方差為1的,將Xt-1帶入Xt中,為什么兩項可以合并,因為Z1Z2都是符合高斯分布,那么他們相加Z2'也符合,并且它們的方差和為新的方差,所有把他們各自的方差求和,(那個帶根號的是標準差),如果你無法理解,可以把它當做一個定理。在多說一句,對Z-->a+bZ,那么Z的高斯分別也從(0,σ)-->(a,bσ),現在我們得到了Xt跟Xt-2的關系
第三,如果你再把Xt-2帶入,得到與Xt-3的關系,并且找到規(guī)律,就是α的累乘,最后得到Xt與X0的關系式,現在我們可以根據這個式子直接得到任意時刻的噪聲圖像。
第四,因為圖像初始化噪聲是隨機的,假設你設置的時間步數(timesteps)為200,就是把0.9999-0.998區(qū)間等分為200份,代表每個時刻的α值,根據Xt和X0的公式,因為α累乘(越?。?,可以看出越往后,噪聲加的越快,大概1-0.13的區(qū)間,0時刻為1,這時Xt代表圖像本身,200時刻代表圖像大概α為0.13噪音占據了0.87,因為是累乘所以噪聲越加越大,并不是一個平均的過程。
第五,補充一句,重參數化技巧(Reparameterization Trick)
如果X(u,σ2),那么X可以寫成X=μ十σZ的形式,其中Z~Ν(0,1)。這就是重參數化技巧。
重參數化技巧,就是從一個分布中進行采樣,而該分布是帶有參數的,如果直接進行采樣(采樣動作是離散的,其不可微),是沒有梯度信息的,那么在BP反向傳播的時候就不會對參數梯度進行更新。重參數化技巧可以保證我們從進行采樣,同時又能保留梯度信息。
逆向擴散(reverse diffusion)
-
前向擴散完畢,接下來是逆向擴散(reverse diffusion),這個可能比上面那個難點,如何根據一個噪聲圖像一步步得到原圖呢,這才是關鍵,
-
逆向開始,我們目標是Xt噪聲圖像得到無噪聲的X0,先從Xt求Xt-1開始,這里我們先假設X0是已知(先忽略為什么假設已知),后面會替換它,至于怎么替換,前向擴散不是已知Xt和X0的關系嗎,現在我們已知的是Xt,反過來用Xt來表示X0,但是還有一個Z噪聲是未知的,這個時候就要Unet上場了,它需要把噪聲預測出來。
-
這里借助貝葉斯公式(就是條件概率),我們借助貝葉斯公式結果,以前寫過一個文檔 (https://tianfeng.space/279.html)
就是已知Xt求Xt-1,反向我們不知道怎么求,但是求正向,如果我們已知X0那么這幾項我們都可以求出來。
開始解讀,既然這三項都符合高斯分別,那帶入高斯分布(也可以叫正態(tài)分布),它們相乘為什么等于相加呢,因為e2 * e3 =e2+3,這個能理解吧(屬于exp,就是e次方),好,現在我們得到了一個整體式子,接下來繼續(xù)化簡:
首先我們把平方展開,未知數現在只有Xt-1,配成AX2+BX+C格式,不要忘了,即使相加也是符合高斯分布,現在我們把原高斯分別公式配成一樣的格式,紅色就是方差的倒數,把藍色乘方差除2就得到了均值μ(下面顯示是化簡的結果,如果你有興趣自己,自己化簡),回歸X0,之前說X0假設已知,現在轉成Xt(已知)表示,代入μ,現在未知數只剩下Zt,
-
Zt其實就是我們要估計的每個時刻的噪聲
-
這里我們使用Unet模型預測
-
模型的輸入參數有三個,分別是當前時刻的分布Xt和時刻t,還有之前的文本向量,然后輸出預測的噪聲,這就是整個過程了,
-
上面的Algorithm 1是訓練過程,
其中第二步表示取數據,一般來說都是一類貓,狗什么的,或者一類風格的圖片,不能亂七八糟什么圖片都來,那模型學不了。
第三步是說每個圖片隨機賦予一個時刻的噪聲(上面說過),
第四步,噪聲符合高斯分布,
第五步,真實的噪聲和預測的噪聲算損失(DDPM輸入沒有文本向量,所有沒有寫,你就理解為多加了一個輸入),更新參數。直到訓練的輸出的噪聲和真實噪聲相差很小,Unet模型訓練完畢。
-
下面我們來到Algorithm2采樣過程
-
不就是說Xt符合高斯分布嘛
-
執(zhí)行T次,依次求Xt-1到X0,不是T個時刻嘛
-
Xt-1不就是我們逆向擴散推出的公式,Xt-1=μ+σZ,均值和方差都是已知的,唯一的未知噪聲Z被Unet模型預測出來,εθ這個是指已經訓練好的Unet,
采樣圖
-
為了方便理解,我分別畫出文生圖和圖生圖,如果使用stable diffusion webui畫圖的人一定覺得很熟悉,如果是文生圖就是直接初始化一個噪聲,進行采樣,
-
圖生圖則是在你原有的基礎上加噪聲,噪聲權重自己控制,webui界面是不是有個重繪幅度,就是這個,
-
迭代次數就是我們webui界面的采樣步數,
-
隨機種子seed就是我們初始隨機得到的一個噪聲圖,所以如果想要復刻得到一樣的圖,seed要保持一致
階段小結
我們現在再來看這張圖,除了Unet我沒講(下面會單獨介紹),是不是簡單多了,最左邊不就是像素空間的編碼器解碼器,最右邊就是clip把文本變成文本向量,中間上面的就是加噪,下面就是Unet預測噪聲,然后不停的采樣解碼得到輸出圖像。這是原論文采樣圖,沒畫訓練過程。
3.Unet model
unet模型相信小伙伴們都或多或少知道,就是多尺度特征融合,像FPN圖像金字塔,PAN,很多都是差不多的思想,一般使用resnet作為backbone(下采樣),充當編碼器,這樣我們就得到多個尺度的特征圖,然后在上采樣過程中,上采樣拼接(之前下采樣得到的特征圖),上采樣拼接,這是一個普通的Unet。
那stablediffusion的Unet有什么不一樣呢,這里找到一張圖,佩服這位小姐姐有耐心,借一下她的圖。
我解釋一下和ResBlock模塊和SpatialTransformer模塊,輸入為timestep_embedding,context 以及input就是三個輸入分別是時間步數,文本向量,加噪圖像,時間步數你可以理解為transformer里的位置編碼,在自然語言處理中用來告訴模型一句話每個字的位置信息,不同的位置可能意思大不相同,而在這,加入時間步數信息,可以理解為告訴模型加入第幾步噪聲的時刻信息(當然這是我的理解)。
timestep_embedding采用正余弦編碼
ResBlock模塊輸入為時間編碼和卷積后圖像輸出,把它們相加,這就是它的作用,具體細節(jié)不說了,就是卷積,全連接,這些很簡單。
SpatialTransformer模塊輸入為文本向量和上一步ResBlock的輸出,
里面主要講一下cross attention,其他都是一些維度的變換,卷積操作和各種歸一化Group Norm,Layer norm,
利用cross attention將latent space(潛空間)的特征與另一模態(tài)序列(文本向量)的特征融合,并添加到diffusion model的逆向過程,通過Unet逆向預測每一步需要減少的噪音,通過GT噪音與預測噪音的損失函數計算梯度。
看右下角圖,可以知道Q為latent space(潛空間)的特征,KV則都是文本向量連兩個全連接得到,剩下就是正常的transformer操作了,QK相乘后,softmax得到一個分值,然后乘V,變換維度輸出,你可以把transformer當做一個特征提取器,它可以把重要信息給我們顯現出來(僅幫助理解),差不多就是這樣了,之后操作都差不多,最后輸出預測的噪聲。
看完是不是感覺很牛逼?也想學學當下較為火熱的AIGC?這兩天良心哥利用了點時間整理了第三期Stable Diffusion輔助設計教程,希望給大家的AI學習帶來一些幫助
AI繪畫所有方向的學習路線思維導圖
這里為大家提供了總的路線圖。它的用處就在于,你可以按照上面的知識點去找對應的學習資源,保證自己學得較為全面。如果下面這個學習路線能幫助大家將AI利用到自身工作上去,那么我的使命也就完成了:
??stable diffusion新手0基礎入門PDF??
??AI繪畫必備工具??
溫馨提示:篇幅有限,已打包文件夾,獲取方式在:文末
??AI繪畫基礎+速成+進階使用教程??
觀看零基礎學習視頻,看視頻學習是最快捷也是最有效果的方式,跟著視頻中老師的思路,從基礎到深入,還是很容易入門的。
??12000+AI關鍵詞大合集??
這份完整版的AI繪畫資料我已經打包好,資料在此網址里:CSDN大禮包:《全套AI繪畫基礎學習資源包》免費分享 (qq.com)文章來源:http://www.zghlxwxcb.cn/news/detail-860863.html
)文章來源地址http://www.zghlxwxcb.cn/news/detail-860863.html
到了這里,關于stable diffusion原理解讀通俗易懂,史詩級萬字爆肝長文!的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!