使用对数来规范化向量以避免溢出

时间:2010-03-08 09:47:29

标签: algorithm overflow numerical

Problem with arithmetic using logarithms to avoid numerical underflow (take 2)

看过上面的内容并看到了softmax规范化后,我试图规范化矢量,同时避免溢出 -

即如果我有一个数组 x[1], x[2] x[3], x[4], ... , x[n]

我的规范化形式的元素平方和为1.0 并且通过将每个元素除以得到 sqrt(x[1]*x[1]+x[2]*x[2]+...+x[n]*x[n])

现在,即使平方根足够小以适应浮点变量,方块的总和也会溢出,所以我想象一个人可以做类似的事情 s=(2*log(fabs(x[1]))+2*log(fabs(x[2]))+...+2*log(fabs(x[n])))/2

并将元素计算为

exp(log(fabs(x[1]))-s), ..., exp(log(fabs(x[n]))-s

BUT

以上是不正确的,因为log(A + B)不是log(A)+ log(B) - 现在有没有办法进行矢量归一化,以避免溢出更好?

3 个答案:

答案 0 :(得分:4)

而不是

norm  = sqrt(x[1] * x[1] + ... + x[n] * x[n])

您可能希望在平方之前将矢量的元素除以最大可能值

max_x = max(x[1], ..., x[n])
y[1] = x[1] / max_x / n
...
y[n] = x[n] / max_x / n
norm = n * sqrt(y[1] * y[1] + ... + y[n] * y[n]) * max_x

y向量的范数应该等于或小于零。 n * max_x的值仍然可能溢出,因此您还需要注意,操作是以非溢出顺序执行的。

答案 1 :(得分:3)

你似乎在假设:

log(x^2 + y^2)

与:

相同
log(x^2) + log(y^2)

然而,这是不正确的,因为你无法简化这样的总和的对数。

答案 2 :(得分:3)

KennyTM是正确的 - 您对对数的想法是错误的。

你不能使用L2规范,因为它要求你计算向量的大小,这正是你遇到溢出问题。

也许L-infinity范数,你将矢量中的每个分量除以最大分量的绝对值首先会更好。一定要保持最大绝对值,这样才能获得正确的幅度。

我完全理解你需要L2规范,但如果溢出确实是一个问题,你需要采取中间步骤才能得到它:

  1. 找到向量的最大绝对值。
  2. 将每个组件除以最大绝对值以进行标准化;最大值现在为+/- 1。
  3. 计算归一化分量的平方和的平方根。我建议对值进行排序并按升序添加它们,以确保不丢失小组件。
  4. 乘以最大绝对值,得到原始矢量的L2范数。