JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

生成與編輯影像

前面幾篇裡,網路一直在「看」圖片,告訴你裡面有什麼。現在我們把箭頭掉轉過來:看一個模型如何從純粹的雪花雜訊出發,一小步一小步地去雜訊,最終「畫」出一張從未存在過的圖——以及這套魔法在哪裡悄悄露了餡。

把箭頭掉轉:從「看」到「造」

本階到目前為止的一切都朝著一個方向跑:圖片進去,標籤、框或遮罩出來。卷積網路看出一隻貓;視覺 Transformer看出各個部件以及它們之間的關係。生成則把這個箭頭反了過來。我們要的不是「影像 → 含義」,而是「含義 → 影像」:把「一隻狐狸在雨中讀報紙」這個想法交給模型,讓它產出與之相符的像素。難就難在沒有唯一正確答案——能誠實地匹配這幾個字的圖,可以有十億張之多。

所以生成器並不是把一個輸入映到一個輸出的函數。它是一種從浩瀚的「合理影像」空間裡取樣的方式——就像擲骰子是在 1 到 6 這些數字裡取樣一樣。早期的嘗試用 生成對抗網路,讓一個造假者和一個鑑別者對打;也用過 變分自編碼器,把影像擠過一個狹窄的瓶頸。兩者都能用,但訓練起來都很嬌氣。最終接管這個領域的方法更溫和,而且一旦你看懂,幾乎是順理成章的。

擴散:學會把雜訊「撤銷」

擴散模型背後的把戲是這樣的。拿一張真實照片,往裡一點點撒入隨機雜訊——先一點,再多一點,越來越多——經過幾百個微小步驟後,它就和電視雪花花屏沒什麼兩樣了。這種「破壞」很容易,無非是加雜訊。真正巧妙的一步是訓練一個網路去倒著跑這個過程:給它一張帶雜訊的圖,再告訴它一個數字、說明它*有多*雜,讓它預測出當初加進去的那部分雜訊,好把它減掉。做到這一點,你就能一層一層把雜訊剝下來。

回報來了。要*生成*影像,你根本不從照片開始——你從純雜訊、從全新的隨機雪花出發,然後一遍又一遍地向訓練好的網路問同一個問題:「你在這裡看到了什麼雜訊?」減掉一小口,再重複。許多步之後,雜訊就凝結成一張乾淨、連貫的影像。網路從沒背下這張圖;它學到的是「真實影像長什麼樣」的大致樣貌,並用它從隨機中雕出秩序。負責預測雜訊的主力網路通常是一個 U-Net——一種編碼器—解碼器,先把影像縮小以抓住整體大局,再把它放大回全解析度,同時保住細節。

潛在擴散:在一個更小的世界裡做這件事

在一張全尺寸影像上跑幾百個去雜訊步驟——每一遍都是幾百萬像素——代價高得嚇人。讓影像生成便宜到人人可用的那次突破,叫 潛在擴散。思路是:根本不去擴散像素。先訓練一個 自編碼器,把一張影像壓成一小格數字——一個潛在表示(latent)——它抓住影像的精髓,體積也許只有原來的幾十分之一,並且能被解碼回一張忠實的圖。然後,把整套「從雜到淨」的擴散過程統統放進這個緊湊的潛在空間裡去跑。

流程於是變成:在潛在空間裡放入雜訊 → 一步步去雜訊 → 得到一個乾淨的潛在表示 → 一次性把它解碼成全解析度像素。因為潛在表示小得多,每個去雜訊步只需做一小部分工作,模型也得以專注於*含義*,而不必浪費力氣去複刻精確的像素紋理(那些交給解碼器)。這正是你也許在自己筆電上跑過的那些開源模型背後的架構。代價是一個微妙之處:解碼器會把最細的細節抹糊,這也是為什麼招牌上生成的文字、以及小人臉的結構常常出來是亂的。

用文字掌舵:文字生成影像

到目前為止,模型能憑空夢出*某張*連貫的圖,卻還不是你點的那張。文字生成影像給它裝上了方向盤。你的提示詞會被轉成一個嵌入向量——一串捕捉其含義的數字——通常由 CLIP 這類模型來做,它在訓練時學會把相互匹配的圖文對在一個共享空間裡放得彼此靠近。在每一個去雜訊步裡,這個文字嵌入都會透過注意力機制餵進 U-Net,於是雜訊預測就被往「與你的話相符的內容」那一側輕輕推。整張圖,是*以提示詞為條件*被雕出來的。

latent = random_noise()                  # start from static
for t in reversed(timesteps):            # e.g. 50 steps
    text = encode(prompt)                # meaning of your words
    eps  = unet(latent, t, text)         # predicted noise, nudged by text
    latent = step(latent, eps, t)        # subtract a sip of noise
image = decoder(latent)                  # latent -> full pixels (once)
潛在空間裡的文字生成影像迴圈:許多個小小的去雜訊步,每一步都由提示詞掌舵,最後只解碼一次。

還有一個值得認識的旋鈕:引導強度。你可以告訴模型,是該更緊地貼著提示詞,還是更多地聽從它自己對「什麼樣子才自然」的判斷。調到很高,影像會死死咬住你的字眼,但可能變得豔俗、過飽和;調低一些,圖會更柔和自然,卻可能跑題、偏離你的要求。這裡沒有免費的午餐——它是一個真實的權衡,要憑感覺去調,而不是有唯一正確取值的開關。

編輯與超解析度:同一個思路,換個條件

一旦你抓住了「去雜訊,並以某物為條件」這個核心,一整箱工具就打開了——你只需換掉模型*以什麼*為條件。給它一張真實照片、把一塊摳空,讓它把那塊區域補上(inpainting,局部重繪)。讓去雜訊不從純雪花、而是從一張現有影像「加了一半雜訊」的版本開始,它就會把圖往你的提示詞那邊推、同時保住原有構圖(圖生圖)。以一張邊緣圖或一具姿態骨架為條件,你就能精確掌控佈局。去雜訊引擎本身從不改變;變的只是條件。

超解析度又是同一招:讓生成器以一張小而模糊的圖為條件,請它產出一張更大、更清晰的圖。但在這裡,誠實非常要緊。模型並不是在*找回*已丟失的細節——那些資訊根本就沒了。它是在編造與低清輸入相符的、看似合理的細節。那清晰的磚牆紋理、那被「銳化」出來的車牌,也許看起來很可信,卻可能完全是虛構的。用來把照片修得更好看,沒問題;可一旦有人把放大後的圖當成「現場真的就是這樣」的證據,那就危險了。

誠實的侷限、瑕疵,以及炒作避而不談的部分

這些模型令人驚嘆,但它們不是魔法。它們沒有任何關於物理或解剖學的模型——只有像素的統計規律。於是它們會畫出六根手指的手、違背幾何的倒影、打錯方向的陰影、以及糊成「像字母的鬼畫符」的文字。這些不是補個補丁就能修好的 bug;它們是從方法本身長出來的。模型給每一塊區域填上*局部*看起來合理的東西,卻沒有一本全局帳本去核對手指加起來是不是五根。更新的模型在這方面越來越好,但「更好」不等於「解決了」。

還有一個更深的侷限。生成器只能從訓練資料展示給它的那個世界裡取樣,因此它會繼承那批資料的偏見——你點一個「醫生」或「美人」,看看它預設會蹦出哪些面孔。它能混搭、能重組,卻不會像行銷話術暗示的那樣、從無到有地憑空發明出真正嶄新的風格。又因為同一套機器也能造出以假亂真的贗品,對影像生成誠實的描述就必須連它的陰影一起講:深度偽造,以及一個至今懸而未決的活生生的問題——拿誰的圖來訓練它

退一步看,整一階就串起來了。你學過像素如何變成張量,卷積網路如何讀它們,Transformer如何把各部件聯繫起來——而現在,你看到同樣的積木倒著跑,就能從雜訊裡召喚出影像。「看」與「造」,原來是同一種本領的兩個方向:一個真正學懂了視覺世界統計規律的模型,既能認出這個世界,也能小心翼翼地、把它夢回來。