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