机器学习笔记(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\)
形式真好看吧

浙公网安备 33010602011771号