wake-up-neo.com

Überlauf in exp in scipy/numpy in Python?

Was bedeutet der folgende Fehler:

Warning: overflow encountered in exp

in scipy/numpy mit Python im Allgemeinen bedeuten? Ich berechne ein Verhältnis in Protokollform, d. H. Log (a) + log (b), und nehme dann den Exponenten des Ergebnisses mit exp und verwende eine Summe mit logsumexp wie folgt:

c = log(a) + log(b)
c = c - logsumexp(c)

einige Werte im Array b sind absichtlich auf 0 gesetzt. Ihr Protokoll wird -Inf sein.

Was könnte die Ursache für diese Warnung sein? Vielen Dank.

17
user248237dfsf

In Ihrem Fall bedeutet dies, dass b irgendwo in Ihrem Array very small ist, und Sie erhalten eine Zahl (a/b oder exp(log(a) - log(b))), die zu groß für das dtype (float32, float64 usw.) des Arrays ist. Zum Speichern der Ausgabe verwenden. 

Numpy kann konfiguriert werden 

  1. Ignorieren Sie diese Art von Fehlern, 
  2. Fehler ausgeben, aber keine Warnung ausgeben, um die Ausführung zu stoppen (Standardeinstellung)
  3. Fehler protokollieren 
  4. Eine Warnung auslösen
  5. Fehler melden
  6. Rufen Sie eine benutzerdefinierte Funktion auf

Siehe numpy.seterr , um zu steuern, wie Unter-/Überläufe usw. in Gleitkommaarrays behandelt werden.

25
Joe Kington

Wenn Sie mit Exponential umgehen müssen, gehen Sie schnell in einen Unter-/Überlauf, da die Funktion so schnell wächst. Ein typischer Fall sind Statistiken, bei denen das Summieren von Exponentialen verschiedener Amplitude recht häufig ist. Da die Zahlen sehr groß/klein sind, nimmt man das Protokoll normalerweise an, um in einem "vernünftigen" Bereich zu bleiben, der sogenannten Protokolldomäne:

exp(-a) + exp(-b) -> log(exp(-a) + exp(-b))

Probleme treten immer noch auf, weil exp (-a) immer noch unterfließt. Beispiel: exp (-1000) liegt bereits unter der kleinsten Zahl, die Sie als Double darstellen können. Also zum Beispiel:

log(exp(-1000) + exp(-1000))

gibt -inf (log (0 + 0)), obwohl Sie mit -1000 von Hand (-1000 + log (2)) rechnen können. Die Funktion logsumexp macht es besser, indem sie das Maximum der Anzahl von Datensätzen extrahiert und aus dem Protokoll entnimmt:

log(exp(a) + exp(b)) = m + log(exp(a-m) + exp(b-m))

Es vermeidet nicht vollständig den Unterlauf (wenn beispielsweise a und b sehr unterschiedlich sind), es werden jedoch die meisten Präzisionsprobleme im Endergebnis vermieden

8

Ich denke, Sie können diese Methode verwenden, um dieses Problem zu lösen:

Normalisiert

Ich überwinde das Problem bei dieser Methode. Bevor ich diese Methode verwende, ist die Genauigkeit, die ich einstufte, 86%. Nach dieser Methode beträgt die Genauigkeit meiner Klassifizierung: 96% !!! Es ist großartig!
zuerst:
Min-Max-Skalierung

 Min-Max scaling

zweite:
Z-Score-Standardisierung

 Z-score standardization

Dies sind übliche Methoden zur Implementierung von normalization.
Ich benutze die erste Methode. Und ich ändere es. Die maximale Anzahl wird durch 10 geteilt. Daher ist die maximale Anzahl des Ergebnisses 10. Dann ist exp (-10) nicht overflow!
Ich hoffe, meine Antwort wird Ihnen helfen! (^_^)

3
intoo

Ist exp(log(a) - log(b)) nicht dasselbe wie exp(log(a/b)), was a/b ist?

>>> from math import exp, log
>>> exp(log(100) - log(10))
10.000000000000002
>>> exp(log(1000) - log(10))
99.999999999999957

2010-12-07: Wenn dies der Fall ist, "werden einige Werte im Array b absichtlich auf 0 gesetzt", dann werden Sie im Wesentlichen durch 0 dividiert. Das klingt wie ein Problem.

2
hughdbrown

In meinem Fall lag es an großen Werten in den Daten. Ich musste mich normalisieren (durch 255 dividieren, da sich meine Daten auf Bilder bezogen haben), um die Werte herabzusetzen.

0
sheikirfanbasha