2010-12-05 30 views
11

¿Qué hace el siguiente error: por lo general significaDesbordamiento en exp en scipy/numpy en Python?

Warning: overflow encountered in exp 

en scipy/numpy usando Python? Estoy calcular una relación en forma de registro, es decir, log (a) + log (b) y después de tomar el exponente del resultado, utilizando exp, y usando una suma con logsumexp, como sigue:

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

algunos los valores en la matriz b se establecen intencionalmente en 0. Su registro será -Inf.

¿Cuál podría ser la causa de esta advertencia? Gracias.

+0

Bueno, solo eche un vistazo al resultado de log (a) -log (b), entonces sabrá por qué se está desbordando. –

+2

¿podría decirnos más sobre lo que está tratando de hacer? ¿Estás tratando de implementar logsumexp? –

Respuesta

21

En su caso, significa que es b muy pequeña en algún lugar de la matriz, y que está recibiendo un número (o a/bexp(log(a) - log(b))) que es demasiado grande para lo que dtype (float32, float64, etc) la matriz lo estás usando para almacenar la salida.

Numpy se puede configurar para

  1. Ignorar este tipo de errores,
  2. Imprimir el error, pero no plantea una advertencia para detener la ejecución (por defecto)
  3. registrar el error,
  4. Elevar una advertencia
  5. generará un error
  6. llamar a una función definida por el usuario

Consulte numpy.seterr para controlar cómo maneja tener sub/desbordamientos, etc. en matrices de punto flotante.

2

¿No es exp(log(a) - log(b)) lo mismo que exp(log(a/b)) que es lo mismo que a/b?

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

2010-12-07: Si esto es así "algunos valores de la matriz B se establecen intencionalmente a 0", entonces se está dividiendo esencialmente por 0. Eso suena como un problema.

+1

es lo mismo siempre que ignore el problema de precisión, lo cual es muy frecuente cuando comienza a tomar una cantidad exponencial de números. Tal vez el OP está intentando implementar algo como logsumexp –

+0

Estoy usando logsumexp - vea la revisión de la publicación editada - ¿Esto marcará la diferencia? – user248237dfsf

+0

@David Cournapeau: lo que significa que la respuesta que usa logs y exp es menos precisa, ¿no? La división es más precisa, habría pensado. Solo por mi información. – hughdbrown

8

Cuando necesita hacer frente a la exponencial, entra rápidamente en flujo insuficiente/continuo ya que la función crece tan rápidamente. Un caso típico son las estadísticas, donde la suma de exponenciales de varias amplitudes es bastante común. Dado que los números son muy grandes/cargas fraccionadas, uno generalmente toma el registro de alojarse en un rango "razonable", el denominado dominio de registro:

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

Los problemas surgen porque todavía exp (-a) todavía subdesborda hasta . Por ejemplo, exp (-1000) ya está debajo del número más pequeño que puede representar como un doble. Así, por ejemplo:

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

da -inf (log (0 + 0)), a pesar de que se puede esperar algo así como -1000 a mano (-1000 + log (2)).El logsumexp función hace mejor, mediante la extracción de la max del conjunto de números, y sacándolo del registro:

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

No evita underflow totalmente (si a y b son muy diferentes, por ejemplo), pero que evita la mayoría de los problemas de precisión en el resultado final

2

Creo que se puede utilizar este método para resolver este problema:

Normalized

puedo superar el problema de este método. Antes de usar este método, la precisión que mi clasificación es: 86%. Después de usar este método, la precisión de mi clasificación es: ¡¡96% !!! ¡Es genial!
primero:
Min-Max scaling

Min-Max scaling

Segundo:
Z-score standardization

Z-score standardization

Estos son métodos comunes para implementar normalization.
Uso el primer método. Y lo alterno. El número máximo se divide por 10. Entonces el número máximo del resultado es 10. Entonces exp (-10) no será overflow!
Espero que mi respuesta te ayude! (^_^)

0

En mi caso, fue debido a los grandes valores en los datos. Tuve que normalizar (dividir entre 255, porque mis datos estaban relacionados con las imágenes) para reducir los valores.

Cuestiones relacionadas