「生成」一張圖到底是什麼意思
你到目前為止見過的大多數視覺系統都是「辨識器」。你給它一張圖,它回給你一個標籤:「貓」、「狗」、「停車再開標誌」。箭頭只朝一個方向走——圖片進去、答案出來。而「生成模型」把這個箭頭反過來跑。你幾乎什麼都不給它——只給一把隨機數字——它卻回給你一張全新的、看起來像是真實世界裡會出現的圖片。沒有人拍過這張圖;是模型「想像」出來的。
機器怎麼可能想像出它從沒見過的東西?想想一位技藝高超的偽畫師。他不是把一幅畫背起來、一筆一筆照抄——那只是影印。他真正做的,是研究上千件作品,直到把那股「風格」吸收進骨子裡:這位畫家如何沾筆、如何調色、如何安排光影。把所有畫作背後的規律都吸收之後,偽畫師可以坐在一張空白畫布前,畫出一幅原作者從未畫過、卻又一看就知道是「他的味道」的全新作品。生成視覺模型就是這位偽畫師,只是規模放大到了數百萬張照片。
左:一張影像流入分類器,產生「貓」這個字。右:一團隨機雜訊流入生成器,產生一張全新的貓影像。
這裡有一個貫穿整個學習軌的核心心智模型,請一路帶著它。所有「看起來可信的真實世界影像」構成一個機率分布:人臉、貓、海灘的照片機率很高;一整片隨機雪花的螢幕則機率低到不行。所謂「生成」一張圖,其實就是從這個分布中抽出一個樣本——伸手進「所有合理圖片」構成的空間,撈一張出來。模型的全部工作,就是把這個分布的形狀學得夠好,好到能從中抽樣。我們接下來要研究的這一族模型,自 2021 年起就主宰了影像生成,它就是 擴散模型。
核心技巧:先摧毀,再重建
要從「所有自然影像的分布」中抽樣,聽起來難到不可能——那個空間大到天文數字,又糾纏不清。擴散模型用一個美得驚人的簡單想法繞開了這個難題。如果這整個學習軌你只記得一件事,請記住這件:把一個難題拆成許多個微小的簡單題——做法是先學會摧毀,再學會重建。
先談「摧毀」這一半——也就是前向擴散過程。從一張乾淨的照片開始。在上面灑一點點隨機雜訊,讓它變得稍微粗糙一點。再做一次。再一次——重複數百次甚至上千次。每一步單看幾乎不改變圖片,但顆粒會一點一滴累積起來。步數夠多之後,照片就消失了:剩下的東西,和沒調好的電視那片雪花靜電毫無二致——純粹的隨機雜訊,原圖一絲痕跡都不剩。
接著是「重建」這一半——也就是逆向去雜訊過程。我們訓練一個神經網路去「還原」加雜訊的其中一步:給它一張稍微有點雜訊的圖,請它變得稍微乾淨一點。就這一項技能,整場遊戲的關鍵全在這裡。要生成一張全新的圖,我們從一張全新的純隨機雜訊開始——抽出這種雜訊易如反掌——然後請網路一次清掉一步、一步又一步,沿著鏈條往回走。走到最末端,一張清晰、連貫、從未出現在訓練集裡的影像就浮現了。我們把那個不可能的任務(「從無到有變出一張逼真的圖」)轉化成了一長串同一個簡單任務(「把這張弄得雜訊少一點點」)。
一排影像:最左邊是清晰照片,往右逐漸變得粗糙,最右端是純雪花。箭頭向右標示「加入雜訊」,向左標示「去雜訊」。
兩個畫面能把這種「不對稱」講得很生動。(1)把一滴墨水滴進一杯水裡。它會綻開、擴散,直到整杯水變成均勻的灰——這過程看著很容易,但你盯著看一輩子,也永遠看不到墨水自己聚回成一滴。前向過程就是那個擴散;而訓練好的模型,做的正是那個看似奇蹟的逆轉。(2)據說米開朗基羅曾說,雕像本來就在大理石裡,他只是把不屬於雕像的部分鑿掉。擴散模型就是那位雕刻家:拿到一塊純雜訊,它一步步把雜訊鑿掉,直到藏在裡面的形象被顯露出來。
快速導覽其他選項:GAN 與 VAE
擴散模型並不是降臨在一個空房間裡。多年以來,另外兩族模型也在生成影像,而且你會不斷聽到它們的名字,所以讓我們公平地認識一下。第一個是生成對抗網路(GAN)。想像兩個網路之間的一場較量:一個是負責畫假圖的「生成器」,另一個是「鑑別器」——一位評審——負責分辨哪些是假圖、哪些是真照片。它們互相對抗著訓練。偽造者越來越擅長騙過評審;評審越來越敏銳地抓出贗品;一回合又一回合,假圖變得逼真到令人發毛。
生成器把雜訊變成假圖;鑑別器同時收到假圖與真圖,輸出「真或假」,並以回饋箭頭同時訓練兩個網路。
GAN 能畫出令人驚豔的影像,但這場較量出了名地難以平衡。只要任何一方壓過另一方,訓練就會崩潰或來回震盪,而不是穩定收斂。它們還有一個毛病叫做模式崩潰(mode collapse):生成器發現了少數幾種能可靠騙過評審的圖型,就悄悄地不再生產其他東西了——想像我們的偽畫師因為夕陽好賣,就只學畫夕陽,把別的都忘光了。結果是它只覆蓋了真實資料多樣性的一小部分。
第二族是變分自編碼器(VAE)。它有兩半:一個「編碼器」把影像壓縮成一小組數字——一段精簡的「潛在編碼(latent code)」——以及一個「解碼器」,把編碼再展開回一張影像。把兩者一起訓練,使得 解碼(編碼(影像)) ≈ 原圖,之後你就能餵給解碼器一段全新的隨機編碼來生成影像。VAE 訓練起來穩定又優雅,這很討喜——但它的輸出在歷史上總是偏模糊,彷彿隔著一層毛玻璃看圖,因為壓縮會把細節抹平。
一張影像經過編碼器,變成中間一段小小的潛在向量,再經過解碼器變回一張影像。
那麼擴散模型為什麼在 2021–2022 年前後超越了這兩者?三個原因。訓練穩定:逆向網路是用樸素的迴歸損失來訓練的——預測一個目標、量出誤差、微調權重——沒有對抗式的拉鋸需要平衡,所以它幾乎不會崩潰。樣本品質:緩慢的多步精修能產出可與最強 GAN 匹敵、甚至更勝一籌的細節。覆蓋面:因為它學的是去除每一種影像的雜訊,而不只是學會騙過某個評審,它能捕捉資料的完整廣度,也就大致避開了模式崩潰。
走過一連串越來越雜的影像
讓我們用一點點溫和的符號,把這個「逐步」的想法變具體——沒什麼好怕的,只是給鏈條上的圖片取名字而已。把乾淨的起始影像叫做 x₀(讀作「x-零」;那個下標只是步數計數器)。加一步雜訊之後我們得到 x₁,接著 x₂,依此類推,每一次都更雜一點,一路走到 x_T——它(幾乎)是純雪花。大寫的 T 是總步數,實務上 T 常常設在 1000 左右。所以前向過程是一整道由圖片組成的階梯,x₀ → x₁ → x₂ → … → x_T,從照片走到雪花。
這條鏈有一個很乾淨的性質:每一張圖只取決於緊接在它前面的那一張。要做出 x₅,你拿 x₄ 再灑一抹雜訊就好——不需要回頭看 x₃、x₂ 或 x₀。具有這種「沒有記憶」習性的過程,叫做馬可夫鏈(Markov chain):下一個狀態只需要當前狀態,從不需要整段歷史。正是這個性質,讓我們能用「同一條簡單規則反覆套用」來描述整個前向過程。
有一個旋鈕掌控著整道階梯:雜訊排程(noise schedule)——這份配方規定每一步要加多少雜訊。一份合理的排程會在早期幾步只加一絲絲雜訊(讓圖片溫和地劣化),到後期幾步再加得多一些(把工作收尾、抵達完全的雪花)。把這份配方調對非常重要:雜訊加得太快,逆向時網路每一步要還原的跨度就太大;加得太慢,又會白白浪費數百步的步數和算力。調整排程是擴散模型實作上的一門手藝,我們之後會再回來談它。
一道標記好的影像階梯,從 x_0(乾淨)到 x_T(雪花),早期加的雜訊少、後期加的多。
因為整條前向鏈不過就是「拿上一張圖、加上排程好的雜訊」,我們可以把它寫成一個很小的迴圈。下面的程式碼不是真正的數學(那會在第 2 份指南登場)——它是對「正在發生的事」忠實的速寫,好讓你腦中的畫面和這段程式對得上。
# Forward diffusion as a tiny loop (conceptual sketch, not the exact math).
# schedule[t] says how strong the noise is at step t; bigger later on.
x = clean_image # this is x_0
chain = [x]
T = 1000 # total number of steps
for t in range(1, T + 1):
noise = random_normal(shape=x.shape) # fresh random static
strength = schedule[t] # how much to add at this step
# Markov: the new image depends ONLY on the current one, x.
x = mix(x, noise, strength) # blend in a little noise
chain.append(x)
# chain[0] is the clean photo; chain[T] is (almost) pure noise.
# Note: NOTHING here was learned. It is a fixed recipe.
# The neural network's job (Guide 2-3) is to walk this list BACKWARDS.模型實際上學會做什麼
有個合理的問題一直懸在半空中:當我們說「訓練那個逆向網路」時,它到底在預測什麼?你可能會猜它直接輸出比較乾淨的那張圖。但真正的答案——也是支撐起這套主力做法、令人意外地俐落的選擇——更簡單:給網路一張有雜訊的圖,外加一個數字 t 告訴它現在走到第幾步,它就去預測「被加進去的那團雜訊」。它對著那片顆粒指出:「那一團亂——那就是雜訊。」
為什麼「預測雜訊」就等於「去雜訊」?因為這是單純的算術。有雜訊的圖,大致上就是「乾淨的圖加上一些雜訊」。如果網路能告訴你雜訊是什麼,你只要把它減掉,剩下的就是比較乾淨的圖。預測雜訊和移除雜訊,是同一枚硬幣的兩面——而且事實證明,對網路來說,「預測雜訊」比「直接預測圖片」是個更容易、更好馴服的學習目標。做一次,你就從 x_t 走到比較乾淨的 x_{t-1};沿著鏈條一路做到底,一整張圖就從雪花裡浮現出來。
一個日常的比喻:把一張顆粒粗糙的夜拍照片交給一位老練的修圖師。他不會從頭重畫整個場景;他會看著照片、一一指出——「這個斑點是感光元件雜訊,那一粒也是,還有那個」——一旦把那些斑點挑掉,底下真正的照片就乾乾淨淨地浮現了。網路就是那位修圖師,只不過它是一次估計整張圖上整片雜訊的分布,而且在沿著鏈條往回走的過程中,一遍又一遍地這麼做。
這套具體的配方——一條固定的前向加雜訊鏈,加上一個被訓練去預測「每一步所加雜訊」的網路——有個名字:去雜訊擴散機率模型,簡稱 DDPM。它是 擴散模型最乾淨、最具影響力的一套表述,而下一份指南要嚴謹講清楚的,正是它。這條學習軌裡其他的一切——文字提示、潛在空間、細緻的控制——全都搭建在這一個想法之上:預測雜訊、把它減掉、再重複。
這是接下來的路線圖,好讓你隨時知道自己走到哪裡。我們剛剛建立了直覺。接下來我們會把「加雜訊」講精確,然後是去雜訊網路與取樣器,再來學會用文字去引導它,最後拿到完整的控制權:
- 第 2 份——刻意加入雜訊:把前向擴散過程精確地寫下來(排程,以及那個能一步跳到任意 x_t 的俐落捷徑)。
- 第 3 份——學會去雜訊:負責預測雜訊的 U-Net、訓練用的損失函數,以及把鏈條反向跑來生成影像的取樣器。
- 第 4 份——以文字作畫:潛在擴散(第 3 節提過的 VAE 招數)與文字生成圖像的條件機制,讓一段提示詞就能召喚出一張圖。
- 第 5 份——精通控制:局部重繪與編輯、ControlNet,以及「可引導、可控制生成」的當前前沿。