4.2 散度、距离与信息不等式
熵度量单个分布的不确定性,互信息度量两个变量的共享信息。还有一类需求没有被覆盖:给定两个分布,它们差多少。用近似分布替代真实分布损失了多少信息、生成样本的分布与真实分布偏离多远、模型的预测分布在训练过程中如何变化,这些问题都需要一个分布之间的差异的度量。
李雅普诺夫式的答案为这类需求提供了多个候选:KL 散度、交叉熵、JS 散度、f 散度、Rényi 散度、Tsallis 散度、Bregman 散度、总变差距离、Hellinger 距离、Wasserstein 距离、最大均值差异。它们之间的联系与区别是本节的中心内容。这些量并非可以任意互换:有的不对称,有的不满足三角不等式,有的在有重叠时才有界,有的即使分布完全不重叠也能给出有意义的梯度。选错度量会使估计与优化出现结构性错误,例如用 KL 训练生成模型时训练信号消失,用总变差做高维检验时功效极低。
本节按从 KL 散度出发逐步扩展的顺序组织。先给出 KL 散度的定义与四条关键性质,再讨论交叉熵与 JS 散度这两个直接派生量;随后引入 f 散度这一生成框架,把 KL、总变差、Hellinger、卡方统一进来;接着讨论 Rényi 与 Tsallis 两族参数化散度,以及来自凸分析的 Bregman 散度;最后处理三个基于几何或核的度量:Wasserstein 距离、最大均值差异,以及它们的适用场景。本节结尾说明各度量在不同任务中的选择依据,并与 4.3 节的信息几何建立接口。
4.2.1 KL 散度
定义
KL 散度(Kullback-Leibler divergence)度量用一个分布近似另一个分布的代价,定义为
连续情形写成积分
KL 散度在信息论中的解释是近似带来的额外编码长度。若真实分布为
非负性
证明用 Jensen 不等式。对数函数是凹函数,因此
移项即得
非负性有大量直接应用。上一节用它证明了
不对称性与三角不等式
不对称的根源是求和时按
KL 散度也不满足三角不等式:
是非负但不一定有界的量
两个分布支撑完全错开时 KL 散度为无穷。取
在有限支撑且两个分布都取正值的条件下,散度有界。以比特为单位,
两个常见分布的 KL 散度
两个正态分布。设
这一公式在变分推断中经常出现:用高斯近似后验时,KL 项可以直接写出显式表达(2.12 节的 ELBO 中包含这一项)。
两个伯努利分布。设
这是逻辑回归损失函数的基本单元(见交叉熵部分)。
import numpy as np
def kl(p, q, eps=1e-12):
"""KL 散度(比特)"""
p = np.asarray(p, dtype=float)
q = np.asarray(q, dtype=float) + eps
mask = p > 0
return float(np.sum(p[mask] * np.log2(p[mask] / q[mask])))
p = np.array([0.9, 0.1])
q = np.array([0.5, 0.5])
print(f"D(p||q) = {kl(p, q):.4f} 比特")
print(f"D(q||p) = {kl(q, p):.4f} 比特 两者不相等,说明 KL 不对称")
# 两个正态分布的 KL(自然对数单位)
def kl_normal(mu1, s1, mu2, s2):
return np.log(s2 / s1) + (s1 ** 2 + (mu1 - mu2) ** 2) / (2 * s2 ** 2) - 0.5
print(f"\n正态 KL(同方差,均值差 1):{kl_normal(0, 1, 1, 1):.4f} 奈特")
print(f"正态 KL(同均值,方差 4 倍):{kl_normal(0, 1, 0, 2):.4f} 奈特")
print(f"正态 KL(自身):{kl_normal(0, 1, 0, 1):.4f} 奈特")4.2.2 交叉熵
交叉熵(cross entropy)定义为
它与 KL 散度、熵的关系为
当
以
即真实类别的预测概率的负对数。这一形式解释了交叉熵损失的直观:正确类别的预测概率越接近
交叉熵也是语言模型的训练目标。给定前缀
困惑度(perplexity)是这一损失的指数形式
import numpy as np
def cross_entropy(p, q, eps=1e-12):
"""交叉熵(比特)"""
p = np.asarray(p, dtype=float)
q = np.asarray(q, dtype=float) + eps
mask = p > 0
return float(-np.sum(p[mask] * np.log2(q[mask])))
def entropy(p):
p = np.asarray(p, dtype=float)
p = p[p > 0]
return float(-np.sum(p * np.log2(p)))
p = np.array([0.0, 1.0, 0.0]) # 独热标签
for pred in [[0.1, 0.7, 0.2], [0.2, 0.5, 0.3], [0.3, 0.4, 0.3]]:
q = np.array(pred)
print(f"预测分布 {pred}:交叉熵 = {cross_entropy(p, q):.4f} 比特")
# 正确类别概率越低,交叉熵越大
# 非独热情形:H(p, q) = H(p) + KL(p||q)
p_soft = np.array([0.1, 0.7, 0.2])
q_soft = np.array([0.2, 0.6, 0.2])
print(f"\nH(p) = {entropy(p_soft):.4f},H(p,q) = {cross_entropy(p_soft, q_soft):.4f}")
print(f"验证 H(p,q) - H(p) = {cross_entropy(p_soft, q_soft) - entropy(p_soft):.4f}")4.2.3 JS 散度
JS 散度(Jensen-Shannon divergence)把 KL 散度对称化并限制取值:
其中
对称性:
有界性:以比特为单位,
有定义的平方根:
JS 散度与 JS 距离(
import numpy as np
def kl(p, q, eps=1e-12):
p = np.asarray(p, dtype=float)
q = np.asarray(q, dtype=float) + eps
mask = p > 0
return float(np.sum(p[mask] * np.log2(p[mask] / q[mask])))
def js(p, q):
p = np.asarray(p, dtype=float)
q = np.asarray(q, dtype=float)
m = 0.5 * (p + q)
return 0.5 * kl(p, m) + 0.5 * kl(q, m)
p = np.array([0.9, 0.1])
q = np.array([0.5, 0.5])
print(f"D_JS(p||q) = {js(p, q):.4f},D_JS(q||p) = {js(q, p):.4f} 对称")
print(f"支撑完全不重叠时:D_JS = {js([1.0, 0.0], [0.0, 1.0]):.4f} 比特(上界 1)")
print(f"KL 在同样情形下为无穷:D_KL = {kl([1.0, 0.0], [0.0, 1.0], eps=0.0):.2e}(数值溢出前的替代值)")
# 说明 JS 有界,KL 发散4.2.4 f 散度
定义
f 散度(f-divergence)用凸函数统一了一大批散度。设
由
常见散度在 f 散度框架中的位置
不同的
| 名称 | 生成函数 | 备注 |
|---|---|---|
| KL 散度 | 不对称 | |
| 反向 KL | 与上者互为反向 | |
| 总变差 | 对称、有界 | |
| 卡方散度 | 对上尾敏感 | |
| Hellinger 距离平方 | 有界、对称 | |
| 见 4.2.5 节 | 包含 KL 的两个方向为极限 |
表格的意义在于把散度设计转化为 Selecting
变分表示
f 散度有一个由凸共轭给出的变分表示,它是互信息估计与对抗式训练的理论依据。由 Fenchel 对偶(3.2 节的共轭函数),
其中
import numpy as np
def f_divergence(p, q, f):
"""按定义计算 f 散度"""
p = np.asarray(p, dtype=float)
q = np.asarray(q, dtype=float)
mask = (q > 0)
u = np.where(mask, p / np.where(mask, q, 1.0), 0.0)
return float(np.sum(q[mask] * f(u[mask])))
f_kl = lambda u: np.where(u > 0, u * np.log(u), 0.0)
f_tv = lambda u: 0.5 * np.abs(u - 1)
f_chi2 = lambda u: (u - 1) ** 2
f_hell = lambda u: (np.sqrt(u) - 1) ** 2
p = np.array([0.7, 0.2, 0.1])
q = np.array([0.5, 0.3, 0.2])
print(f"KL(p||q) = {f_divergence(p, q, f_kl):.4f}")
print(f"总变差 = {f_divergence(p, q, f_tv):.4f}")
print(f"卡方散度 = {f_divergence(p, q, f_chi2):.4f}")
print(f"Hellinger 平方 = {f_divergence(p, q, f_hell):.4f}")
# 各散度数值不同但符号一致,且都在 p = q 时为零4.2.5 Rényi 散度与 Tsallis 散度
Rényi 散度
Rényi 散度(Rényi divergence)用一个阶参数
阶参数的作用决定了对分布哪一部分更敏感。
第二条极限称为最大散度(max-divergence),在差分隐私的定义中直接使用(4.8 节)。当
Tsallis 散度
Tsallis 散度(Tsallis divergence)用
它与 Rényi 散度的关系是单调变换:
import numpy as np
def renyi(p, q, alpha, base=np.e):
p = np.asarray(p, dtype=float)
q = np.asarray(q, dtype=float)
if abs(alpha - 1) < 1e-12:
mask = p > 0
return float(np.sum(p[mask] * np.log(p[mask] / q[mask])) / np.log(base))
s = np.sum(np.where(p > 0, p ** alpha * q ** (1 - alpha), 0.0))
return float(np.log(s) / ((alpha - 1) * np.log(base)))
p = np.array([0.8, 0.15, 0.05])
q = np.array([0.6, 0.3, 0.1])
for a in [0.5, 1.0, 2.0, 5.0, 20.0]:
print(f"alpha = {a:5.1f}:Rényi 散度 = {renyi(p, q, a, base=2):.4f} 比特")
print(f"最大散度 log2 max(p/q) = {np.log2(np.max(p / q)):.4f} 比特")
# alpha 增大时散度单调上升,趋近最大散度4.2.6 Bregman 散度
定义
Bregman 散度(Bregman divergence)由可微凸函数
几何含义是
Bregman 散度在参数空间而非分布空间上定义,因此它同时适用于参数估计与矩阵分解。常见的实例:
| 生成函数 | 散度 | 用途 |
|---|---|---|
| 欧氏距离平方 | 最小二乘 | |
| 广义 KL 散度 | 非负矩阵分解、计数数据的拟合 | |
| Itakura-Saito 散度 | 谱分解、音频处理 | |
| 指数族的 KL 形式 | 广义线性模型 |
与凸共轭、镜像下降的关系
Bregman 散度与凸共轭函数通过对偶配对联系:
import numpy as np
def bregman(x, y, phi, grad_phi):
x = np.asarray(x, dtype=float)
y = np.asarray(y, dtype=float)
return float(phi(x) - phi(y) - grad_phi(y) @ (x - y))
phi_euclid = lambda x: 0.5 * np.sum(x ** 2)
grad_euclid = lambda x: x
phi_ent = lambda x: np.sum(np.where(x > 0, x * np.log(np.where(x > 0, x, 1.0)), 0.0))
grad_ent = lambda x: np.log(np.where(x > 0, x, 1.0))
x = np.array([0.6, 0.4])
y = np.array([0.5, 0.5])
print(f"欧氏生成函数的 Bregman 散度 = {bregman(x, y, phi_euclid, grad_euclid):.4f}")
print(f"负熵生成函数的 Bregman 散度 = {bregman(x, y, phi_ent, grad_ent):.4f}")
# 后者与 KL 散度同源,数值上等于 KL(x||y)(以奈特为单位)4.2.7 总变差距离与 Hellinger 距离
总变差距离
总变差距离(total variation distance)定义为两个分布在任意事件上概率差的上确界:
右端的等式对离散分布成立。总变差是对称的、取值在
这一结论说明总变差与可区分性完全对应:
总变差与 KL 散度之间由 Pinsker 不等式联系:
以奈特为单位。这条不等式说明了为什么用 KL 衡量差异时会出现看似矛盾的结论:KL 可以很大(甚至无穷)而总变差仍然有界。反过来,总变差小意味着 KL 小(在一定条件下),这使它成为更强的分布接近判据。
Hellinger 距离
Hellinger 距离(Hellinger distance)定义为
其中
在统计中,Hellinger 距离的平方是局部渐近正态理论中的标准工具:两个接近的分布之间的 KL 散度与 Hellinger 距离平方在局部有相同的二阶主项,而 Hellinger 距离的估计更稳定(对稀疏计数不敏感)。
4.2.8 Wasserstein 距离与最大均值差异
Wasserstein 距离
前面所有散度都建立在逐点比较概率值的基础上,这使它们对支撑的几何位置不敏感。举一个极端例子:取
Wasserstein 距离(Wasserstein distance)利用取值空间上的度量解决这一问题。一阶情形(也称推土机距离)定义为
其中
即两个分位数函数之差的积分。上例中
Wasserstein 距离的关键性质有三条。第一,它利用空间度量,因此能反映分布位置与形状的差异,而不仅是有无重叠。第二,它弱化了对支撑的要求:支撑错开时 Wasserstein 距离仍然有界,且当两个分布都连续时它是可微的(在一定条件下),这使梯度流有意义。第三,Kantorovich 对偶给出另一个表达:
上确界在 1-Lipschitz 函数上取。这一形式只需要期望,与 f 散度的变分表示结构相同,是 Wasserstein GAN 用判别器(限制为 Lipschitz 函数)估计距离的依据。代价是计算量:一般情形下的精确计算是线性规划问题,高维时依赖熵正则化的近似算法(Sinkhorn 算法)。
最大均值差异
最大均值差异(maximum mean discrepancy,MMD)用核函数把分布映射到再生核希尔伯特空间(RKHS),再比较两者的均值:
其中
三项都是核函数的期望,可以由样本平均直接估计,不需要估计密度。当核是特征核(characteristic kernel,如高斯核)时,
MMD 的用途集中在两类任务。作为两样本检验统计量:给定两组样本,判断它们是否来自同一分布,MMD 的样本估计有已知的零分布,检验功效通常优于基于总变差的方法。作为训练目标:在生成模型中用 MMD 衡量生成分布与真实分布的差异,训练过程不需要对抗博弈,稳定性好。它的性质介于逐点散度与 Wasserstein 距离之间:利用了核引入的几何结构,计算量与样本量成平方关系(可用无偏估计与随机特征近似降低)。
import numpy as np
# 一维 Wasserstein 距离的闭式计算:分位数函数之差的积分
def wasserstein1_1d(x, y, n_grid=2000):
grid = np.linspace(0, 1, n_grid)
qx = np.quantile(x, grid)
qy = np.quantile(y, grid)
return float(np.trapezoid(np.abs(qx - qy), grid))
rng = np.random.default_rng(5)
a = rng.normal(0, 1, size=20_000)
b_close = rng.normal(0.01, 1, size=20_000)
b_far = rng.normal(100, 1, size=20_000)
print(f"W1(p, q_接近) = {wasserstein1_1d(a, b_close):.4f}")
print(f"W1(p, q_远离) = {wasserstein1_1d(a, b_far):.4f}")
# KL 与总变差对两者给出相同结论,Wasserstein 能区分远近
# MMD 的样本估计(高斯核)
def mmd2(x, y, sigma=1.0):
def k(u, v):
return np.exp(-((u[:, None] - v[None, :]) ** 2) / (2 * sigma ** 2))
return float(k(x, x).mean() + k(y, y).mean() - 2 * k(x, y).mean())
xs = rng.normal(0, 1, size=400)
ys = rng.normal(0.3, 1, size=400)
zs = rng.normal(0, 1, size=400)
print(f"\nMMD²(同分布) = {mmd2(xs, zs):.6f}")
print(f"MMD²(均值差 0.3)= {mmd2(xs, ys):.6f}")4.2.9 如何选择度量
选择度量需要先明确任务要求,再对照度量的性质。下表给出常见的对照维度。
| 性质 | KL | JS | 总变差 | Hellinger | Wasserstein | MMD |
|---|---|---|---|---|---|---|
| 对称 | 否 | 是 | 是 | 是 | 是 | 是 |
| 有界 | 否 | 是 | 是 | 是 | 否 | 否 |
| 满足三角不等式 | 否 | 平方根满足 | 是 | 是 | 是 | 是 |
| 支撑错开时有限 | 否 | 是 | 是 | 是 | 是 | 是 |
| 利用取值几何结构 | 否 | 否 | 否 | 否 | 是 | 是(核) |
| 无需密度估计即可从样本估计 | 否 | 否 | 是 | 部分 | 是(有近似) | 是 |
三条实践建议。第一,训练生成模型时优先考虑能提供有效梯度的度量:支撑不重叠时 KL 与 JS 的梯度消失,Wasserstein 与 MMD 仍有信号。第二,做分布检验时优先考虑能从样本直接估计的度量:总变差、MMD 有成熟的检验统计量与零分布,KL 需要先做密度估计,在高维下不可靠。第三,需要解释性时回到 KL:它有明确的编码代价解释,而 Wasserstein 与 MMD 的数值尺度依赖空间度量与核的选择。
KL 散度还有一个特殊的地位:它是唯一使最大似然估计与最小散度等价的选择,因为在
4.2.10 本节小结
从 KL 出发的度量家族
本节以 KL 散度为中心展开了一族分布差异度量。KL 散度由近似带来的额外编码长度定义,非负性来自 Jensen 不等式,不对称与不满足三角不等式使它属于散度而非距离,支撑错开时发散是它在生成模型中的主要弱点。交叉熵与 KL 散度只差一个与待优化分布无关的常数项,因此在固定真实分布时两者等价,这是分类损失与语言模型训练目标的设计依据。JS 散度通过对平均分布取双向 KL 得到对称且有界的版本,其平方根满足三角不等式。f 散度用凸生成函数统一了 KL、总变差、卡方与 Hellinger,并由凸共轭给出变分表示,这一表示是互信息估计与对抗式训练的起点。Rényi 与 Tsallis 散度以阶参数串联 KL 的两个方向与最大散度,Bregman 散度把散度定义在参数空间上并与镜像下降算法对应。总变差距离与假设检验的错误率直接对应,Hellinger 距离在局部渐近分析中更稳定;Wasserstein 距离与最大均值差异利用取值空间上的度量与核结构,在支撑错开时仍提供有效梯度,代价是计算量与超参数选择。
散度给出了分布之间距离的概念,但它还没有回答一个自然的问题:在由参数化的分布构成的集合上,这些散度如何随参数变化。把参数空间与散度结合,就得到信息几何的框架:KL 散度的局部二阶展开给出一个度量张量,这个张量正是第 2.9 节出现过的 Fisher 信息矩阵。下一节讨论最大熵原理、指数族与信息几何,把统计模型组织成一个带度量的空间,并给出自然梯度与变分推断的几何解释。
练习题
第 1 题 概念推导
证明 KL 散度的非负性,并说明等号成立的条件;再用该结论证明互信息的非负性。
参考答案
非负性:由 Jensen 不等式,对凹函数
因此
等号条件:Jensen 不等式中等号成立当且仅当
互信息非负:由定义
把它写成 KL 散度的形式后,直接应用上面的结论:非负性成立,等号当且仅当
第 2 题 计算推理
某生成模型用高斯分布
参考答案
表达式:把
数值(以奈特为单位):
惩罚形式不同的原因:均值误差以
更重要的是方向的不对称:
第 3 题 代码验证
比较五种散度在两个分布逐渐分开时的变化:用一维高斯混合构造
参考答案
import numpy as np
from scipy import stats
def kl_gauss(mu1, s1, mu2, s2):
return np.log(s2 / s1) + (s1 ** 2 + (mu1 - mu2) ** 2) / (2 * s2 ** 2) - 0.5
def js_gauss(mu1, s1, mu2, s2, n=200_001, lim=30):
x = np.linspace(-lim, lim, n)
p = stats.norm.pdf(x, mu1, s1)
q = stats.norm.pdf(x, mu2, s2)
m = 0.5 * (p + q)
dx = x[1] - x[0]
kl_pm = np.sum(np.where(p > 0, p * np.log(p / np.maximum(m, 1e-300)), 0)) * dx
kl_qm = np.sum(np.where(q > 0, q * np.log(q / np.maximum(m, 1e-300)), 0)) * dx
return 0.5 * (kl_pm + kl_qm)
def tv_gauss(mu1, s1, mu2, s2, n=200_001, lim=30):
x = np.linspace(-lim, lim, n)
p = stats.norm.pdf(x, mu1, s1)
q = stats.norm.pdf(x, mu2, s2)
return 0.5 * np.sum(np.abs(p - q)) * (x[1] - x[0])
def hellinger_gauss(mu1, s1, mu2, s2, n=200_001, lim=30):
x = np.linspace(-lim, lim, n)
p = stats.norm.pdf(x, mu1, s1)
q = stats.norm.pdf(x, mu2, s2)
dx = x[1] - x[0]
return np.sqrt(max(0.0, 1 - np.sum(np.sqrt(p * q)) * dx))
print(f"{'Δμ':>5} {'KL':>8} {'JS':>8} {'TV':>8} {'Hell':>8} {'W2(近似)':>10}")
for d in [0.0, 0.5, 1.0, 2.0, 5.0, 10.0]:
kl = kl_gauss(0, 1, d, 1)
js = js_gauss(0, 1, d, 1)
tv = tv_gauss(0, 1, d, 1)
he = hellinger_gauss(0, 1, d, 1)
print(f"{d:5.1f} {kl:8.3f} {js:8.4f} {tv:8.4f} {he:8.4f} {np.abs(d):10.3f}")
# W2 一维闭式解为 |Δμ|(同方差情形)输出的典型规律是:随着均值差距增大,KL 按
第 4 题 综合应用
某团队要评估两个文本生成模型的输出分布与真实文本分布的差异。他们考虑三种做法:用困惑度(交叉熵)、用 JS 散度、用 MMD。请说明三种做法的对象与假设,指出各自在什么条件下会给出误导性结论,并给出一个组合使用它们的评估方案。
参考答案
三种做法的对象与假设。困惑度计算模型在真实文本上的平均负对数似然,度量的是模型对真实数据的预测能力,只需要模型能给出似然,不需要估计分布本身。JS 散度要求把两个分布都显式表示出来,在词表大小为
各自的误导条件。困惑度会奖励那些覆盖全部真实样本但分配不匀的模型:把所有概率都分给高频模式时,总体困惑度可能不错,但生成样本缺乏多样性,这一现象称为模型崩溃,困惑度对这种失败不敏感。JS 散度在词分布层面比较时,若两个分布的支撑几乎不重叠(生僻词一律不生成),数值会直接饱和到上界,无法反映改进的幅度。MMD 的结果强烈依赖核带宽与表示空间:带宽选得过大时所有样本都像来自同一分布,选得过小时任何差异都被放大,表示空间若无法捕捉语义,MMD 的结论与人类判断不符。
组合方案。分三层评估。第一层用困惑度判断模型是否学到了真实数据的统计规律,同时报告生成样本的 n-gram 多样性指标(如去重后的 n-gram 比例)以检查是否发生模型崩溃。第二层用分布层面的度量,在句向量空间上同时计算 MMD 与 Wasserstein 距离,以多个核带宽与多个随机投影重复计算,报告数值的分布而非单点值。第三层用人或独立模型的判断,对生成样本与真实样本做区分实验(请标注者判断哪些是生成的),得到人类可分辨的比例作为最终指标。三层结合的原因是它们各自有盲区:困惑度看不出多样性缺失,分布度量受表示与核的选择影响,人类判断代价高且噪声大,交叉验证可以覆盖单一指标的盲区。
常见错误
错误 1 · 在需要对称性的场合使用 KL 散度
原因:KL 散度不对称,
解决:需要对称时改用 JS 散度、总变差或 Hellinger 距离,三者都满足三角不等式。必须使用 KL 时明确写出方向并说明选择该方向的原因,例如变分推断用
错误 2 · 在支撑可能不重叠的场景直接用 KL 作为训练损失
原因:支撑错开时 KL 散度发散,梯度失去意义。生成模型早期阶段生成分布与真实分布几乎不重叠,此时 KL 与 JS 给不出有效梯度,训练停滞而损失曲线看起来只是平缓。
解决:改用 Wasserstein 距离或 MMD,它们在支撑错开时仍提供有意义的梯度;或对分布做平滑处理并在训练早期使用,随着分布接近再切换回 KL 与交叉熵。监控手段是同时记录总变差或 MMD 作为辅助指标,判断重叠程度。
错误 3 · 把总变差与 KL 的数值大小直接比较
原因:两个度量的尺度不同。KL 无上界,可以取到几十甚至无穷;总变差始终在
解决:比较不同度量的数值时先换算到同一尺度,或直接使用不等式给出的界。报告结果时说明所用度量与单位(比特或奈特),避免读者按其他度量的尺度理解数值。
错误 4 · 用固定核带宽的 MMD 比较差异悬殊的分布
原因:MMD 的核带宽决定了它能分辨的尺度。带宽固定时,样本之间距离远大于带宽的情形下核值全部接近零,MMD 无法区分不同的差异;距离远小于带宽时核值全部接近 1,差异被抹平。用单一带宽得到两个分布没有差异的结论可能是带宽选择的结果。
解决:在多个带宽下计算 MMD,取其中最大的(或报告各带宽的完整曲线)。使用多核 MMD(把多个带宽的高斯核求和作为核函数)可以避免手动选择,代价是计算量增加。同时报告所选的表示空间,说明语义相似度是否被核捕捉。