2017-05-17 2 views
0

je dois mettre en œuvre une nouvelle fonction de perte pour mon réseau profond qui est le suivant:tensorflow: Mise en œuvre de la nouvelle fonction de perte retourne un « ValueError: Aucun gradients prévus pour toute variable »

import tensorflow as tf 
from tensorflow.python import confusion_matrix 
from tensorflow.python.ops import math_ops 
from tensorflow.python.ops import array_ops 

def gms_loss(targets=None, logits=None, name=None): 
    #Shape checking 
    try: 
     targets.get_shape().merge_with(logits.get_shape()) 
    except ValueError: 
     raise ValueError("logits and targets must have the same shape (%s vs %s)" 
         % (logits.get_shape(), targets.get_shape())) 
    #Compute the confusion matrix 
    predictions=tf.nn.softmax(logits) 
    cm=confusion_matrix(tf.argmax(targets,1),tf.argmax(predictions,1),3) 

    def compute_sensitivities(name): 
     """Compute the sensitivity per class via the confusion matrix.""" 
     per_row_sum = math_ops.to_float(math_ops.reduce_sum(cm, 1)) 
     cm_diag = math_ops.to_float(array_ops.diag_part(cm)) 
     denominator = per_row_sum 

     # If the value of the denominator is 0, set it to 1 to avoid 
     # zero division. 
     denominator = array_ops.where(
      math_ops.greater(denominator, 0), denominator, 
      array_ops.ones_like(denominator)) 

     accuracies = math_ops.div(cm_diag, denominator) 
     return accuracies 

    gms = math_ops.reduce_prod(compute_sensitivities('sensitivities')) 
    return gms 

Voici l'appel de le code graphique:

test=gms_loss(targets=y,logits=pred) 
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(test) 

et enfin, l'erreur déjà connu:

"ValueError: No gradients provided for any variable, check your graph for ops that do not support gradients, between variables..." 

Je ne suis pas en mesure de f ind problème, si je l'utilise softmax_cross_entropy, cela fonctionne (mais pas en mesure d'optimiser correctement, c'est pourquoi j'ai besoin de la nouvelle fonction de perte)

Nous vous remercions à l'avance

Répondre

2

Je pense que le problème est que la fonction tf.argmax() n'est pas différentiable. Par conséquent, l'optimiseur ne parviendra pas à calculer le gradient de la fonction de perte par rapport à vos prédictions et cibles. Je ne connais pas un moyen de gérer cela avec la fonction argmax, donc je recommanderais d'éviter les fonctions non différentiables.

+0

Vous avez raison, oubliez-le, GMS n'est tout simplement pas dérivable ... Merci pour votre temps. – DarkHawk

+0

@DarkHawk Je suis confronté à un problème similaire lorsque j'essaie de créer une fonction de coût/perte personnalisée. J'utilisais argmax pour comprendre la matrice de confusion et NE PAS pénaliser autant les faux négatifs que les faux positifs. Avez-vous déjà trouvé une solution à votre problème? Ça te dérange le partage? Merci! – mschmidt42

+0

@ mschmidt42 En supposant que l'indice positif (signal) est 0 et que tous les autres indices sont négatifs (arrière-plan), vous pouvez utiliser quelque chose comme 'w = s (y) [:, 0] * (1 - y '[:, 0 ]) + K * (1 - s (y) [:, 0]) * y '[:, 0], où y est la sortie réseau, s (y) est la softmax de la sortie réseau, et y' sont les vraies étiquettes. Cela produit de grandes erreurs pour les faux positifs (première partie de la somme) et les faux négatifs (seconde partie). Il n'y a pas de 'argmax' dedans, donc cela donne aussi une erreur pour les prédictions correctes, mais il est différentiable. Vous pouvez ajuster la pondération relative des parties en augmentant ou en diminuant K. – ml4294