Diffusion Models
圖中: x 0 x_0 x0?為圖像, z z z為采樣自正態(tài)分布的噪音
擴(kuò)散模型**是受非平衡熱力學(xué)的啟發(fā)。它們定義一個(gè)擴(kuò)散步驟的馬爾可夫鏈,逐漸向數(shù)據(jù)添加隨機(jī)噪聲,然后學(xué)習(xí)逆擴(kuò)散過程,從噪聲中構(gòu)建所需的數(shù)據(jù)樣本。與VAE或流動(dòng)模型不同,擴(kuò)散模型是用固定的程序?qū)W習(xí)的,而且隱變量具有高維度。
訓(xùn)練階段,是在圖片中添加噪聲,給網(wǎng)絡(luò)輸入這一張?zhí)砑釉肼暤膱D片,網(wǎng)絡(luò)需要預(yù)測(cè)的則是添加的噪聲。
使用階段,由隨機(jī)生成的噪聲,使用網(wǎng)絡(luò)預(yù)測(cè)添加了什么噪聲,然后逐步去除噪聲,直到還原。
、
1、擴(kuò)散過程
- 擴(kuò)散的過程,是不斷地逐步向圖片中添加噪聲,直到圖像完全變?yōu)榧冊(cè)肼暎?/li>
- 添加的噪聲為高斯噪聲,而后一時(shí)刻都是由前一時(shí)刻的圖像增加噪聲得到的。
添加噪聲的過程:
這里定義了兩個(gè)參數(shù) α t \alpha_t αt?、 β t \beta_t βt?;( t t t的范圍為0~ T T T之間的整數(shù), β t \beta_t βt? 從 β 1 \beta_1 β1?變化到 β T \beta_T βT?,是逐漸變大的,論文中是從0.0001等量的增加 T T T次,直到0.002 )
而 α t \alpha_t αt?與 β t \beta_t βt?的關(guān)系為:
α t = 1 ? β t \alpha_t = 1- \beta_t αt?=1?βt? (1)
T T T表示的是,由圖片通過逐步添加噪聲直至完全變?yōu)榧冊(cè)肼暤倪^程所需要經(jīng)歷的次數(shù),也就是圖片需要總計(jì)需要添加噪聲的步數(shù)。而 t t t則代表的是 T T T中具體的某一步。
則給圖像添加噪聲的過程的表達(dá)式可以寫為:
x t = α t x t ? 1 + 1 ? α t z t x_t=\sqrt{\alpha_t}x_{t-1}+\sqrt{1-\alpha_t}z_t xt?=αt??xt?1?+1?αt??zt? (2)
x t x_t xt?表示的是第 t t t擴(kuò)散步時(shí),添加噪聲后的圖片,而 x t ? 1 x_{t-1} xt?1?是第 t ? 1 t-1 t?1時(shí)刻所獲得的圖片; z t z_t zt?表示的是 t t t時(shí)刻所添加的噪聲,該噪聲采樣自標(biāo)準(zhǔn)正態(tài)分布 N ( 0 , 1 ) N(0,1) N(0,1)
那么可以依照公式(2)依次從原始圖像 x 0 x_0 x0?逐步添加噪聲,擴(kuò)散至 x T x_T xT?:
x 1 = α 1 x 0 + 1 ? α 1 z 1 x_1=\sqrt{\alpha_1}x_{0}+\sqrt{1-\alpha_1}z_1 x1?=α1??x0?+1?α1??z1?
x 2 = α 2 x 1 + 1 ? α 2 z 2 x_2=\sqrt{\alpha_2}x_{1}+\sqrt{1-\alpha_2}z_2 x2?=α2??x1?+1?α2??z2?
……
x t = α t x t ? 1 + 1 ? α t z t x_t=\sqrt{\alpha_t}x_{t-1}+\sqrt{1-\alpha_t}z_t xt?=αt??xt?1?+1?αt??zt?
……
x T = α T x T ? 1 + 1 ? α T z T x_T=\sqrt{\alpha_T}x_{T-1}+\sqrt{1-\alpha_T}z_T xT?=αT??xT?1?+1?αT??zT?
由此可以看出 β t \beta_t βt?逐漸增加,相應(yīng)的 α t \alpha_t αt?逐漸減小, 1 ? α t 1-\alpha_t 1?αt?則是逐漸增大的,也就是說,添加的噪聲是逐步增加的,而原始圖像的比例是逐漸減小的,并且噪聲添加的程度是逐次擴(kuò)大的。
但對(duì)網(wǎng)絡(luò)的訓(xùn)練,數(shù)據(jù)是需要隨機(jī)采樣的,每次采樣到 t t t時(shí)刻的時(shí)候,都從 x 0 x_0 x0?開始遞推則太過于繁瑣。
所以需要一次就計(jì)算出來:
將式 : x t ? 1 = α t ? 1 x t ? 2 + 1 ? α t ? 1 z t ? 1 x_{t-1}=\sqrt{\alpha_{t-1}}x_{t-2}+\sqrt{1-\alpha_{t-1}}z_{t-1} xt?1?=αt?1??xt?2?+1?αt?1??zt?1?帶入(2)式中,可得
x t = α t ( α t ? 1 x t ? 2 + 1 ? α t ? 1 z t ? 1 ) + 1 ? α t z t x_t=\sqrt{\alpha_t}(\sqrt{\alpha_{t-1}}x_{t-2}+\sqrt{1-\alpha_{t-1}}z_{t-1})+\sqrt{1-\alpha_t}z_t xt?=αt??(αt?1??xt?2?+1?αt?1??zt?1?)+1?αt??zt?
式子展開為:
x t = α t α t ? 1 x t ? 2 + α t 1 ? α t ? 1 z t ? 1 + 1 ? α t z t x_t=\sqrt{\alpha_t}\sqrt{\alpha_{t-1}}x_{t-2}+\sqrt{\alpha_t}\sqrt{1-\alpha_{t-1}}z_{t-1}+\sqrt{1-\alpha_t}z_t xt?=αt??αt?1??xt?2?+αt??1?αt?1??zt?1?+1?αt??zt?
= α t α t ? 1 x t ? 2 + ( α t ( 1 ? α t ? 1 ) z t ? 1 + 1 ? α t z t ) =\sqrt{\alpha_t}\sqrt{\alpha_{t-1}}x_{t-2}+(\sqrt{\alpha_t (1- \alpha_{t-1})}z_{t-1}+\sqrt{1-\alpha_t}z_t) =αt??αt?1??xt?2?+(αt?(1?αt?1?)?zt?1?+1?αt??zt?)
其中每次加入的噪聲—— z 1 , z 2 , . . . , z t ? 1 , z t , . . . z T z_1,z_2,...,z_{t-1},z_t,...z_T z1?,z2?,...,zt?1?,zt?,...zT?——都是服從正態(tài)分布 N ( 0 , 1 ) N(0,1) N(0,1)
所以可以將
z t ? 1 z_{t-1} zt?1?和 z t z_t zt?之間的系數(shù)合并在一起,因?yàn)檎植汲艘砸粋€(gè)系數(shù),只改變方差,而 N ( 0 , σ 1 2 ) + N ( 0 , σ 2 2 ) ~ N ( 0 , σ 1 2 + σ 2 2 ) N(0,\sigma_1^2)+N(0,\sigma_2^2) \sim N(0,\sigma_1^2+\sigma_2^2 ) N(0,σ12?)+N(0,σ22?)~N(0,σ12?+σ22?)
所以
x t = α t α t ? 1 x t ? 2 + ( α t ( 1 ? α t ? 1 ) z t ? 1 + 1 ? α t z t ) x_t=\sqrt{\alpha_t}\sqrt{\alpha_{t-1}}x_{t-2}+(\sqrt{\alpha_t (1- \alpha_{t-1})}z_{t-1}+\sqrt{1-\alpha_t}z_t) xt?=αt??αt?1??xt?2?+(αt?(1?αt?1?)?zt?1?+1?αt??zt?)
= α t α t ? 1 x t ? 2 + ( a t ( 1 ? a t ? 1 ) + 1 ? a t ) z =\sqrt{\alpha_t}\sqrt{\alpha_{t-1}}x_{t-2}+(\sqrt{a_t(1-a_{t-1})+1-a_t})z =αt??αt?1??xt?2?+(at?(1?at?1?)+1?at??)z
= α t α t ? 1 x t ? 2 + ( 1 ? a t a t ? 1 ) z =\sqrt{\alpha_t\alpha_{t-1}}x_{t-2}+(\sqrt{1-a_t a_{t-1}})z =αt?αt?1??xt?2?+(1?at?at?1??)z
再將 x t ? 2 = α t ? 2 x t ? 3 + 1 ? α t ? 2 z t ? 2 x_{t-2}=\sqrt{\alpha_{t-2}}x_{t-3}+\sqrt{1-\alpha_{t-2}}z_{t-2} xt?2?=αt?2??xt?3?+1?αt?2??zt?2?帶入上式,循環(huán)往復(fù),將 x 1 x_1 x1?帶入,可得
x t = α t α t ? 1 . . . α 2 α 1 x t ? 1 + ( 1 ? α t α t ? 1 . . . α 2 α 1 ) z x_t=\sqrt{\alpha_t\alpha_{t-1}...\alpha_2 \alpha_1}x_{t-1}+(\sqrt{1-\alpha_t\alpha_{t-1}...\alpha_2 \alpha_1})z xt?=αt?αt?1?...α2?α1??xt?1?+(1?αt?αt?1?...α2?α1??)z
= α t  ̄ x 0 + ( 1 ? a t  ̄ ) z =\sqrt{\overline{\alpha_t}}x_{0}+(\sqrt{1-\overline{a_t}})z =αt???x0?+(1?at???)z (3)
其中 α t  ̄ \overline{\alpha_t} αt??表示從 α 1 \alpha_1 α1?到 α t \alpha_t αt?的連乘
、
2、訓(xùn)練過程
因此,擴(kuò)散模型的訓(xùn)練過程如下:
- 從數(shù)據(jù)集中隨機(jī)抽選一張圖片,
- 隨機(jī)從1~T中抽取一個(gè)擴(kuò)散步,
- 按照式(3)計(jì)算得到 x t x_t xt?,
- 輸入網(wǎng)絡(luò),得到輸出,輸出同添加的噪聲做損失,更新梯度,
- 反復(fù)訓(xùn)練,直至滿意。
詳細(xì)訓(xùn)練過程的代碼過程如下:
for i, (x_0) in enumerate(tqdm_data_loader): # 由數(shù)據(jù)加載器加載數(shù)據(jù),
x_0 = x_0.to(device) # 將數(shù)據(jù)加載至相應(yīng)的運(yùn)行設(shè)備(device)
t = torch.randint(1, T, size=(x_0.shape[0],), device=device) # 對(duì)每一張圖片隨機(jī)在1~T的擴(kuò)散步中進(jìn)行采樣
sqrt_alpha_t_bar = torch.gather(sqrt_alphas_bar, dim=0, index=t).reshape(-1, 1, 1, 1) # 取得不同t下的 根號(hào)下alpha_t的連乘
"""取得不同t下的 根號(hào)下的一減alpha_t的連乘"""
sqrt_one_minus_alpha_t_bar = torch.gather(sqrt_one_minus_alphas_bar, dim=0, index=t).reshape(-1, 1, 1, 1)
noise = torch.randn_like(x_0).to(device) # 從標(biāo)準(zhǔn)正態(tài)分布中采樣得到z
x_t = sqrt_alpha_t_bar * x_0 + sqrt_one_minus_alpha_t_bar * noise # 計(jì)算x_t
out = net_model(x_t, t) # 將x_t輸入模型,得到輸出
loss = loss_function(out, noise) # 將模型的輸出,同添加的噪聲做損失
optimizer.zero_grad() # 優(yōu)化器的梯度清零
loss.backward() # 由損失反向求導(dǎo)
optimizer.step() # 優(yōu)化器更新參數(shù)
、
3、正向使用過程
使用過程是從 x T x_T xT?一步一步取出噪聲,推測(cè)出 x 0 x_0 x0?
也就是說,需要在已知 x T x_T xT?的情況下,先反推 x t ? 1 x_{t-1} xt?1?,然后推 x t ? 2 x_{t-2} xt?2?……最終推測(cè)得到 x 0 x_0 x0?
根據(jù)貝葉斯公式推導(dǎo)為:
x
t
?
1
=
1
α
t
(
x
t
?
1
?
α
t
1
?
α
t
 ̄
M
(
x
t
,
t
)
)
+
β
t
z
x_{t-1}=\frac{1}{\sqrt{\alpha_t}}(x_t-\frac{1-\alpha_t}{\sqrt{1-\overline{\alpha_t}}}M(x_t, t))+\sqrt{\beta_t}z
xt?1?=αt??1?(xt??1?αt???1?αt??M(xt?,t))+βt??z
則整個(gè)算法為:
- x T x_T xT?隨機(jī)采樣自標(biāo)準(zhǔn)正態(tài)分布;
- 從T到1開始循環(huán),
- 按照上述公式計(jì)算 x t ? 1 x_{t-1} xt?1?,依次往復(fù),其中 M ( x t , t ) M(x_t, t) M(xt?,t)為網(wǎng)絡(luò)模型,輸入的是 x t x_t xt?步的結(jié)果和第t步,因?yàn)槟P鸵獙?duì)每一步的位置進(jìn)行編碼, z z z取樣至標(biāo)準(zhǔn)正態(tài)分布,在t為最后一步的時(shí)候,z取零
具體代碼如下:
for t_step in reversed(range(T)): # 從T開始向零迭代
t = t_step
t = torch.tensor(t).to(device)
z = torch.randn_like(x_t,device=device) if t_step > 0 else 0 # 如果t大于零,則采樣自標(biāo)準(zhǔn)正態(tài)分布,否則為零
"""按照公式計(jì)算x_{t-1}"""
x_t_minus_one = torch.sqrt(1/alphas[t])*(x_t-(1-alphas[t])*model(x_t, t.reshape(1,))/torch.sqrt(1-alphas_bar[t]))+torch.sqrt(betas[t])*z
x_t = x_t_minus_one
、
4、結(jié)果
因?yàn)樵O(shè)備有限,訓(xùn)練網(wǎng)紅人臉數(shù)據(jù),測(cè)試時(shí)網(wǎng)絡(luò)生成的結(jié)果如下:這是在一張3080ti上訓(xùn)練得到的結(jié)果
、
5、網(wǎng)絡(luò)模型
模型使用UNet,并具有第t擴(kuò)散步的位置編碼信息。
、
6、其他
github:https://github.com/HibikiJie/Diffusion-Models文章來源:http://www.zghlxwxcb.cn/news/detail-401105.html
權(quán)重
鏈接:https://pan.baidu.com/s/19PuZr6duixJaSU1kvmn8Vg
碼:yhR9文章來源地址http://www.zghlxwxcb.cn/news/detail-401105.html
到了這里,關(guān)于Diffusion Models擴(kuò)散模型簡單講解與簡單實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!