https://www.crosslabs.org//blog/diffusion-with-offset-noise
帶有偏移噪聲的擴散
針對修改后的噪聲進行微調,使得穩定擴散能夠輕松生成非常暗或非常亮的圖像。
作者:尼古拉斯·古藤伯格
|
2023年1月30日
馬里奧兄弟使用穩定擴散挖掘隧道。左圖顯示了未使用偏移噪聲的原始結果,右圖使用偏移噪聲顯示了更豐富的黑色調。
穩定擴散在使用偏移噪聲前(左)和使用偏移噪聲后(右)
去噪擴散概率模型(Denoising Diffusion Probabilistic Models)是一種相對較新的生成神經網絡模型,可以從從數據中學習到的高維概率分布中生成樣本。其他解決同類問題的方法包括生成對抗網絡(Generative Adversarial Networks)、歸一化流(Normalizing Flows)以及各種形式的自回歸模型,這些模型一次或分批對維度進行采樣。此類模型的主要應用之一是在圖像合成中,擴散模型在圖像質量方面最近競爭力很強,特別是在生成全局連貫的圖像構圖方面。穩定擴散(Stable Diffusion)是一個預訓練的、公開可用的模型,能夠使用這種技術生成一些驚人的結果。然而,它有一個有趣的限制,似乎大多沒有被注意到。如果你試圖讓它生成特別暗或特別亮的圖像,它幾乎總是生成平均值相對接近0.5的圖像(全黑圖像為0,全白圖像為1)。例如:
左上:暴雨中的黑暗小巷(0.301);右上:白色背景上的單色線條藝術標志(0.709);左下:陽光明媚的雪坡(0.641);右下:僅有火把照亮的廣場(0.452)
大多數情況下,這些圖像仍然是合理的。但是,這種平均值趨近于0.5的軟約束可能導致圖像顯得淡化、亮霧區域平衡其他暗區域、高頻紋理(在標志中)而不是空白區域、灰色背景而不是白色或黑色等。雖然有些可以通過手動后期處理來修正或調整,但這里也存在一個更大的潛在限制,即場景的整體色調可能與表現和構圖的其他方面相關,這樣擴散模型就無法像其他方法那樣自由探索這些方面。但為什么會這樣呢?我是想象中的效果還是這些結果是“正確的”?這是訓練數據的問題、架構的問題還是擴散模型本身的問題?(事實證明是最后一個)。
不過,首先,為了確保我沒有想象出這些效果,我嘗試針對一張全黑圖像對穩定擴散進行微調。通常,對穩定擴散(SD)進行微調效果很好——有一種稱為Dreambooth的技術可以教SD新的特定概念,比如特定的人的臉或特定的貓,幾十張圖像和幾千次梯度更新就足夠讓模型學會特定對象的樣子。將其擴展到一萬步,它甚至可以開始記住特定的圖像。
但當我針對這張全黑圖像進行了3000步微調后,對于“全黑圖像”的生成結果仍然如下:
使用提示:“全黑圖像”
所以看來不僅SD開箱即用時無法生成過于暗或亮的圖像,而且它甚至無法學會這樣做。除非對其進行一些修改。
要理解發生了什么,幫助很大的是研究一下擴散模型正在學習反轉的內容。通常,擴散模型被公式化為特定前向隨機過程的逆過程——重復添加少量“獨立同分布”(iid)的高斯噪聲。也就是說,每個像素在潛在空間中在每一步都接收自己的隨機樣本。擴散模型學習在進行了一些步后,從圖像中找到返回原始圖像的方向。給定這個可以“向真實圖像倒退”的模型,你從純噪聲開始,反轉噪聲過程以得到新的圖像。
問題在于,你在前向過程中永遠不會完全擦除原始圖像,因此,從純噪聲開始的逆過程模型并不能完全回到圖像的真實分布。相反,那些噪聲最后破壞的特征在逆過程中變化最小——這些特征繼承自用于開始過程的潛在噪聲樣本。乍一看可能不明顯,但如果你研究前向過程如何破壞圖像,長波長特征需要更長時間才能被噪聲破壞:
這就是為什么使用相同的潛在噪聲種子但不同提示往往會生成在整體構圖上相關但在個體紋理或小尺度圖案上不同的圖像。擴散過程不知道如何改變這些長波長特征。而最長的波長特征是整個圖像的平均值,也是獨立樣本之間變化最小的特征。這個問題在目標對象的維度越高時越嚴重,因為獨立噪聲樣本集合的標準差與1/N成比例。因此,如果你生成一個4維向量,這可能不是大問題——你只需要兩倍的樣本來獲得最低頻率分量與最高頻率分量。但在512x512分辨率的穩定擴散中,你生成的是一個3 x 64^2 = 12288維的對象。所以最長波長變化比最短波長慢大約100倍,意味著你需要考慮成百上千步才能捕捉到,而默認值大約是50(對于一些復雜的采樣器,甚至低至20)。
似乎增加采樣步數確實可以幫助SD生成更極端的圖像,但我們可以做得更好,并提供一個即插即用的解決方案。訣竅在于我們教擴散模型逆轉的噪聲結構。因為我們使用的是iid樣本,我們有這個1/N效應。但如果我們使用的噪聲看起來像每個像素的iid樣本加上整個圖像相同的單個iid樣本呢?用代碼術語來說,目前的訓練循環使用的噪聲如下:noise = torch.randn_like(latents)但我可以使用這樣的噪聲:noise = torch.randn_like(latents) + 0.1 * torch.randn(latents.shape[0], latents.shape[1], 1, 1)這將使模型學習自由改變零頻分量,因為該分量現在比基礎分布快隨機化約10倍(選擇0.1在我的有限數據和訓練時間內效果很好——如果我設得太大,它會傾向于主導模型的現有行為,但如果設得太小,我不會看到改善)。
用這樣的噪聲進行約一千步的微調,僅需40張手工標注的圖像,就足以顯著改變穩定擴散的行為,而不會讓它在以前能夠生成的東西上變得更糟。以下是文章上方四個提示的對比結果:
右上:暴雨中的黑暗小巷(0.032);左上:白色背景上的單色線條藝術標志(0.974);左下:陽光明媚的雪坡(0.858);右下:僅有火把照亮的廣場(0.031)
星空在使用偏移噪聲前后
超級英雄在黑暗小巷中與植物怪物戰斗前后
結論
有許多論文討論了改變去噪擴散模型的噪聲調度,以及使用不同于高斯分布的噪聲,甚至完全去除噪聲而使用其他破壞操作如模糊或遮罩。然而,大多數關注點似乎是加速推理過程——能夠使用更少的步數。似乎沒有太多關注關于噪聲(或圖像破壞操作)的設計決策如何限制可以輕松合成的圖像類型。然而,這對于這些模型的美學和藝術用途來說非常相關。對于深入定制這些模型并進行自己的微調的個別藝術家來說,針對某個項目調整使用這種偏移噪聲并不難。你可以使用我們的檢查點文件(在訪問此文件前請閱讀最后的注意事項)。但是,用少量圖像進行微調,結果永遠不會像大項目可以實現的那樣普遍或好。
因此,我想以一個請求結束,向那些參與訓練這些大型模型的人:請在下次進行大規模訓練時,在訓練過程中加入一點這樣的偏移噪聲。它應該顯著增加模型的表現范圍,允許在生成標志、剪切圖、自然明亮和黑暗的場景、強色彩照明的場景等方面得到更好的結果。這是一個非常簡單的技巧!