我从一个很具体的困扰开始。模型对一张从没见过的图片给出的 softmax 最大值是 0.99,可我没有任何依据说它“99% 属于猫”。softmax 只做了一件事:把 logits 归一化成和为 1 的数。它回答的问题是“在已经假定的这几个类里,哪个最像”,而不是“这个样本是否属于我见过的任何一类”。
要判断一个样本有没有越界,我需要知道的不是分类器给它打了多少分,而是已知类别的数据在空间里占据了多少概率质量、这个样本离那片质量有多远。前者是密度,后者是距离,两者都是分布的几何性质,而不是分类器的性质。
先算一道运输题。
甲矿有 3 吨煤,乙矿有 1 吨;A 厂要 2 吨,B 厂要 2 吨。运价是:甲到 A 每吨 1 块,甲到 B 每吨 2 块,乙到 A 每吨 3 块,乙到 B 每吨 1 块。怎么运最省?
设甲运往 A 的吨数是 x。甲的 3 吨要分完,所以甲到 B 是 3−x;A 要 2 吨,所以乙到 A 是 2−x;乙只有 1 吨,所以乙到 B 是 1−(2−x)=x−1。四个数都得非负,于是 1≤x≤2。总运费
x⋅1+(3−x)⋅2+(2−x)⋅3+(x−1)⋅1=11−3x.x 越大越省,取 x=2,总运费 5 块:甲到 A 运 2 吨,甲到 B 运 1 吨,乙到 B 运 1 吨。
这张“每个产地往每个销地运多少”的表,就是运输方案。Monge 在 1781 年问的是一般情形:给定一堆土 μ 和一个坑 ν,怎么搬最省。
他的写法是找一个映射 T:X→Y,要求“搬完之后每个地方刚好装满”,也就是推前测度 T#μ=ν,即对任意可测集 B,
(T#μ)(B)=μ(T−1(B))=ν(B),代价是 ∫c(x,T(x))dμ(x)。于是 Monge 问题就是
Tinf ∫Xc(x,T(x))dμ(x)s.t.T#μ=ν.这个提法有一个硬伤:T 必须是确定性的,一个产地只能有一条固定去向。如果 μ 在某个点上有原子,而 ν 在那里要求把质量分到两个地方,就无解。举个最小的例子:全部质量集中在甲一个点上,μ=δ0;而两个厂各要一半,ν=21δ1+21δ2。T(0) 必须同时等于 1 和 2,函数做不到。
可这件事在现实中天天发生:一辆车分两个厂送货而已。Kantorovich 在 1940 年代的办法是把映射换成联合分布。令
Π(μ,ν)={π∈P(X×Y) : (projX)#π=μ, (projY)#π=ν},π(x,y) 读作“从 x 搬到 y 的那部分质量”,于是
Wc(μ,ν)=π∈Π(μ,ν)inf∫X×Yc(x,y)dπ(x,y).允许分裂之后一定有解,而且原问题变成一个线性规划:π 就是那张运输表。
取 c(x,y)=d(x,y)p(d 是度量),则
Wp(μ,ν)=(π∈Π(μ,ν)inf∫d(x,y)pdπ)1/p是 Pp(X) 上的一个真度量。这一点比看起来重要,因为 KL 不是。取 μ=δx, ν=δy,Wp(δx,δy)=d(x,y) 是个有限的数,而 KL(δx∥δy)=+∞。支撑不交的时候,KL 要么发散要么给出零梯度,W 却仍然告诉你“隔了多远”。
平移的例子更直白。把 μ 整体挪 ε:Wp 是 ε 量级,而
KL(N(0,1)∥N(ε,1))=2ε2,是二阶的。所以小位移时 KL 的梯度趋近于零,W 的梯度是常数。生成模型里那句“Wasserstein 提供不饱和梯度”,准确的数学内容就是这一行。
顺带说一句,计算机视觉里管它叫 Earth Mover's Distance,数学里叫 Wasserstein 距离,是同一个东西;EMD 通常特指 W1,或者指带整数质量的离散版本。把一张 28×28 的手写数字的灰度值当成质量,W 就是“把这张画改写成那张画的最小工作量”,我最初就是靠这个画面理解它的。
回到那道运输题。我算出最低运费是 5 块。如果有人说他能做到 4 块,我怎么证明他做不到?
不去枚举所有运输表。我给每个矿定一个“提货加价” u,每个厂定一个“到货减价” v,只要求一条规矩:对任意一条路线,两个价加起来不超过运费,
ui+vj≤cij.那么任何一张运单的总价都满足
ij∑πijcij≥ij∑πij(ui+vj)=i∑ui(j∑πij)+j∑vj(i∑πij)=i∑aiui+j∑bjvj.最后这个数只跟 u,v 有关,跟运单无关;而中间那步把 π 的边缘和换成了产量 ai、需求 bj。所以只要我找到一组 u,v,使这个和等于 5,我就证明了运费不可能低于 5 块。
试一试:取 u=(0,−1),v=(1,2)。四条路线逐一检查:甲到 A 是 0+1=1≤1,甲到 B 是 0+2=2≤2,乙到 A 是 −1+1=0≤3,乙到 B 是 −1+2=1≤1,全部成立。而 3⋅0+1⋅(−1)+2⋅1+2⋅2=5。证书找到了。
这就是对偶的思想:不去找运单,而是找一张“价格表”,让价格表卡住运费的下界。最优的价格表能卡到最紧,那个值就等于最低运费。离散情形下,这件事可以写成拉格朗日形式,把两组等式约束配乘子:
L(π,φ,ψ)=ij∑πijCij+i∑φi(ai−j∑πij)+j∑ψj(bj−i∑πij)=i∑aiφi+j∑bjψj+ij∑πij(Cij−φi−ψj).对 π≥0 取下确界:只要有一对 (i,j) 使 Cij−φi−ψj<0,令 πij→∞ 就得到 −∞;否则下确界在 π=0 处取到。于是对偶问题就是
φ,ψmax i∑aiφi+j∑bjψjs.t.φi+ψj≤Cij,正好是上面那张价格表。线性规划强对偶成立,所以两个值相等——这保证了“最优证书”一定存在,而且恰好卡紧。
连续情形把求和换成积分:
Wc(μ,ν)=sup{∫φdμ+∫ψdν : φ(x)+ψ(y)≤c(x,y)}.取 c=d。约束 φ(x)+ψ(y)≤d(x,y) 允许我取 ψ=−φ,此时它变成 φ(x)−φ(y)≤d(x,y),也就是 φ 是 1-Lipschitz 的。所以
W1(μ,ν)=∥φ∥Lip≤1sup∫φd(μ−ν).这个式子的分量很重:左边是关于分布的优化问题,右边是关于函数的优化问题,而函数可以用神经网络参数化。WGAN 干的就是这件事,只差把 Lipschitz 约束用 weight clipping 或 gradient penalty 近似实现。
二次代价 c=21∥x−y∥2 时还有一个 Brenier 定理:若 μ 关于 Lebesgue 测度绝对连续,最优的 π 由映射 T=∇u 给出,其中 u 是凸函数。换句话说,最优搬运方案是某个凸势函数的梯度,是一个“单调”的变换。这句话是后半段所有流模型的伏笔:如果我要把一个分布搬到另一个分布,最优的那个可逆映射长得像 ∇u。
A 公司的薪资在 0 到 1 万之间均匀分布,B 公司在 0 到 2 万之间均匀分布。一个人从 A 跳到 B,平均涨多少?
“最省力”的搬法是按百分位对齐:A 的第 30 百分位是 0.3 万,B 的第 30 百分位是 0.6 万,所以 A 里处在 30 分位的那个人涨 0.3 万。一般地,分位 t 的人从 t 万变成 2t 万,涨幅是 t 万,平均
∫01tdt=21 万.这里可以直接用 2t−t 而不是 ∣2t−t∣,因为所有人都在往同一个方向涨。而这个“平均涨幅”正是 W1。
如果反过来,A 是 U(0,2)、B 是 U(0,1),那就是平均降 0.5 万,W1 仍然是 0.5——它量的是“搬了多少”,不管涨还是跌。
一般地,一维的 Wp 有闭式解:
Wpp(μ,ν)=∫01Fμ−1(t)−Fν−1(t)pdt,也就是把两条分位数曲线逐点相减再积分。p=1 时有更漂亮的形式。用上一节的对偶,对绝对连续的 φ(∣φ′∣≤1)分部积分,
∫φd(μ−ν)=∫φ(x)(Fμ′(x)−Fν′(x))dx=−∫φ′(x)(Fμ(x)−Fν(x))dx,绝对值不超过 ∫∣Fμ−Fν∣dx;取 φ′=−sign(Fμ−Fν) 时等号成立。于是
W1(μ,ν)=∫RFμ(x)−Fν(x)dx.两条 CDF 曲线之间的面积,就是搬运的总量。拿刚才的薪资例验一下:在 [0,1] 上 F(x)=x、G(x)=x/2,差是 x/2,积出 41;在 [1,2] 上 F(x)=1,差是 1−x/2,也积出 41。合计 21,和分位数算法的结果一致。
一维之所以这么简单,是因为凸代价下最优耦合是“单调”的:不会出现 x1<x2 却 T(x1)>T(x2),否则交换一下就更省。所以 T=Fν−1∘Fμ 就是答案——按排名对齐。多维没有这种排序,所有困难都从这里开始。
高斯之间有一个著名的闭式解:
W22(N(m1,Σ1),N(m2,Σ2))=∥m1−m2∥2+tr(Σ1+Σ2−2(Σ11/2Σ2Σ11/2)1/2).一维退化为 (m1−m2)2+(σ1−σ2)2,验算一下:tr(σ12+σ22−2∣σ1σ2∣)=(σ1−σ2)2,对得上。取 N(0,1) 与 N(0,4),得 W2=1,正好是标准差之差;而最优映射是 x↦2x,位移的均方根也正好是 1。两个数在这里是同一个数。
最优映射还是仿射的:T(x)=m2+A(x−m1),其中
A=Σ1−1/2(Σ11/2Σ2Σ11/2)1/2Σ1−1/2.写成操作就是“先白化再上色”,风格迁移里的 AdaIN 做的正是这个(对角版本)。所以“高斯之间的最优传输”这件事,工程界早就在做了,只是没有这么叫。
高斯集合配上 W2 构成一个黎曼流形(Bures–Wasserstein 空间),两点间的测地线就是位移插值 μt=((1−t)id+tT)#μ。这意味着我可以在分布空间里插值和求平均。我在写 Fréchet 均值那篇时说过,在没有向量结构的空间里“平均”要重新定义;W2 空间是最典型的例子——两个高斯的中点要沿测地线走一半,不是把参数取平均。
W 定义了“是什么”,但没告诉我“怎么算”。
n=104 个样本对 104 个样本,代价矩阵就是 108 个数,float32 存下来 400 MB,还没开始迭代。我最早在自己机器上试 OT,把 n 开到 5000 就被内存劝退了。
离散 OT 是线性规划,实践上是 O(n3) 量级的算法。更麻烦的是解落在多面体的顶点上,π 很稀疏,而 W 作为代价矩阵的函数是分段线性的,梯度分段常数、在切换点跳变。这种“硬”信号在优化里很难用。
Cuturi 在 2013 年的做法是加熵正则:
π∈Π(μ,ν)min ⟨C,π⟩+εij∑πijlogπij.熵项把解从顶点“推”到内部,变成严格正的光滑解。用拉格朗日乘子可以解出
πij=uiKijvj,Kij=exp(−Cij/ε),u,v 由边缘约束定出,交替更新 u←a/(Kv)、v←b/(K⊤u),每次都是矩阵—向量乘法。这就是 Sinkhorn 迭代。它的意义不只是快,而是可微、可并到 GPU 上,于是能塞进神经网络当一层用。
ε 可以读作一个旋钮。取三个点搬到三个点:ε 很大时,K 接近全 1 矩阵,每个点都往每处送一点,解是稠密的、模糊的;ε→0 时 K 接近单位矩阵,解退化成“就近硬匹配”,也就是原始 OT。中间是连续插值。
代价是 ε>0 时它不再是度量。最直接的一点:把 π=diag(a) 代入,Wε(μ,μ)=ε∑iailogai=0。所以工程上常用的 Sinkhorn 散度要先去偏:
Sε(μ,ν)=OTε(μ,ν)−21OTε(μ,μ)−21OTε(ν,ν).去偏之后才非负、才在 μ=ν 处为零。
还有一个更根本的代价,来自样本。经验分布 μn 到真分布 μ 的收敛速度,在 d 维空间里大致是
EWp(μn,μ) ≲ n−1/d(d>2p).指数太糟糕了。d=100 时误差按 n−0.01 衰减,想把误差减半,样本量要乘 2100。所以“直接在高维空间算 Wasserstein”在绝大多数真实问题上不可行。
三条出路我都用过:把数据先降到低维再算;用 sliced Wasserstein,把分布投影到随机一维方向上算 W,再对方向平均(一维的收敛是 n−1/2,一下就正常了);或者用低秩分解把代价矩阵近似成低秩。共同点是不要在原始高维空间里做全秩的 OT。
我拿两个模型对同一张图跑一遍,输出分别是 (0.90,0.10) 和 (0.99,0.01)。另一张图上,两个模型的输出是 (0.50,0.50) 和 (0.59,0.41)。
两组变化的欧氏距离都是 0.09。但我的直觉说它们不是一回事:前者是从“犹豫”变成“笃定”,后者只是从不偏不倚稍微偏了一点。
这种直觉能不能写成数?能。把 Bernoulli 分布按 Fisher–Rao 距离量一下:(0.5,0.59) 是 0.18,(0.9,0.99) 是 0.44,后者是前者的两倍半。同样的坐标变化,在概率接近 0 或 1 的地方要走更远的路——那里是单纯形的“边缘”,流形在那边被拉长了。
那么这把尺子是怎么来的?
模型的输出住在单纯形
ΔK−1={p∈RK: pi≥0, i∑pi=1}里。问题在于这个空间有边界:越靠近顶点,同样的坐标变化对应的“实质变化”越大。欧氏距离看不见这件事。
Rao 在 1945 年的想法是:把参数化的分布族 {pθ} 本身看成一个流形,在上面装一把由数据决定的尺子。这把尺子就是 Fisher 信息矩阵
gij(θ)=Epθ[∂ilogpθ⋅∂jlogpθ]=−Epθ[∂i∂jlogpθ],两个表达式的相等用到了 E[∂ilogp]=0,因为对 θ 求导再积分,∫∂ipdx=∂i∫pdx=0。
为什么是它?有三个我觉得足够有说服力的理由。
第一,它是 KL 的二阶展开。把 logpθ+dθ 在 θ 处展开到二阶,一阶项的期望为零,剩下
KL(pθ∥pθ+dθ)=−21E[∂i∂jlogpθ]dθidθj+O(∥dθ∥3)=21gijdθidθj+O(∥dθ∥3).所以 KL 虽然整体上不对称,局部却退化成一个二次型,二次型的矩阵就是 Fisher。反过来说,任何“局部像 KL”的距离都会给出同一个度量。
第二,Chentsov 定理说:单纯形上的黎曼度量,若在充分统计量(更准确地说,Markov 态射)下保持不变,则差一个常数因子必为 Fisher–Rao。换句话说,这不是我随手挑的度量,而是在“只依赖分布、不依赖参数化”这个要求下唯一的选择。
第三,对指数族它恰好是势函数的 Hessian,下一节说。
把 Bernoulli 族算一遍。p(x∣θ)=θx(1−θ)1−x,
g(θ)=θ(1−θ)1.弧长 ds=dθ/θ(1−θ),积分得
d(θ1,θ2)=2arcsinθ1−arcsinθ2.θ=0.5 与 θ=0.9 的距离是 2(1.2490−0.7854)≈0.927。而 θ→0 与 θ→1 的距离是 π,有限。这一点我很喜欢:从“几乎确定是 0”走到“几乎确定是 1”,不管两端有多极端,路径长度都是 π;而 KL(0.999∥0.001)≈6.9 并且随极端程度一起发散。几何距离和信息量在这里分道扬镳。
那个 2arcsinθ 不是巧合。对一般的离散分布,
dFR(p,q)=2arccos(i∑piqi),而映射 p↦u=2p 把单纯形嵌入到 RK 中半径为 2 的球面上(因为 ∑i4pi=4),Fisher–Rao 距离正好是球面上的大圆距离。这个嵌入叫 Hellinger 嵌入,∑ipiqi 叫 Bhattacharyya 系数。
有了球面,测地线就清楚了。两点之间的大圆弧写回单纯形是
pt=Zt((1−t)p+tq)2,Zt=i∑((1−t)pi+tqi)2.这不是线性插值:概率质量走的是一条弯的路。如果我在单纯形上按大圆距离做最近原型分类,两个原型之间的“垂直平分线”是一条大圆,投影回单纯形是弯的;而按线性插值它会是直的。这就是我理解的“非欧氏边界”最干净的来源。
我抛一枚硬币 100 次,60 次正面。这句话里真正有用的信息只有两个数:100 和 60。给定正面概率 θ,正面次数服从二项分布,而样本对 θ 的全部影响都通过“正面次数”这个线性统计量进去——这就是充分统计量。
指数族把这个结构写成一个模板:
p(x∣θ)=h(x)exp(θ⊤T(x)−ψ(θ)).T 是充分统计量,θ 是自然参数,ψ 是对数配分函数,负责把总质量归一化成 1。抛硬币就是 T(x)=x、θ=log1−pp、ψ(θ)=log(1+eθ)。
ψ 的性质很好:∇ψ(θ)=Eθ[T(X)],∇2ψ(θ)=Covθ[T(X)]。第二个等式说明 Fisher 度量就是 ψ 的 Hessian,上一节里“度量由凸函数给出”的说法在这里变成了具体的东西。
令 η=∇ψ(θ) 为期望参数,它与 θ 之间是 Legendre 变换的关系:ψ∗(η)=supθ(θ⊤η−ψ(θ)),且 ∇ψ∗(η)=θ。所以同一个分布有两套坐标,自然参数 θ 和期望参数 η,互为对偶。
现在算两个成员之间的 KL:
KL(pθ∥pθ′)=Eθ[logpθ−logpθ′]=Eθ[(θ−θ′)⊤T]−(ψ(θ)−ψ(θ′))=(θ−θ′)⊤∇ψ(θ)−ψ(θ)+ψ(θ′)=ψ(θ′)−ψ(θ)−∇ψ(θ)⊤(θ′−θ).最后这个式子是凸函数 ψ 在 θ 处的切平面在 θ′ 处高出的那部分。它有名字:Bregman 散度。
拿方差固定为 1 的高斯族验一下。此时 θ=μ,ψ(θ)=θ2/2,手算
KL(N(θ1,1)N(θ2,1))=2(θ1−θ2)2,而 ψ 的 Bregman 散度是 21θ22−21θ12−θ1(θ2−θ1)=21(θ2−θ1)2。同一个数。
所以在这类模型里,KL 不是某种抽象的“信息量”,它就是 Bregman 散度;而它的 Hessian 就是 Fisher 度量。散度和度量是同一个凸函数的两个侧面。这是我写这篇博客最想讲清楚的一件事。
先看一个会让人不舒服的例子。p=(1,0) 是“真相”,q=(0.5,0.5) 是“模型的预测”。
KL(p∥q)=log2≈0.693,KL(q∥p)=+∞.同一个“差”,从左往右量是 0.69,从右往左量是无穷。原因不难想:p 在第二位上放了 0,而 q 在那里放了 0.5,用 p 去看 q,只是多花了 0.69 nat;用 q 去看 p,等于说“我给了一个 p 认为绝不可能的东西分配了概率”,这种错误在 KL 里罚到无穷。
这正是交叉熵写成 KL(y∥q) 而不是反过来的原因:y 是真相,模型 q 不该在真答案上给 0 概率。
再看一个尺度上的例子。Itakura–Saito 散度 DIS(x∥y)=x/y−log(x/y)−1:把音量从 1 减半到 0.5,DIS=2−log2−1=0.307;从 2 减半到 1,DIS 还是 0.307。同样的比例变化,距离一样。而欧氏距离给的是 0.25 和 1,差了四倍——因为欧氏觉得“从 2 到 1 变化更大”,可听感上这明明是同一件事。
这两个例子指向同一件事:距离可以不对称,也可以不按绝对差来量。
一般地,给定凸函数 f 和可微点 y,
Df(x∥y)=f(x)−f(y)−∇f(y)⊤(x−y).几何上,这是 f 的图像在 x 处比 y 处的切平面高出多少。f 凸所以非负,严格凸所以只在 x=y 时为零。它不对称,也不满足三角不等式,所以我不叫它距离,叫散度。
几个我常用的:f(x)=21∥x∥2 给 21∥x−y∥2;f(p)=∑ipilogpi(负熵)给 KL(p∥q);f(p)=−∑ilogpi 给 Itakura–Saito;f(x)=21x⊤Ax 给 Mahalanobis 距离。
它在机器学习里出现的频率比多数人以为的高。交叉熵
CE(y,q)=−i∑yilogqi=KL(y∥q)+H(y)=D−H(y∥q)+H(y),所以训练一个分类器、一个语言模型,最小化交叉熵就是在最小化一个 Bregman 散度;标签固定时 H(y) 是常数,梯度完全来自 D。
Bregman 散度还有一个我很喜欢的性质:它的质心是算术平均。对任意 Bregman 散度,
argcmin i∑Df(xi∥c)=n1i∑xi.求导得到 ∑i∇2f(c)(xi−c)=0,结论就是这一行。所以换散度不会改变“平均”这件事,但会改变“谁离谁近”这件事。
这一点值得展开,因为它关系到分类边界。设两个类原型 c1,c2,最近原型判类就是比较 Df(x∥c1) 与 Df(x∥c2)。把定义代进去,
Df(x∥c1)−Df(x∥c2)=[f(x)−f(c1)−∇f(c1)⊤(x−c1)]−[f(x)−f(c2)−∇f(c2)⊤(x−c2)]=常数−f(c1)+f(c2)+∇f(c1)⊤c1−∇f(c2)⊤c2+(∇f(c2)−∇f(c1))⊤x.f(x) 那一项消掉了,剩下的是 x 的仿射函数。所以边界仍然是一个超平面。
这个结论有点扫兴,但我觉得它比“Bregman 给出弯曲边界”更有用:Bregman 改变的不是假设空间,而是“垂直于谁”——这个超平面垂直于 Hessian 度量下的法向,而不是欧氏法向。换句话说,它换了一把尺子,没有换刀。
具体到二维单纯形(其实就是线段 [0,1])上,两个类原型 0.2 和 0.6,用 KL 判类的分界点在 p≈0.387;欧氏中点是 0.4;而在 logit 坐标里取中点又得到 0.380。三个数,三把尺子,没有哪把是“错”的,取决于你认为什么该被同等对待。
真正弯的边界来自两个地方。一是把比较放在约束集上:单纯形加 Fisher–Rao,就是上一节的大圆。二是把它放在非线性映射之后:如果 q(x)=softmax(Wx),那么 {x:Df(q(x)∥c1)=Df(q(x)∥c2)} 在 q 空间是超平面,在 x 空间是它的原像,一般是一张弯的曲面。我见到的“非欧氏边界”基本都是后者。
Bregman 还给出两个优化工具。一个是镜像下降:
xt+1=argxmin ⟨gt,x⟩+η1Df(x∥xt),直觉是“走一步,但别离原来的位置太远”,而“太远”用 f 来量。取 f=21∥x∥2 就是梯度下降;取 f 为负熵,在单纯形上得到指数梯度/乘法权重更新,更新式是乘性的,天然保持非负。另一个是自然梯度:θt+1=θt−ηG(θ)−1∇L,其中 G 是 Fisher。它是在 Fisher–Rao 度量下做最速下降,而不是在欧氏度量下。对 softmax 回归,自然梯度会消掉 logits 尺度带来的平台期——因为在 Fisher 度量下,那个尺度根本不算“距离”。
手上有五个一维样本:0.9, 1.0, 1.1, 5.0, 5.1。肉眼看出两簇,中间在 3 附近是空的。
现在用核密度估计去拟合,只用高斯核、只改带宽。带宽取 0.1,每个点都是一个尖峰,曲线在两个簇内部剧烈起伏;带宽取 5,曲线被抹平。抹平到什么程度?算一下会发现,x=3 那个空洞处的密度大约是 0.073,而簇心 x=1 处是 0.071——空洞反而比簇心更“密”。因为核太宽,五个点全都够到了中间,而簇心只够到自己人和远处那两个点的尾巴。
这个例子里,带宽就是分辨率。h 太小,方差爆炸;h 太大,两个类之间的空隙被填平,一个明显偏离的样本反而显得很正常。我用 KDE 做异常检测时最常踩的坑就是这个:调 h 其实是在调“我允许多大的类间间隙”。
形式上是
p^h(x)=n1i=1∑nKh(x−xi),Kh(u)=h−dK(u/h).它的偏差和方差可以算出来(记 ∫K=1,∫∥u∥2K(u)du=σK2,∥K∥22=∫K2):
Ep^h(x)−p(x)≈2h2σK2Δp(x),Varp^h(x)≈nhdp(x)∥K∥22.两项一个随 h 增、一个随 h 减,最优带宽 h∗∝n−1/(d+4),此时 MSE∝n−4/(d+4)。
d=1 时是 n−4/5,很不错。d=10 时是 n−2/7,想把误差减半,样本量要乘 23.5≈11。这个数字我建议背下来:每加几个维度,KDE 就从“能用”滑向“不能用”。
但 KDE 在高维还有一层跟带宽无关的麻烦。考虑标准正态 N(0,Id)。众数在原点的密度是 (2π)−d/2;而一个“典型”样本落在半径 d 的球壳上(因为 ∥X∥2/d→1),那里的密度是 (2π)−d/2e−d/2。两者差 ed/2 倍,d=100 时是 e50≈5×1021。
有个很好记的画面:一个 100 维的橙子,果皮比果肉厚得多。球的体积几乎全在表面附近那层薄壳里,维度越高这层壳占的比例越大。所以“最典型的位置”不是圆心,而是那层壳。密度的最大值在圆心,可那里几乎没有质量。
这意味着什么?如果我用“密度低于阈值”判 OOD,而阈值按众数附近校准,那几乎会把所有正常样本都判成异常。这就是典型集悖论。
所以“低密度等于分布外”这个直觉在高维是错的。密度是点态的,回答的是“这个点附近有多挤”;我真正想问的是“这个点离已知类别的概率质量有多远”。后者是分布态的问题,得用前面那些工具。
写采样代码时我总会用到同一招:random() 只能给 U(0,1),可我想要指数分布,于是取
x=−λlog(1−u).这一个式子就是一个标准化流。反过来看,u=1−e−λx 是 x 的 CDF,而密度按变量替换是
px(x)=pu(u)dxdu=1⋅λe−λx,正好是指数分布。我写 Box–Muller 那篇时用的也是这套逻辑:先有均匀分布,再靠一个可逆变换把形状掰成想要的样子。
一般地,设 x=f(z),z∼pz,则
px(x)=pz(f−1(x))det∂x∂f−1,取对数:
logpx(x)=logpz(z)−logdetJf(z).那个 log∣det∣ 项就是“局部的伸缩率”:变换把一小块体积放大了多少,密度就要相应缩小多少。多层复合时 log-det 相加,所以加深网络不增加计算上的困难,只要每层的 Jacobian 行列式好算(比如三角矩阵)。
一维的情形可以推到极致:任意一维分布都能写成逆 CDF。取 z∼U(0,1)、f=F−1,x=f(z) 的分布就是 F,这是精确的,不是近似。取 z∼N(0,1),f=F−1∘Φ 就得到任意一维分布。上面那个指数分布的例子就是 F−1(u)=−log(1−u)/λ。
举个能算的例子。p(x)=21φ(x)+21φ(x−3),两个单位方差高斯,中心相距 3。它的 CDF 是 F(x)=21Φ(x)+21Φ(x−3),流就是 f=F−1∘Φ。两峰之间 x=1.5 处的真实密度是 φ(1.5)≈0.1295;如果错当成单个高斯(中心在 1.5、单峰),会给出 φ(0)≈0.3989,高估三倍。流模型能把这个“鞍部”学出来,靠的正是分段可逆映射,而不是更大的方差。
连续情形就是 Neural ODE:dz/dt=v(z,t),密度沿轨迹演化,
dtdlogpt(zt)=−tr(∂z∂v),这其实是变量替换公式的无穷小版本,行列式取对数后变成迹。迹在高维不好算,实践中用 Hutchinson 估计 tr(A)≈Eε[ε⊤Aε],ε 取 Rademacher 向量,代价是方差。
流与最优传输有一个漂亮的接口。Brenier 说最优映射是 ∇u,流说数据由可逆映射得到;当映射取 ∇u 时两者重合,于是可以问:能不能直接学那个“最优”的流?Flow matching 就是这么做的。它的条件目标是
L=Et,x0,x1vθ(xt,t)−(x1−x0)2,xt=(1−t)x0+tx1,其中 (x0,x1) 是噪声与数据的配对。如果配对来自 OT 计划,这条直线就是 W2 的测地线,轨迹最直,采样需要的步数最少。这是我看到的“最优传输”与“生成模型”结合得最干净的一处:OT 在这里不是损失函数,而是给流指定了走哪条路。
不过我要泼一盆冷水。流模型能给出很好的密度,但似然不等于“属于这个类”。Nalisnick 等人在 2019 年观察到,在图像上训练得很好的流模型给 OOD 样本的似然反而更高;原因还是典型集——模型把质量摊在一个高维薄壳上,OOD 样本落在壳外,却可能恰好落在密度不低的地方。所以流更适合做生成、做密度比、做精确的变量替换,而不是拿来当 OOD 分数直接用。
现在把这些工具放回机器学习里,按我实际见过、用过的顺序说。
生成模型是最直接的一站。GAN 的原始目标用 JS 散度,而 JS 在两个分布支撑不交时是个常数 log2,梯度为零——这是早期 GAN 训练不稳定的理论解释之一。WGAN 换成 W1,用对偶式
Gmin∥f∥Lip≤1max EPr[f(x)]−EPg[f(x)],critic f 就是 Kantorovich 势函数,Lipschitz 约束用 weight clipping 或 gradient penalty 近似。这个改动的实质是把一个饱和的散度换成一个不饱和的度量。
扩散模型和流匹配是同一件事的两种写法,都是把噪声分布运输到数据分布。区别在路径:扩散用固定的前向过程,流匹配可以自己选,选了 OT 路径就得到更直的轨迹和更少的采样步数。
域适应与分布偏移是 W 最能发挥的地方。给定源域和目标域的特征分布 μS,μT,直接最小化 W(μS,μT) 就能对齐两个域,且不需要标签。对偶形式又让它变成对抗训练:一个网络学 φ 去最大化 ∫φdμS−∫φdμT,另一个网络调整特征表示去最小化这个差。多个源域时用 Wasserstein 重心,在 W2 空间里求“平均分布”,这正是 Fréchet 均值在分布空间里的实例。
OOD 检测,也就是我开头那个 0.99 的问题,我会分三层来做。
设想一条质检流水线,训练时只有“正常”“划痕”“凹陷”三类。现在来了一个从没见过的新缺陷。
点态一层比较样本密度:对每个类拟合 KDE 或流,取 −logp^k(x) 作为分数。它便宜、可解释,但受典型集悖论和带宽影响,高维不可靠——上一节那个“空洞比簇心更密”的例子就是反例。
分布一层算测试批(或测试样本的邻域)到每个类条件分布的 W2,取最小者作为“离最近已知类的距离”。优点是它看整片质量而不是单个点;缺点是它需要一批样本,还有 n−1/d 的样本复杂度。实践中的折中是:在低维隐空间里算,或者用对偶势 φ——一旦在一批数据上解出 φ,φ(x) 本身就是逐样本分数,可以拿去做单点判定。我很喜欢这个技巧,它把“批级别的距离”翻译成了“点级别的分数”,两个需求一次满足。
输出一层比较类别概率分布的差异:训练时记录每个类在验证集上的平均预测分布(单纯形上的一个点),测试时算测试批的平均预测分布与它的 Fisher–Rao 距离。距离大,说明模型在这批数据上的“说话方式”变了,即使每个样本的置信度都不低。这一层不需要标签也不需要密度估计,我觉得是性价比最高的一个。
分类与损失那一侧前面已经说了:交叉熵是 Bregman,自然梯度是 Fisher 预条件,镜像下降是 Bregman 投影。这三个东西实现上都很朴素,但把它们在理论上认成同一族,能省掉很多“为什么这个 trick 有效”的困惑。
回到那个 0.99。
置信度回答的是“在这几个类里最像哪个”,它是一次相对排序,分母被 softmax 强行归一化成 1。分布几何回答的是“这个点离已知类别的概率质量有多远”,它是一个绝对量,不依赖“一定属于某个类”这个假设。这两件事不该互相替代,而应该互补:分类器给候选,分布几何判越界。
如果只留一个式子,我会留 Kantorovich 对偶:
W1(μ,ν)=∥φ∥Lip≤1sup∫φd(μ−ν).它把一个关于分布的优化问题,变成了一个关于函数的优化问题。分布是无穷维的、难参数化的;函数是可以拿神经网络拟合的。这一步转换,才是最优传输能从 1781 年的搬土问题走进今天每一篇 WGAN、每一次域适应、每一个流匹配模型的真正原因。
至于 Fisher–Rao 和 Bregman,它们给我的东西不太一样:不是算法,而是一种校准过的直觉——当我说“两个分布很近”的时候,我最好知道自己是拿哪把尺子在量,以及那把尺子在局部是不是真的像一个度量。