2

数値のアンダーフローを回避するために対数を使用する算術の問題 (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

しかし

log(A+B) は log(A)+log(B) ではないため、上記は正しくありません。オーバーフローをより適切に回避するベクトル正規化を行う方法はありますか?

4

3 に答える 3

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まだオーバーフローする可能性があるため、ここでも操作がオーバーフローしない順序で実行されるように注意する必要があります。

于 2010-03-08T11:04:40.813 に答える
3

あなたは次のことを仮定しているようです:

log(x^2 + y^2)

以下と同じです:

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

ただし、そのような合計の対数を単純化することはできないため、これは正しくありません。

于 2010-03-08T10:15:07.093 に答える
3

KennyTM は正しいです。対数に関するあなたの考えは間違っています。

ベクトルの大きさを計算する必要があるため、L2ノルムを使用することはできません。これはまさにオーバーフローの問題を抱えているものです。

おそらく、最初にベクトル内の各成分を最大成分の絶対値で除算する L 無限ノルムの方がよいでしょう。正しいマグニチュードを取り戻すことができるように、必ずその最大絶対値に固執してください。

L2ノルムが必要であることは完全に理解していますが、オーバーフローが実際に問題である場合は、それを取得するために中間の手順を実行する必要があります:

  1. ベクトルの最大絶対値を見つけます。
  2. 各コンポーネントを最大絶対値で割って正規化します。最大値が +/- 1 になりました。
  3. 正規化された成分の二乗和の平方根を計算します。小さなコンポーネントが失われないように、値を並べ替えて昇順に追加することをお勧めします。
  4. 元のベクトルの L2 ノルムを取得するには、最大絶対値を掛けます。
于 2010-03-08T10:18:55.413 に答える