Вычисление индекса Джини в тензорном потоке

Я пытаюсь записать вычисление индекса Джини как функцию стоимости тензорного потока. Индекс Джини: https://en.wikipedia.org/wiki/Gini_coefficient

тупое решение будет

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

Может кто-нибудь помочь мне разобраться, как это сделать в tf (например, в tf нет argsort, который может быть частью дифференцируемой функции, AFAIK)

1 ответ

Решение

Вы можете выполнить сортировку с помощью tf.nn.top_k(), Эта функция возвращает кортеж, вторым элементом являются индексы. Его порядок должен быть обратным, так как порядок убывает.

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

Вот код, который вы можете использовать для проверки того, что эта функция возвращает то же числовое значение, что и ваша функция 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})))
Другие вопросы по тегам