【发布时间】:2012-10-06 02:42:48
【问题描述】:
我需要执行一次 softmax 操作。也就是说,给定从 -inf 到 +inf 的一系列n 实数值,我通过对每个值取幂并除以指数之和将它们转化为概率:
for (i = 0; i < n; i++)
p_x[i] = exp(x[i]) / sum_exp(x, n)
(不要从字面上理解代码,我不是在总结所有exp 的每次迭代!)
在某些极端情况下(使用 8 字节双精度),当值超过 700 时,我会遇到溢出问题。我知道我可以使用另一个 base 来代替 e,但是,我担心调用 pow 会比 exp 慢得多(速度对我来说很重要)。
解决这个问题的最快方法是什么?
【问题讨论】:
-
不要害怕
pow变慢。 基准测试!如果你不能衡量,你就不能改进。 -
如果你害怕
pow,那exp2呢?它执行2^x而不是e^x。 -
我对@987654331@、
exp和exp2(我不知道)进行了基准测试。exp似乎比pow快 40~50 倍,比exp2快 6~7 倍。嗯,已经是这样了。 -
700 与
+Inf相比似乎并不极端。你能进一步限制你的域吗? -
事实上,我发现从每个指数中减去一个常数值更容易、更有效。这样,结果保持不变。后来才注意到,使用不同的基数会产生不同的概率。