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.

Función de pérdida de TensorFlow sin gradiente proporcionado.

Actualmente intento codificar mi propia función de pérdida, pero al devolver el resultado (un tensor que consta de una lista con los valores de pérdida) obtengo el siguiente error:

ValueError: No se proporcionaron gradientes para ninguna variable: ['conv2d/kernel:0', 'conv2d/bias:0', 'conv2d_1/kernel:0', 'conv2d_1/bias:0', 'dense/kernel:0', 'dense/bias:0', 'dense_1/kernel:0', 'dense_1/bias:0', 'dense_2/kernel:0', 'dense_2/bias:0'].

Sin embargo, en tutoriales y en sus documentos también utilizan tf.reduce_mean y cuando lo uso como ellos (mostraron cómo codificar la función de pérdida mse) no obtengo el error, por lo que parece que me falta algo.

Mi código:

gl = tfa.losses.GIoULoss()
def loss(y_true, y_pred):
        batch_size = y_true.shape[0]
        bbx_true = y_true.numpy()

        bbx_pred = y_pred.numpy()

        losses = []
        curr_true = []
        curr_pred = []
        for i in range(batch_size):
            curr_true = bbx_true[i] 
            curr_pred = bbx_pred[i][0][0]

            curr_true = [curr_true[x:x+4] for x in range(0, len(curr_true), 4)]
            curr_pred = [curr_pred[x:x+4] for x in range(0, len(curr_pred), 4)]

            if len(curr_true) == 0:
                curr_true.append([0., 0.,0.,0.])

            curr_loss = gl(curr_true, curr_pred)

            losses.append(curr_loss)

        return tf.math.reduce_mean(losses, axis=-1)

Básicamente, quiero lograr la “regresión de cuadros delimitadores” y debido a eso quiero usar la función de pérdida GIoUloss. Debido a que mi modelo produce 7896 neuronas (la cantidad máxima de cuadros delimitadores que quiero predecir según mi conjunto de entrenamiento multiplicado por 4) y la función de pérdida gioloss necesita la entrada como una matriz de listas con 4 elementos cada una, tengo que realizar esta transformación.

¿Cómo tengo que cambiar mi código para también construir un gradiente?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El error ocurre porque TensorFlow no puede calcular los gradientes de las variables utilizadas en la función de pérdida. Para generar un gradiente, es necesario utilizar la función de diferenciación automática de TensorFlow, que calcula los gradientes de una operación en relación a sus entradas.

    En su código, está convirtiendo los tensores a matrices numpy, lo que los hace no-diferenciables. Para resolver esto, es necesario dejar los tensores como están y utilizar operaciones de TensorFlow para la operación.

    Aquí está una versión actualizada de su código que debería funcionar:

    gl = tfa.losses.GIoULoss()
    
    @tf.function
    def loss(y_true, y_pred):
        batch_size = y_true.shape[0]
        # Extraer las coordenadas de los cuadros delimitadores de los tensores y_pred y y_true
        # y convertirlos al formato esperado por GIoULoss
        bbx_true = tf.reshape(tf.squeeze(y_true), [batch_size, -1, 4])
        bbx_pred = tf.reshape(tf.squeeze(y_pred), [batch_size, -1, 4])
    
        losses = []
        for i in range(batch_size):
            curr_true = bbx_true[i] 
            curr_pred = bbx_pred[i]
    
            curr_loss = gl(curr_true, curr_pred)
    
            losses.append(curr_loss)
    
        # Calcular la media de las pérdidas para el lote
        return tf.math.reduce_mean(losses)
    

    En esta versión del código, la función de loss se define utilizando el decorador tf.function de TensorFlow, que le dice a TensorFlow que compile la función en un grafo que pueda ser ejecutado eficientemente. Las coordenadas de los cuadros delimitadores se extraen utilizando operaciones de TensorFlow y se convierten al formato esperado por GIoULoss. Las pérdidas se calculan utilizando objetos tf.Tensor y se agregan a una lista. Se calcula la media de las pérdidas para todo el lote utilizando una operación de TensorFlow.

    Con estos cambios, la función de loss ahora debería ser diferenciable y capaz de calcular gradientes.

Comments are closed.