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