Как выбрать кросс-энтропийную потерю в тензорном потоке?
Проблемы классификации, такие как логистическая регрессия или полиномиальная логистическая регрессия, оптимизируют кросс-энтропийную потерю. Обычно слой кросс-энтропии следует за слоем softmax, который производит распределение вероятностей.
В тензорном потоке существует по меньшей мере дюжина различных функций кросс-энтропийной потери:
tf.losses.softmax_cross_entropy
tf.losses.sparse_softmax_cross_entropy
tf.losses.sigmoid_cross_entropy
tf.contrib.losses.softmax_cross_entropy
tf.contrib.losses.sigmoid_cross_entropy
tf.nn.softmax_cross_entropy_with_logits
tf.nn.sigmoid_cross_entropy_with_logits
- ...
Какие из них работают только для бинарной классификации, а какие подходят для многоклассовых задач? Когда вы должны использовать sigmoid
вместо softmax
? Как sparse
функции отличаются от других и почему это только softmax
?
Связанное (более ориентированное на математику) обсуждение: кросс-энтропийные джунгли.
3 ответа
Предварительные факты
В функциональном смысле сигмоид является частичным случаем функции softmax, когда число классов равно 2. Оба они выполняют одну и ту же операцию: преобразуют логиты (см. Ниже) в вероятности.
В простой бинарной классификации нет большой разницы между ними, однако в случае полиномиальной классификации сигмоид позволяет работать с неисключительными метками (так называемыми мульти-метками), в то время как softmax работает с эксклюзивными классами (см. Ниже).
Логит (также называемый счетом) - это необработанное немасштабированное значение, связанное с классом, до вычисления вероятности. С точки зрения архитектуры нейронной сети это означает, что логит является выходом плотного (полностью связного) уровня.
Именование тензорного потока немного странно: все нижеприведенные функции принимают логиты, а не вероятности, и сами применяют преобразование (которое просто более эффективно).
Сигмовидная функция семьи
tf.nn.sigmoid_cross_entropy_with_logits
tf.nn.weighted_cross_entropy_with_logits
tf.losses.sigmoid_cross_entropy
tf.contrib.losses.sigmoid_cross_entropy
(Устаревшее)
Как говорилось ранее, sigmoid
Функция потерь для двоичной классификации. Но функции тензорного потока имеют более общий характер и позволяют проводить мультиметочную классификацию, когда классы независимы. Другими словами, tf.nn.sigmoid_cross_entropy_with_logits
решает N
бинарные классификации сразу.
Метки должны иметь горячее кодирование или могут содержать вероятности мягкого класса.
tf.losses.sigmoid_cross_entropy
кроме того, позволяет устанавливать веса в партии, то есть делать некоторые примеры более важными, чем другие. tf.nn.weighted_cross_entropy_with_logits
позволяет устанавливать веса классов (помните, что классификация является двоичной), т.е. делать положительные ошибки больше отрицательных ошибок. Это полезно, когда данные тренировки не сбалансированы.
Softmax семейство функций
tf.nn.softmax_cross_entropy_with_logits
(УСТАРЕЛО В 1.5)tf.nn.softmax_cross_entropy_with_logits_v2
tf.losses.softmax_cross_entropy
tf.contrib.losses.softmax_cross_entropy
(Устаревшее)
Эти функции потерь следует использовать для многочленной взаимоисключающей классификации, т.е. выбрать одну из N
классы. Также применимо, когда N = 2
,
Метки должны иметь горячее кодирование или могут содержать мягкие вероятности класса: конкретный пример может принадлежать классу A с вероятностью 50% и классу B с вероятностью 50%. Обратите внимание, что строго говоря, это не означает, что он принадлежит к обоим классам, но можно интерпретировать вероятности таким образом.
Прямо как в sigmoid
семья, tf.losses.softmax_cross_entropy
позволяет установить весовые коэффициенты в партии, то есть сделать некоторые примеры более важными, чем другие. Насколько я знаю, в тензорном потоке 1.3 нет встроенного способа установки весов классов.
[UPD] В тензорном потоке 1,5, v2
версия была представлена и оригинал softmax_cross_entropy_with_logits
потеря стала устаревшей. Единственное различие между ними заключается в том, что в более новой версии обратное распространение происходит как в логитах, так и в метках ( здесь обсуждается, почему это может быть полезно).
Семейство разреженных функций
tf.nn.sparse_softmax_cross_entropy_with_logits
tf.losses.sparse_softmax_cross_entropy
tf.contrib.losses.sparse_softmax_cross_entropy
(Устаревшее)
Как обычный softmax
выше, эти функции потерь должны использоваться для многочленной взаимоисключающей классификации, т.е. выбрать одну из N
классы. Разница заключается в кодировке меток: классы указываются как целые числа (индекс класса), а не как горячие векторы. Очевидно, что это не разрешает мягкие классы, но может сэкономить память, когда существуют тысячи или миллионы классов. Тем не менее, обратите внимание, что logits
аргумент должен по-прежнему содержать логиты для каждого класса, поэтому он потребляет как минимум [batch_size, classes]
объем памяти.
Как и выше, tf.losses
версия имеет weights
аргумент, который позволяет установить весовые коэффициенты в партии.
Отобранные софтмакс функции семейства
tf.nn.sampled_softmax_loss
tf.contrib.nn.rank_sampled_softmax_loss
tf.nn.nce_loss
Эти функции предоставляют еще одну альтернативу для работы с огромным количеством классов. Вместо того, чтобы вычислять и сравнивать точное распределение вероятностей, они вычисляют оценку потерь из случайной выборки.
Аргументы weights
а также biases
укажите отдельный полностью связанный слой, который используется для вычисления логитов для выбранного образца.
Как и выше, labels
закодированы не в горячем виде, а имеют форму [batch_size, num_true]
,
Выборочные функции подходят только для тренировок. Во время тестирования рекомендуется использовать стандарт softmax
потеря (или разреженная или горячая), чтобы получить фактическое распределение.
Еще одна альтернативная потеря tf.nn.nce_loss
, который выполняет контрастную оценку шума (если вам интересно, посмотрите это очень подробное обсуждение). Я включил эту функцию в семейство softmax, потому что NCE гарантирует приближение к softmax в пределе.
Хотя хорошо, что принятый ответ содержит гораздо больше информации, чем запрошенный, я чувствовал, что использование нескольких общих правил большого пальца сделает ответ более компактным и интуитивно понятным:
- Есть только одна реальная функция потерь. Это кросс-энтропия (КЭ) . Для особого случая двоичной классификации эта потеря называется двоичной CE (обратите внимание, что формула не меняется), а для небинарных или многоклассовых ситуаций она называется категориальной CE (CCE). Разреженные функции являются частным случаем категориального CE, где ожидаемые значения не кодируются в горячем виде, а являются целыми числами.
- У нас есть формула softmax, которая является активацией для мультиклассового сценария. Для бинарного сценария этой же формуле дается специальное имя - сигмовидная активация.
- Поскольку при работе с логарифмическими функциями иногда возникают числовые нестабильности (для экстремальных значений), TF рекомендует объединить уровень активации и уровень потерь в одну функцию. Эта комбинированная функция численно более стабильна. TF предоставляет эти комбинированные функции, и они имеют суффикс _with_logits.
Итак, давайте теперь подойдем к некоторым ситуациям. Скажем, существует простая проблема двоичной классификации - присутствует кошка на изображении или нет? Какой есть выбор функции активации и потери? Это будет сигмовидная активация и (бинарный)CE. Таким образом, можно использовать sigmoid_cross_entropy или, что более предпочтительно, sigmoid_cross_entropy_with_logits. Последняя сочетает в себе функцию активации и потери и должна быть численно стабильной.
Как насчет мультиклассовой классификации . Допустим, мы хотим знать, присутствует ли на изображении кошка, собака или осел. Какой есть выбор функции активации и потери? Это будет активация softmax и (категорический)CE. Таким образом, можно использовать softmax_cross_entropy или более предпочтительно softmax_cross_entropy_with_logits. Мы предполагаем, что ожидаемое значение закодировано в горячем режиме (100 или 010 или 001). Если (по какой-то странной причине) это не так и ожидаемое значение является целым числом (либо 1, либо 2, либо 3), вы можете использовать «разреженные» аналоги вышеуказанных функций.
Возможен и третий случай. У нас может быть классификация с несколькими ярлыками . Таким образом, на одном изображении могут быть собака и кошка. Как мы с этим справимся? Хитрость здесь в том, чтобы рассматривать эту ситуацию как множественные проблемы бинарной классификации - в основном кошка или не кошка / собака, или без собаки и осла, или без осла. Определите потери для каждой из трех (двоичных классификаций) и затем сложите их. По сути, это сводится к использованию потери sigmoid_cross_entropy_with_logits.
Это отвечает на 3 конкретных вопроса, которые вы задали. Все, что необходимо, - это перечисленные выше функции. Вы можете игнорировать семейство tf.contrib, которое устарело и не должно использоваться.
Однако для версии 1.5 softmax_cross_entropy_with_logits_v2
должен использоваться вместо этого, при использовании его аргумента с argument key=...
как после>
softmax_cross_entropy_with_logits_v2(_sentinel=None, labels=y,\
logits = my_prediction, dim=-1, name=None)