В чем разница между sparse_softmax_cross_entropy_with_logits и softmax_cross_entropy_with_logits?
Недавно я наткнулся на https://www.tensorflow.org/api_docs/python/tf/nn/sparse_softmax_cross_entropy_with_logits и не могу понять, в чем разница по сравнению с https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits.
Разница только в том, что тренируются векторы y
должен быть горячим кодированием при использовании sparse_softmax_cross_entropy_with_logits
?
Читая API, я не смог найти никаких других отличий по сравнению с softmax_cross_entropy_with_logits
, Но зачем нам тогда дополнительная функция?
не должны softmax_cross_entropy_with_logits
дают те же результаты, что и sparse_softmax_cross_entropy_with_logits
, если он снабжен обучающими данными / векторами с горячим кодированием?
3 ответа
Наличие двух разных функций - это удобство, поскольку они дают одинаковый результат.
Разница проста:
- За
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
на этом ярлыке.
Я просто хотел бы добавить 2 вещи к принятому ответу, которые вы также можете найти в документации TF.
Первый:
tf.nn.softmax_cross_entropy_with_logits
ПРИМЕЧАНИЕ. Хотя классы являются взаимоисключающими, их вероятности не должны быть. Все, что требуется, - это то, что каждая строка меток является допустимым распределением вероятности. Если это не так, вычисление градиента будет неверным.
Во-вторых:
tf.nn.sparse_softmax_cross_entropy_with_logits
ПРИМЕЧАНИЕ. Для этой операции вероятность данной метки считается исключительной. То есть мягкие классы недопустимы, и вектор меток должен предоставлять один конкретный индекс для истинного класса для каждой строки логитов (каждой записи мини-пакета).
Обе функции вычисляют одинаковые результаты, а https://www.tensorflow.org/api_docs/python/tf/nn/sparse_softmax_cross_entropy_with_logits вычисляет перекрестную энтропию непосредственно на разреженных метках, а не конвертирует их с использованием горячего кодирования.
Вы можете убедиться в этом, запустив следующую программу:
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 и сравниваю их вывод. Попробуйте запустить его несколько раз, чтобы убедиться, что он всегда выдает одинаковый результат