高质量GAN采样的枢纽度先验.
1. 维度灾难与Hubness现象
维度灾难(the curse of dimensionality)指出,数据在高维空间中的分布具有稀疏性,从而产生有悖于低维空间(如二维或三维空间)常识的现象。
高维空间中边长为$1$的超立方体内的样本点集中分布在立方体角落。考虑$n$维空间中边长为$1$的超立方体内接超球体,超球体半径为$\frac{1}{2}$,其体积(测度)为$\text{const} \cdot (\frac{1}{2})^n $,当$n→∞$时,超球体体积为$0$。
枢纽(Hubness)现象是指在高维空间中随机采样一批样本点,会有少数样本点经常出现在其他点的$k$邻域中。用hub值统计每个样本点出现在其余点的$k$邻域的次数,则总有一些点的hub值较大。
直观地,靠近密度中心(均值向量)的点与所有点的平均距离最小,有更大的概率在其他点的$k$邻域中(对应hub值较大);而密度中心附近的点(以密度中心为球心的球邻域)占比非常小,因此这类hub值较大的点非常少。
2. 枢纽度先验 Hubness Prior
本文提出了枢纽度先验(Hubness Prior),即在GAN的采样过程中,hub值越大的采样点对应的生成质量就越好。
一般地,GAN的采样流程是$z$~\(\mathcal{N}(0,1)\), $x = G(z)$。从\(\mathcal{N}(0,1)\)中采样$N$个样本点后,计算每个样本点的hub值,只保留hub值超过阈值$t$的样本点用来生成新的样本。hub值的计算通过kNN实现。
def get_z_samples(size, t=50):
"""通过Hub值对采样结果进行筛选
"""
Z = np.empty((0, z_dim))
while len(Z) < size:
z = np.random.randn(10000, z_dim)
hub = np.zeros(10000)
for i in range(10):
zi = z[i * 1000:(i + 1) * 1000]
# 计算样本矩阵z和查询矩阵zi的距离
d = (z**2).sum(1)[:, None] + (zi**2).sum(1)[None] - 2 * z.dot(zi.T)
# 计算每个样本点的5近邻
for j in d.argsort(0)[1:1 + 5].T:
hub[j] += 1
z = z[hub > t]
Z = np.concatenate([Z, z], 0)[:size]
print('%s / %s' % (len(Z), size))
return Z
hub值越大,则越接近样本的密度中心,则该样本不太可能是没有经过充分训练的离群点,因此采样质量相对更高。