2016-05-19 3 views
46

Я недавно натолкнулся на tf.nn.sparse_softmax_cross_entropy_with_logits, и я не могу понять, какая разница по сравнению с tf.nn.softmax_cross_entropy_with_logits.TensorFlow: какая разница между sparse_softmax_cross_entropy_with_logits и softmax_cross_entropy_with_logits?

Единственная разница в том, что подготовка векторов y должна быть one-hot encoded при использовании sparse_softmax_cross_entropy_with_logits?

Чтение API Я не смог найти никакой другой разницы по сравнению с softmax_cross_entropy_with_logits ... но зачем нам нужна дополнительная функция?

Не должно softmax_cross_entropy_with_logits произвести тот же результат, что и sparse_softmax_cross_entropy_with_logits, если он снабжен одноразовыми закодированными данными/векторами обучения?

+0

Мне интересно сравнить их производительность, если они могут использоваться (например, с эксклюзивными метками изображений); Я ожидаю, что разреженная версия будет более эффективной, по крайней мере, с точки зрения памяти. –

+0

См. Также [этот вопрос] (https://stackoverflow.com/q/47034888/712995), в котором обсуждается * все функции кросс-энтропии * в тензорном потоке (оказывается, их много). – Maxim

ответ

81

Имея две различные функции, это удобство, так как они дают одинаковый результат.

Разница проста:

  • Для sparse_softmax_cross_entropy_with_logits, этикетки должны иметь форму [batch_size] и DTYPE int32 или int64. Каждая метка является int в диапазоне [0, num_classes-1].
  • Для softmax_cross_entropy_with_logits метки должны иметь форму [batch_size, num_classes] и dtype float32 или float64.

Этикетки, используемые в softmax_cross_entropy_with_logits являются один горячий вариант этикеток, используемых в sparse_softmax_cross_entropy_with_logits.

Другая крошечная разница в том, что с sparse_softmax_cross_entropy_with_logits, вы можете дать -1 в качестве метки, чтобы иметь потерю 0 на этой этикетке.

+5

Правильно ли это -1? Как говорится в документации: «Каждая запись в ярлыках должна быть индексом в [0, num_classes]. Другие значения будут вызывать исключение, когда этот op запущен на CPU, и вернуть NaN для соответствующих строк потерь и градиента на графическом процессоре». – user1761806

12

Я хотел бы добавить 2 вещи к принятому ответу, которые вы также можете найти в документации TF.

Первое:

tf.nn.softmax_cross_entropy_with_logits

Примечание: В то время как классы являются взаимоисключающими, их вероятности не должно быть. Все, что требуется, состоит в том, что каждая строка меток является действительным распределением вероятностей . Если это не так, вычисление будет неправильным.

Второе:

tf.nn.sparse_softmax_cross_entropy_with_logits

ПРИМЕЧАНИЕ: Для выполнения этой операции, вероятность данной этикетке считается эксклюзивным. То есть, мягкие классы не допускаются, а вектор меток должен предоставлять один конкретный индекс для истинного класса для каждой строки логитов (каждая запись в мини-часах).

+4

Что следует использовать, если классы не являются взаимоисключающими. Я имею в виду, если мы объединяем несколько категориальных ярлыков? – Hayro

+0

Я также читал это. Таким образом, это означает, что мы применяем вероятность класса на кросс-энтропии, а не принимаем ее как одномерный вектор. –

+0

@ Hayro - Вы имеете в виду, что вы не можете сделать одну горячую кодировку? Думаю, вам придется посмотреть на другую модель. [This] (http://ufldl.stanford.edu/wiki/index.php/Softmax_Regression) упомянул что-то вроде «было бы более целесообразно построить 4 бинарных логистических классификатора регрессии». Сначала убедитесь, что вы можете отделить классы. – ashley

8

Обе функции вычисляет одни и те же результаты и sparse_softmax_cross_entropy_with_logits вычисляет перекрестную энтропию непосредственно на разреженных метках вместо преобразования их с one-hot encoding.

Вы можете проверить это, запустив следующую программу:

import tensorflow as tf 
from random import randint 

dims = 8 
pos = randint(0, dims - 1) 

logits = tf.random_uniform([dims], maxval=3, dtype=tf.float32) 
labels = tf.one_hot(pos, dims) 

res1 = tf.nn.softmax_cross_entropy_with_logits(  logits=logits, labels=labels) 
res2 = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=tf.constant(pos)) 

with tf.Session() as sess: 
    a, b = sess.run([res1, res2]) 
    print a, b 
    print a == b 

Здесь я создаю случайный logits вектор длины dims и генерировать один горячий кодированные метки (где элемент в pos 1 и другие равны 0) ,

После этого я вычисляю softmax и разреженный softmax и сравниваю их выходные данные. Попробуйте повторить его несколько раз, чтобы убедиться, что он всегда производит одинаковый вывод.

Смежные вопросы