机器学习笔记(6): KL 散度

可能更好的阅读体验 Jeefy's Blog: KL 散度

KL 散度描述的是两个分布之间的差异,更具体一点,是一个分布相对另一个分布的差异。

\[D_{KL}(P || Q) = \sum_{x \in P} P(x) \log \frac {P(x)}{Q(x)} = {\mathbb E}_{x \sim P}[\log P(x) - \log Q(x)] \]

需要注意的是:

  • 这里计算的 \(Q\) 相对 \(P\) 的差异
  • 如果 \(Q\) 中出现了 \(P\) 中不存在的东西,那么不会计入散度
  • 但是如果 \(Q\) 中是小概率,但是 \(P\) 中概率很大,那么 \(P(x)\) 不小并且 \(\log \frac {P(x)}{Q(x)}\) 很大,可能会导致散度爆炸。
  • 如果 \(P(x)\) 中某个分布的概率很小,那么 \(P(x)\) 会使得该概率对散度的影响很小,但如果概率相差很大,还是会构成差距。
    • 补充:考虑 \(\log\) 是一个上凸函数,那么利用琴生不等式,有 \({\mathbb E}_{x \sim P}[\log \frac {P(x)} {Q(x)}] = -{\mathbb E}_{x \sim P}[\log \frac {Q(x)} {P(x)}] \ge -\log {\mathbb E}_{x \sim P}[\frac {Q(x)} {P(x)}] = - \log 1 = 0\),故散度不可能为负数,并且当且仅当 \(P = Q\) 时等号成立。
  • 数值不稳定,因为 \(\log\) 在 \(< 1\) 时估计与真实值的差距很大。
  • 根据 神秘 言论:KL 散度衡量的是“用分布 \(Q\) 去编码分布 \(P\) 时,平均多用了多少比特”。既然 \(P\) 是最优编码,用任何其他 \(Q\) 编码必然效率更低(花费更多比特),不可能更少(负数)或一样

如果利用 KL 散度作为 Loss,那么实际上计算的交叉熵:

\[J(\theta) = {\mathbb E}_{x \sim P} [-\log Q(x)] = \sum_{x \in P} - P(x) \log Q(x) \]

其对于 \(\theta\) 偏导:

\[\frac {\partial J(\theta)}{\partial \theta} = \sum_{x \in P} - \frac {P(x)} {Q(x)} \frac {\partial Q(x)} {\partial \theta} \]

由于一般来说,对于模型的回归问题,最终的输出不是归一化的,也就是 \(\sum Q(x) \ne 1\),所以需要在外面套一层 softmax 函数,保证概率和为 \(1\):

\[J(\theta) = {\mathbb E}_{x \sim P} [- \log \frac {e^{Q(x)}}{\sum_x e^{Q(x)}}] = \sum_{x \in P} -P(x) \log \frac {e^{Q(x)}}{\sum_z e^{Q(z)}} \]

那么对于每一个 \(x\) 单独求取梯度:

\[\begin{aligned} \frac {\partial J(\theta)} {\partial z_i} &= \frac \partial {\partial z_i} \sum_{j} -y_j \log \frac {e^{z_j}} {\sum_t e^{z_t}} \\ &= \sum_j -y_j \frac {\sum_t e^{z_t}} {e^{z_j}} \frac \partial {\partial z_i} \frac {e^{z_j}} {\sum_t e^{z_t}} \\ &= \sum_j -y_j \frac S {e^{z_j}} \begin{cases} \frac {(e^{z_j} S - e^{z_i} e^{z_j})} {S^2} & i = j \\ - \frac {e^{z_j} e^{z_i}} {S^2} & i \ne j \\ \end{cases} \\ & = \sum_j - y_j (\delta_{ij} - \frac {e^{z_i}}{S}) \\ & = \frac {e^{z_i}} {\sum e^{z_t}} - y_i \end{aligned} \]

需要注意的是,这里默认有 \(\sum_i y_i = 1\)
形式真好看吧

posted @ 2026-04-03 11:02  jeefy  阅读(121)  评论(0)    收藏  举报