iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0

雖然在過去,GAN 一直都是生成高品質圖片的主流,但他訓練不穩定、模式單一的問題也困擾著許多人。近幾年,一個從熱力學汲取靈感的模型:擴散模型 (diffusion model) 席捲了生成圖片的領域,如 Stable Diffusion 或 DALL-E 等,也讓 AI 生圖這件事變得世人皆知。

核心思想

擴散模型的核心,包含了兩個方向相反的過程

  1. 前向過程(擴散過程):在這部分,模型會有序、逐步破壞一張真實圖片,在每一步都添加一點點高斯噪點。經過足夠的步數後,原圖所有結果與資訊都會被破壞,變成一張符合常態分佈的高斯噪點圖。我們在每一步添加多少噪點,是由一個預先設定好的、稱為變異數調度 (variance schedule) 的超參數決定的。

  2. 反向過程(去噪過程):這一部分的目標是學習一個神經網路,讓他逆轉前向過程。從純粹的噪點圖開始,每一步神經網路都會去預測帶噪圖片的「噪點是長怎樣」,然後再減去被預測的噪點,得到一張「乾淨一點」的圖片。在不斷進行這個過程後,我們最終可以得到一張清晰、全新的圖片。

神經網路的角色

神經網路通常是 U-Net 架構,它扮演了噪點預測器的角色。訓練時的流程是

  1. 隨機選取一張真實圖片。

  2. 隨機選取一個步數 t。

  3. 根據前向過程的公式,預測圖片在第 t 步時應該會變成怎樣。

  4. 把 t 與第 t 步的圖片一起送入 U-Net 模型,目標是讓他的輸出與步驟 3 實際天家的噪點盡量接近(損失最小)。

透過在所有圖片、所有 t 上的大量訓練,這個 U-Net 模型就學會了在任何噪點程度下,都能精準地預測出圖片中的噪點,從而掌握了從噪點還原回清晰圖像的能力。

實際效果

擴散模型效果良好主要有以下因素

  • 訓練穩定:與 GAN 的對抗性訓練不同,擴散模型的訓練目標(預測噪點)非常明確和穩定。

  • 生成多樣性: 由於生成過程是從隨機噪點開始的,每次都能生成完全不同的結果,很好地避免了 GAN 的模式崩潰問題。

  • 可控性:透過在 U-Net 中引入額外的條件 (prompt),我們可以精準地控制生成圖像的內容。

用 Diffusers 函式庫體驗 Stable Diffusion

(注意程式會下載數 GB 的模型)

首先安裝 Diffusers 和相關函式庫

pip install diffusers transformers accelerate scipy safetensors 
import torch
from diffusers import StableDiffusionPipeline

# --- 1. 載入預訓練的 Stable Diffusion 模型 ---
# 我們使用 Stable Diffusion v1.5 版本
# model_id = "runwayml/stable-diffusion-v1-5"
model_id = "sd-legacy/stable-diffusion-v1-5" 

print(f"正在從 Hugging Face Hub 下載模型: {model_id}...")
print("初次下載可能需要一些時間,並佔用數 GB 的磁碟空間。")

# StableDiffusionPipeline 是一個端到端的類,封裝了所有需要的組件
# torch_dtype=torch.float16 使用半精度浮點數,可以節省大量顯存並加速
# use_safetensors=True 使用更安全的權重格式
pipe = StableDiffusionPipeline.from_pretrained(
    model_id, 
    torch_dtype=torch.float16, 
    use_safetensors=True
)

# 將 pipeline 移至 GPU (如果可用)
device = "cuda" if torch.cuda.is_available() else "cpu"
pipe = pipe.to(device)
print(f"模型已載入到 {device}。")

# --- 2. 準備文字提示 (Prompt) ---
prompt = "masterpiece, horse, astronaut, moon"

# (可選) 負面提示 (Negative Prompt),告訴模型不希望看到什麼
negative_prompt = "watermark, low quality, ugly, blurry"

# --- 3. 執行生成 ---
# generator 確保每次生成的隨機結果可重現
generator = torch.Generator(device).manual_seed(42)

print("\n正在根據提示生成圖片...")
# num_inference_steps 是反向去噪的步數
image = pipe(
    prompt, 
    negative_prompt=negative_prompt,
    num_inference_steps=50,
    generator=generator
).images[0]  # images 是一個 list,我們取第一張圖

print("圖片生成完成!")

# --- 4. 顯示並儲存圖片 ---
image.show()
image.save("result.png")

結果
https://ithelp.ithome.com.tw/upload/images/20250906/20178100oyNGAHDJrm.png


上一篇
Day 26 - Vision Transformer
系列文
從0開始:傳統圖像處理到深度學習模型27
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言