es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Tensorflow: Error de división por cero durante la concatenación de elementos únicos del tensor.

Actualmente estoy trabajando en un agente actor-crítico “four wins” en Python. Mientras intentaba propagar hacia atrás a través de distribuciones de probabilidad de acción previamente recolectadas, me encontré con el siguiente error: “ZeroDivisionError: división de entero o módulo por cero”.

Fue capaz de reproducir el error con el siguiente código en Tensorflow versión 2.7.0 en mi CPU (Ubuntu 20.04.3 LTS):

import tensorflow as tf

with tf.GradientTape() as tape:
t = tf.Variable([1.])

concat = tf.concat(values=[t[0], t[0]], axis=0)
concat_sum = tf.reduce_sum(concat)

grads = tape.gradient(concat_sum, t)

Sé que el problema puede parecer trivial en este ejemplo de código. Sin embargo, todavía es incomprensible para mí por qué hay un error aquí. ¿No debería ser lo mismo concatenar los primeros elementos del tensor y sumarlos finalmente que hacer la suma directamente, como en el siguiente código?

with tf.GradientTape() as tape:
t = tf.Variable([1.])

result = t + t

grads = tape.gradient(result, t)

¿Por qué uno genera gradientes válidos mientras que el otro no?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La razón del error en el ejemplo de código se debe al hecho de que la operación de concat crea un tensor de longitud 2 donde ambos elementos son iguales, es decir, [1., 1.]. Al llamar a tf.reduce_sum, esto sumará los dos elementos para dar 2. Como estamos tratando de calcular el gradiente de concat_sum con respecto a t, esto resultará en una división por cero, de ahí el ZeroDivisionError.

    En el segundo ejemplo de código, simplemente agregamos t a sí mismo, lo que resulta en un valor escalar de 2. Como estamos tratando de calcular el gradiente de resultado con respecto a t, esta es una operación válida y obtenemos un gradiente válido.

    Para solucionar el problema en el primer ejemplo, simplemente se puede cambiar el eje de concatenación a axis=1, de modo que obtengamos un tensor de forma [1, 2], y luego llamar a tf.reduce_sum con axis=1 para sumar en la segunda dimensión. Esto se vería de la siguiente manera:

    import tensorflow as tf
    
    with tf.GradientTape() as tape:
        t = tf.Variable([1.])
    
        concat = tf.concat(values=[t[0], t[0]], axis=1)
        concat_sum = tf.reduce_sum(concat, axis=1)
    
        grads = tape.gradient(concat_sum, t)
    

    Esto ahora debería dar un gradiente válido sin errores.

Comments are closed.