先寫下預測,再執行 A/B。看圖上哪條密度換了位置,也看 μ₀、μ₁ 是否真的更新;之後可以用下方控制項只訓練一步,檢查學習尚未完成時的樣子。
標準 A/B 對照的解釋
A、B 用的是同一組已學的 μ₀、μ₁,累計更新都是 60。A 用 c = 1,B 用 c = 0,因此曲線從右移到左;更新紀錄不變才是沒有重訓的證據。若只學一步,兩個均值仍靠近零,切換 c 也不表示已經學好。
示範:用左右各 256 個帶類別的樣本更新兩個平均值後,μ₀ 會接近 −2、μ₁ 接近 2。生成時只換 c,就能選擇左峰或右峰,不必重新更新平均值。
若已自由改動條件或 Python,以你的實際圖與參數為準,不能把這組標準對照當成你的執行紀錄。
這裡真的從 Gaussian mixture 取資料、更新可學參數或選候選,並畫出 density 與 1,000 個生成樣本的直方圖。Toy generator 可以直接抽樣,沒有把它當成訓練完成的 diffusion network。
換你改程式,執行同一個實驗
可以改參數,也可以改抽樣規則。按執行時才載入 Python;運算在你的瀏覽器進行。每次執行從這段程式重新開始,文字不會存檔。
首次展開會帶入上方的控制項設定;之後重開會保留你改過的程式。帶入的是條件,不包含上方累積訓練的參數或生成樣本,因此兩邊的有限抽樣圖不必完全相同。
先只改開頭的 c,再執行。程式分為資料、訓練、生成、畫圖四段;生成段使用訓練段剛學好的參數。整份重跑仍會從初始模型重新訓練。
import math
import numpy as np
import matplotlib.pyplot as plt
# 1. DATA AND SETTINGS -- edit one setting above the model code.
c = 1 # EDIT: 0 = left, 1 = right
steps = 60
rng = np.random.default_rng(42)
sigma = 0.55
grid = np.linspace(-5, 5, 500)
def pdf(x, mu):
return np.exp(-0.5 * ((x - mu) / sigma) ** 2) / (sigma * np.sqrt(2 * np.pi))
def sample_mixture(n, right=0.5):
mu = np.where(rng.random(n) < right, 2.0, -2.0)
return rng.normal(mu, sigma)
base = 0.5 * pdf(grid, -2) + 0.5 * pdf(grid, 2)
data = [rng.normal(mu, sigma, 256) for mu in [-2.0, 2.0]]
# 2. TRAINING -- each full Run starts from these initial means.
means = np.zeros(2)
for _ in range(steps):
gradient = 0.5 * np.array([means[label] - data[label].mean() for label in [0, 1]])
means -= 0.15 * gradient
# 3. GENERATION -- both inputs below use the SAME trained means.
for label in [0, 1]:
print("same trained parameters, c =", label, "uses mean", means[label])
samples = rng.normal(means[c], sigma, 1000)
target = pdf(grid, [-2.0, 2.0][c])
after = pdf(grid, means[c])
print("Trained means:", means)
# 4. PLOTTING -- density curves and the actual returned samples.
plt.figure(figsize=(7, 3.8))
plt.plot(grid, base, color="gray", linestyle="--", label="original base")
plt.plot(grid, target, color="teal", linestyle=":", label="training-data target")
plt.plot(grid, after, color="darkorange", label="model / returned density")
plt.hist(samples, bins=np.linspace(-5, 5, 41), density=True, alpha=0.25, color="darkorange", label="1000 generated outputs")
plt.xlabel("x0")
plt.ylabel("density")
plt.xlim(-5, 5)
plt.legend(fontsize=8)
plt.tight_layout()
plt.show()
套件訊息與警告