2017-10-10 8 views
0

J'essaie d'écrire le calcul de l'indice de Gini comme une fonction de coût de flux tensoriel. Indice de Gini est: https://en.wikipedia.org/wiki/Gini_coefficientCalcul de l'indice de Gini dans tensorflow

une solution numpy serait

def ginic(actual, pred): 
    n = len(actual) 
    a_s = actual[np.argsort(pred)] 
    a_c = a_s.cumsum() 
    giniSum = a_c.sum()/a_s.sum() - (n + 1)/2.0 
    return giniSum/n 

Quelqu'un peut-il me aider à comprendre comment faire cela dans tf (par exemple, dans tf il n'y a pas argsort qui peut faire partie d'un fonction qui est différenciée, AFAIK)

Répondre

1

Vous pouvez effectuer l'argsorting en utilisant tf.nn.top_k(). Cette fonction renvoie un tuple, le second élément étant les indices. Sa commande doit être inversée puisque la commande est décroissante.

def ginicTF(actual:tf.Tensor,pred:tf.Tensor): 
    n = int(actual.get_shape()[-1]) 
    inds = tf.reverse(tf.nn.top_k(pred,n)[1],axis=[0]) # this is the equivalent of np.argsort 
    a_s = tf.gather(actual,inds) # this is the equivalent of numpy indexing 
    a_c = tf.cumsum(a_s) 
    giniSum = tf.reduce_sum(a_c)/tf.reduce_sum(a_s) - (n+1)/2.0 
    return giniSum/n 

Voici un code que vous pouvez utiliser pour vérifier que cette fonction retourne la même valeur numérique que votre fonction numpy ginic:

sess = tf.InteractiveSession() 
ac = tf.placeholder(shape=(50,),dtype=tf.float32) 
pr = tf.placeholder(shape=(50,),dtype=tf.float32) 
actual = np.random.normal(size=(50,)) 
pred = np.random.normal(size=(50,)) 
print('numpy version: {:.4f}'.format(ginic(actual,pred))) 
print('tensorflow version: {:.4f}'.format(ginicTF(ac,pr).eval(feed_dict={ac:actual,pr:pred}))) 
+0

Ok, cela semble bon, mais lorsqu'il est passé à un NN comme une perte fonctionner, il retourne une erreur pour la ligne : ---> 14 n = int (actual.get_shape() [- 1]) erreur: TypeError: \ __ int \ __ non-int retourné (type NoneType) il fonctionne comme prévu si je cours juste une session – Ilya

+0

Je pense que cela se produit parce que la forme de votre espace réservé \ tensor pour 'effective' est' (None,) ', ce qui signifie qu'elle n'a pas de longueur prédéfinie, donc' n' ne peut pas être calculé au moment de construction graphique. Dans ce cas, ce que vous pouvez faire est juste de passer 'n' (la longueur des tableaux) comme argument supplémentaire à la fonction, au lieu de le calculer. – Lior

+0

Ok, je n'ai pas pu résoudre ce problème (j'ai essayé de donner la valeur par défaut de n, mais cela ne résout pas le problème). J'ai fait une nouvelle question pour ce problème particulier https://stackoverflow.com/questions/46674293/custom-loss-function-in-keras-how-to-deal-with-placeholders Encore une fois, merci d'avoir écrit le fonctionne en TF! – Ilya