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