19.7 생성모델의 평가

실습 · 연습문제 2개

가우시안 근사의 Fréchet 거리 frechet-gaussian

FID는 실제 특징과 생성 특징에 각각 가우시안 N(μr,Σr)\mathcal{N}(\boldsymbol{\mu}_r, \boldsymbol{\Sigma}_r), N(μg,Σg)\mathcal{N}(\boldsymbol{\mu}_g, \boldsymbol{\Sigma}_g)를 맞춘 뒤, 두 가우시안의 Fréchet 거리를 계산한다.

d2=∥μr−μg∥2+tr⁡(Σr+Σg−2(ΣrΣg)1/2).d^2 = \lVert \boldsymbol{\mu}_r - \boldsymbol{\mu}_g \rVert^2 + \operatorname{tr}\big(\boldsymbol{\Sigma}_r + \boldsymbol{\Sigma}_g - 2(\boldsymbol{\Sigma}_r\boldsymbol{\Sigma}_g)^{1/2}\big).

함수 두 개를 완성한다.

  1. frechet_from_stats(mu1, S1, mu2, S2): 평균 벡터(shape (d,))와 공분산 행렬(shape (d, d))로 d2d^2를 반환한다. 행렬 제곱근은 scipy.linalg.sqrtm을 쓰고, 수치 오차로 생기는 아주 작은 허수부는 버린다(.real).
  2. frechet_from_features(a, b): 특징 행렬 a(shape (N, d)), b(shape (M, d))에서 표본 평균과 표본 공분산(np.cov(..., rowvar=False))을 구해 1을 호출한다.

테스트는 다음을 확인한다.

  • 같은 가우시안이면 0이다.
  • 공분산이 같고 평균만 다르면 평균 차이의 제곱 노름이다.
  • 1차원에서는 (μ1−μ2)2+(σ1−σ2)2(\mu_1 - \mu_2)^2 + (\sigma_1 - \sigma_2)^2이다.
  • 두 인자의 순서를 바꿔도 값이 같다.
  • 평균과 공분산이 같고 모양만 다른 두 표본 집합(가우시안과 두 봉우리 분포)에는 거의 0을 준다. FID가 가우시안 밖의 구조를 보지 못한다는 뜻이다.

불편 MMD² 추정량 mmd-unbiased

표본 X={xi}i=1m\mathbf{X} = \{\mathbf{x}_i\}_{i=1}^{m}과 Y={yj}j=1n\mathbf{Y} = \{\mathbf{y}_j\}_{j=1}^{n}으로 두 분포의 MMD²를 추정한다. RBF kernel은

k(a,b)=exp⁡ ⁣(−∥a−b∥22h2)k(\mathbf{a}, \mathbf{b}) = \exp\!\Big(-\frac{\lVert \mathbf{a} - \mathbf{b} \rVert^2}{2h^2}\Big)

이고, 같은 점끼리의 항(i=i′i = i', j=j′j = j')을 뺀 불편 추정량은 다음과 같다.

MMD^u2=1m(m−1)∑i≠i′k(xi,xi′)+1n(n−1)∑j≠j′k(yj,yj′)−2mn∑i,jk(xi,yj).\widehat{\mathrm{MMD}}{}^2_u = \frac{1}{m(m-1)}\sum_{i \ne i'} k(\mathbf{x}_i, \mathbf{x}_{i'}) + \frac{1}{n(n-1)}\sum_{j \ne j'} k(\mathbf{y}_j, \mathbf{y}_{j'}) - \frac{2}{mn}\sum_{i, j} k(\mathbf{x}_i, \mathbf{y}_j).

함수 mmd2_unbiased(x, y, bw)를 완성한다. x의 shape은 (m, d), y는 (n, d), bw는 대역폭 h>0h > 0이다. m≠nm \ne n이어도 동작해야 한다. 스칼라(float)를 반환한다.

테스트는 다음을 확인한다.

  • 손으로 계산할 수 있는 작은 예(1차원 점 세 개와 두 개)에서 값이 맞는다.
  • 같은 분포에서 뽑은 두 표본의 값은 0 근처이고, 음수가 나올 수도 있다(대각 항을 뺐으므로).
  • 평균이 다른 두 분포에서는 값이 분명히 양수이고, 평균 차이가 클수록 커진다.
  • 두 인자의 순서를 바꿔도 값이 같다.
  • 대역폭이 차이의 척도보다 훨씬 크면 값이 0에 가까워진다(kernel이 차이를 보지 못한다).

힌트: 쌍별 거리 제곱 행렬을 broadcasting으로 만들고, ∑i≠i′\sum_{i \ne i'}는 전체 합에서 대각선의 합을 빼서 구한다. RBF kernel의 대각선은 모두 1이다.