在机器学习和统计学中,通常会计算各种指数形式的值,例如 softmax 概率值、指数损失函数等。这些指数形式的计算容易遇到数值上溢和下溢的问题,导致计算结果不准确。
为了解决这个问题,常用的技巧是通过一些数学变换将指数形式的值变换成对数形式,这样可以避免数值上溢和下溢的问题,同时也能提高计算速度。
其中一个常用的数学变换是 logsumexp。假设我们要计算一组数 $x_1, x_2, …, x_n$ 的和的指数形式,即 $\exp(x_1)+\exp(x_2)+…+\exp(x_n)$,我们可以将其转换为对数形式,即 $\log(\exp(x_1)+\exp(x_2)+…+\exp(x_n))$。
但是,如果 $n$ 比较大,直接计算 $\log(\exp(x_1)+\exp(x_2)+…+\exp(x_n))$ 会遇到数值上溢和下溢的问题。为了解决这个问题,我们可以利用下面的数学性质:
$$
\log(\exp(a)+\exp(b))=\log\left(\exp(a)(1+\exp(b-a))\right)=a+\log(1+\exp(b-a)) \tag{1}
$$
其中 $a$ 和 $b$ 是任意实数。
根据这个公式 1,我们可以将 $\log(\exp(x_1)+\exp(x_2)+…+\exp(x_n))$ 中每一项 $\exp(x_i)$ 都除以 $\exp(\max(x_1, x_2, …, x_n))$ 再乘以它,这样不会改变原来的值, 为了简化记其为 $m$。
$$
\begin{aligned}
\log(\exp(x_1)+\exp(x_2)+…+\exp(x_n)) &= \log(\exp(x_1-m)\cdot\exp(m)+…+\exp(x_n-m)\cdot\exp(m)) \\
&= \log(\exp(m)\cdot(\exp(x_1-m+…+\exp(x_n-m))) \\
&= \log(\exp(m))+\log(\exp(x_1-m)+…+\exp(x_n-m)) \\
&= m+\log(\exp(x_1-m)+…+\exp(x_n-m))
\end{aligned} \tag{2}
$$
将 $m=\exp(\max(x_1, x_2, …, x_n))$ 带入就有:
$$
\begin{aligned}
&\log(\exp(x_1)+\exp(x_2)+…+\exp(x_n)) =\\
&\max(x_1, x_2, …, x_n)+\log(\exp(x_1-\max(x_1, x_2, …, x_n))+…+\exp(x_n-\max(x_1, x_2, …, x_n)))
\end{aligned} \tag{3}
$$
这样,我们就避免了数值上溢和下溢的问题,并且用 $\max$ 函数来近似表示对数求和,因此 logsumexp 实际上就是 max 的光滑近似。
参考
[2] 关于 LogSumExp