GAN menghasilkan sampel tajam tetapi membayar mahal dalam hal kestabilan: dua jaringan yang saling berhadapan membuat training mudah goyah, sebagaimana kita lihat pada chapter Stabilitas Training GAN . Diffusion model menempuh jalur yang sama sekali berbeda: alih-alih mempertemukan dua model dalam satu permainan, diffusion merusak data secara bertahap dengan derau Gaussian sampai tersisa derau murni, lalu melatih satu jaringan untuk membalik proses tersebut langkah demi langkah. Training-nya menjadi masalah regresi biasa — memprediksi derau yang ditambahkan — sehingga jauh lebih stabil, dan kualitas sampelnya kini menjadi acuan industri. Chapter ini memperkenalkan gagasan besarnya lewat perbandingan keluarga model generatif dan demonstrasi nyata pada sinyal 1D.
Posisi Diffusion di antara Keluarga Model Generatif #
Ketiga keluarga besar yang telah kita bahas — VAE, GAN, dan kini diffusion — menyelesaikan masalah yang sama dengan mekanisme belajar yang berbeda. Tabel berikut merangkum posisi masing-masing:
| Aspek | VAE | GAN | Diffusion |
|---|---|---|---|
| Cara belajar | rekonstruksi + regularizer KL | generator vs discriminator bersaing | memprediksi derau (MSE) |
| Objectif | satu loss gabungan | minimax dua pemain | regresi derau per langkah |
| Kualitas sampel | cenderung kabur | tajam | tajam dan beragam |
| Kestabilan training | stabil | goyah, perlu banyak trik | stabil |
| Kecepatan sampling | cepat (satu forward pass) | sangat cepat | lambat (ratusan langkah) |
VAE pada chapter Variational Autoencoder kompak dan stabil, tetapi asumsi Gaussian pada laten membuat rekonstruksinya cenderung kabur. GAN pada chapter Generative Adversarial Network menghasilkan sampel tajam, tetapi keseimbangan dua jaringan mudah pecah. Diffusion menukar kecepatan sampling dengan kestabilan training dan kualitas — kompromi yang terbukti produktif untuk data berdimensi besar seperti gambar.
Ide Dasar: Menambahkan Derau, Lalu Mempelajari Pembaliknya #
Proses diffusion terdiri dari dua arah. Forward process menambahkan derau Gaussian kecil secara bertahap selama T langkah (biasanya T = 1000): data bersih x_0 berubah perlahan menjadi x_1, x_2, …, hingga x_T yang praktis tak terbedakan dari derau murni. Reverse process adalah arah yang dipelajari: sebuah jaringan denoiser menerima x_t dan t, lalu menebak derau yang harus dibuang agar kembali ke x_t-1. Sampling dilakukan dengan menarik derau acak sebagai x_T, lalu membalik T langkah hingga diperoleh data baru x_0.
Rantai ke bawah pada diagram adalah forward process — tetap dan tidak melibatkan pelatihan. Rantai dari x_T naik kembali adalah reverse process yang dipelajari jaringan denoiser; panahnya membalik arah alur data saat sampling. Pada Chapter Forward dan Reverse Diffusion
kita akan menuliskan kedua proses ini sebagai distribusi Gaussian secara formal.
Melihat Derau Bertahap dengan Angka Nyata #
Berkas proses_derau.py menerapkan forward process pada gelombang sinus 8 titik, memakai jadwal derau linear dari makalah DDPM (beta naik dari 1e-4 ke 0.02), lalu mencetak kondisi sinyal pada empat timestep. Skrip ditutup dengan eksperimen kecil yang menjelaskan mengapa denoiser harus dipelajari, bukan dihitung langsung:
"""Forward diffusion pada sinyal 1D: derau ditambahkan bertahap.
Sinyal gelombang sinus 8 titik dideraui selama T = 1000 langkah.
Skrip mencetak nilai sinyal pada beberapa timestep, menunjukkan SNR
yang menurun, lalu membuktikan mengapa proses baliknya membutuhkan
denoiser yang dipelajari: tanpa mengetahui derau yang benar-benar
ditambahkan, pembalikan langsung menghasilkan nilai tak bermakna.
"""
import numpy as np
rng = np.random.default_rng(42)
# ---------- 1. Sinyal bersih: satu periode gelombang sinus, 8 titik ----------
n = 8
sinyal = np.sin(2.0 * np.pi * np.arange(n) / n)
# ---------- 2. Jadwal derau linear (DDPM): beta kecil -> besar ----------
T = 1000
beta = np.linspace(1e-4, 0.02, T)
alpha = 1.0 - beta
alpha_bar = np.cumprod(alpha) # alpha_bar[t-1] = alpha_1 * ... * alpha_t
# ---------- 3. Forward diffusion iteratif ----------
x = sinyal.copy()
riwayat = {0: x.copy()}
for t in range(1, T + 1):
eps = rng.standard_normal(n)
x = np.sqrt(1.0 - beta[t - 1]) * x + np.sqrt(beta[t - 1]) * eps
if t in (250, 500, 1000):
riwayat[t] = x.copy()
print("sinyal x_0 (gelombang sinus, 8 titik):")
print(" ", np.round(sinyal, 3))
print(f"\nJadwal linear: beta_1 = {beta[0]:.5f}, beta_{T} = {beta[-1]:.2f}")
print()
print(" t | 4 nilai pertama x_t | RMSE vs x_0 | SNR (dB)")
print("------+------------------------------------------+-------------+---------")
for t in (0, 250, 500, 1000):
xt = riwayat[t]
rmse = np.sqrt(np.mean((xt - sinyal) ** 2))
if t == 0:
snr_teks = "inf"
else:
ab = alpha_bar[t - 1]
snr_teks = f"{10.0 * np.log10(ab / (1.0 - ab)):7.1f}"
print(f" {t:4d} | {np.round(xt[:4], 3)} | {rmse:11.3f} | {snr_teks:>7}")
# ---------- 4. Konsep denoiser: pembalikan butuh derau yang tepat ----------
ab500 = alpha_bar[499]
eps = rng.standard_normal(n)
x500 = np.sqrt(ab500) * sinyal + np.sqrt(1.0 - ab500) * eps
tebakan = rng.standard_normal(n)
pulih_benar = (x500 - np.sqrt(1.0 - ab500) * eps) / np.sqrt(ab500)
pulih_tebakan = (x500 - np.sqrt(1.0 - ab500) * tebakan) / np.sqrt(ab500)
print()
print(f"Pulihkan x_0 dari x_500 (alpha_bar_500 = {ab500:.4f}):")
print(" dengan derau yang benar : RMSE",
f"{np.sqrt(np.mean((pulih_benar - sinyal) ** 2)):.4f}")
print(" dengan derau tebakan : RMSE",
f"{np.sqrt(np.mean((pulih_tebakan - sinyal) ** 2)):.4f}")
print()
print("Amplitudo sinyal tersisa di t=500 : sqrt(alpha_bar) =",
f"{np.sqrt(ab500):.4f}")
print("Amplitudo derau di t=500 : sqrt(1-alpha_bar) =",
f"{np.sqrt(1.0 - ab500):.4f}")Output yang Dihasilkan:
sinyal x_0 (gelombang sinus, 8 titik):
[ 0. 0.707 1. 0.707 0. -0.707 -1. -0.707]
Jadwal linear: beta_1 = 0.00010, beta_1000 = 0.02
t | 4 nilai pertama x_t | RMSE vs x_0 | SNR (dB)
------+------------------------------------------+-------------+---------
0 | [0. 0.707 1. 0.707] | 0.000 | inf
250 | [-1.276 -0.004 -1.121 0.091] | 0.966 | 0.4
500 | [ 0.304 0.867 -0.654 -0.141] | 0.736 | -10.7
1000 | [-0.338 -0.206 0.465 -2.571] | 1.286 | -43.9
Pulihkan x_0 dari x_500 (alpha_bar_500 = 0.0786):
dengan derau yang benar : RMSE 0.0000
dengan derau tebakan : RMSE 4.8609
Amplitudo sinyal tersisa di t=500 : sqrt(alpha_bar) = 0.2803
Amplitudo derau di t=500 : sqrt(1-alpha_bar) = 0.9599Tiga fakta terbaca langsung dari keluaran. Pertama, nilai sinyal berubah nyata antar timestep: titik kedua bernilai 0.707 di t=0, menjadi -0.004 di t=250, lalu 0.867 di t=500 — jejak gelombang sinus praktis hilang. Kedua, SNR (rasio sinyal terhadap derau) menurun monoton dari inf ke -43.9 dB; pada t=250 sinyal dan derau sudah sama kuat, dan pada t=1000 yang tersisa hampir murni derau. Ketiga, di t=500 amplitudo sinyal tersisa hanya 0.2803 sedangkan amplitudo derau mencapai 0.9599. Mari kita telaah kode di atas baris per baris:
- Baris 12 (
default_rng(42)): generator derau ber-seed membuat seluruh keluaran reproducible — nilai yang sama muncul pada setiap eksekusi. - Baris 15-16 (
sinyal):np.sinmembentuk satu periode sinus 8 titik; nilai-nilainya persis0, 0.707, 1, 0.707, 0, -0.707, -1, -0.707. - Baris 19-22 (jadwal derau):
betanaik linear dari1e-4ke0.02;alpha = 1 - beta;np.cumprodmenghitungalpha_bar— hasil kali beruntunalphayang melacak sisa amplitudo sinyal, notasi lengkapnya dibahas pada chapter berikutnya. - Baris 27-31 (loop forward): setiap langkah mengalikan
xdengansqrt(1-beta_t)(sinyal menyusut) dan menambahkansqrt(beta_t)kali derau segar; snapshot disimpan padat = 250, 500, 1000. - Baris 39-47 (tabel): RMSE mengukur seberapa jauh
x_tdarix_0; SNR dihitung darialpha_bar— angkainfdit=0menandakan belum ada derau sama sekali. - Baris 50-56 (eksperimen pembalikan):
x_500dibangun langsung darix_0memakai bentuk ringkasx_t = sqrt(alpha_bar_t) x_0 + sqrt(1-alpha_bar_t) eps(rumus ini kita turunkan pada chapter berikutnya). Membalik rumus denganepsyang sama memulihkanx_0sempurna (RMSE0.0000), tetapi memakai derau tebakan menghasilkan RMSE4.8609— hampir tujuh kali amplitudo sinyal asli.
Bagian terakhir itulah inti masalahnya: pembalikan matematis selalu tersedia, tetapi membutuhkan eps yang tidak kita ketahui. Diffusion model menyelesaikannya dengan melatih jaringan untuk menebak eps dari (x_t, t) — tugas regresi ber-loss MSE yang sama sekali tidak melibatkan dua jaringan yang saling berhadapan.
Mengapa Training Diffusion Stabil #
Stabilitas diffusion berasal dari bentuk objectifnya. Denoiser belajar memprediksi derau dengan MSE — fungsi loss yang mulus, bertanda tunggal, dan turunannya teratur — persis keluarga loss yang kita bedah pada chapter Loss Function
. Tidak ada minimax, tidak ada gradien yang saling meniadakan antar dua model, dan tidak ada mode collapse karena proses forward menyentuh seluruh ruang data secara gradual. Imbalannya ada di sisi inference: menghasilkan satu sampel menuntut T kali evaluasi jaringan (ratusan hingga ribuan), itulah alasan riset decoding diffusion berkonsentrasi memangkas jumlah langkah.
Aplikasi: Gambar, Audio, dan Lainnya #
Pada domain gambar, diffusion model menjadi dasar text-to-image generatif yang paling dikenal — Stable Diffusion — yang akan kita bedah arsitekturnya pada chapter Latent Diffusion
. Pada domain audio, model generatif berbasis diffusion mensintesis bentuk gelombang atau spektrogram ucapan dan musik. Penerapan lain membentang dari video, struktur molekul untuk penemuan obat, hingga imputasi data deret waktu. Makalah fondasi DDPM (Denoising Diffusion Probabilistic Models) oleh Ho dkk. tahun 2020 tersedia di arxiv.org/abs/2006.11239
— sumber notasi beta, alpha, dan alpha_bar yang kita pakai sepanjang section ini.
Kita sekarang memegang gambaran besarnya: forward merusak bertahap, reverse dipelajari, sampling membalik dari derau murni. Pertanyaan berikutnya bersifat matematis: bagaimana menuliskan kedua proses itu sebagai distribusi Gaussian, dan mengapa rantai ribuan langkah bisa dilompati oleh satu rumus tertutup? Chapter Forward dan Reverse Diffusion menjawabnya dengan derivasi ringkas dan implementasi NumPy yang angkanya bisa dicocokkan.