В чем разница между 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 и сравниваю их вывод. Попробуйте запустить его несколько раз, чтобы убедиться, что он всегда выдает одинаковый результат

Другие вопросы по тегам