Что такое logits, softmax и softmax_cross_entropy_with_logits?

Я просматривал документы по тензорному API здесь. В документации тензорного потока они использовали ключевое слово, называемое logits. Что это? Во многих методах в документации API это написано как

tf.nn.softmax(logits, name=None)

Если написано, что эти logits являются только Tensors, зачем сохранять другое имя, например logits?

Другое дело, что есть два метода, которые я не смог дифференцировать. Они были

tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

Каковы различия между ними? Документы мне не понятны. Я знаю, что делает tf.nn.softmax. Но не другой. Пример будет действительно полезным.

Ответ 1

Logits просто означает, что функция работает с немасштабированным выходом более ранних слоев и что относительный масштаб для понимания единиц измерения является линейным. В частности, это означает, что сумма входных данных может не равняться 1, что значения не являются вероятностями (у вас может быть значение 5).

tf.nn.softmax выдает только результат применения функции softmax к входному тензору. Softmax "сдавливает" входы так, что sum(input) = 1: это способ нормализации. Форма вывода softmax совпадает с формой ввода: она просто нормализует значения. Выходные данные softmax можно интерпретировать как вероятности.

a = tf.constant(np.array([[.1, .3, .5, .9]]))
print s.run(tf.nn.softmax(a))
[[ 0.16838508  0.205666    0.25120102  0.37474789]]

Напротив, tf.nn.softmax_cross_entropy_with_logits вычисляет кросс-энтропию результата после применения функции softmax (но делает все это вместе более математически аккуратно). Это похоже на результат:

sm = tf.nn.softmax(x)
ce = cross_entropy(sm)

Перекрестная энтропия является суммарной метрикой: она суммирует элементы. Вывод tf.nn.softmax_cross_entropy_with_logits для tf.nn.softmax_cross_entropy_with_logits формы [2,5] имеет форму [2,1] (первое измерение рассматривается как пакет).

Если вы хотите провести оптимизацию, чтобы минимизировать кросс-энтропию и мягкое увеличение после последнего слоя, вы должны использовать tf.nn.softmax_cross_entropy_with_logits вместо того, чтобы делать это самостоятельно, потому что он охватывает численно нестабильные угловые случаи математически правильным образом. В противном случае, вы в конечном итоге взломаете его, добавив маленькие эпсилоны здесь и там.

Отредактировано 2016-02-07: Если у вас есть метки одного класса, где объект может принадлежать только одному классу, вы можете теперь рассмотреть возможность использования tf.nn.sparse_softmax_cross_entropy_with_logits чтобы вам не приходилось конвертировать ваши метки в плотные горячий массив. Эта функция была добавлена после выпуска 0.6.0.

Ответ 2

Краткая версия:

Предположим, что у вас есть два тензора, где y_hat содержит вычисленные оценки для каждого класса (например, от y = W * x + b) и y_true содержит горячие кодированные истинные метки.

y_hat  = ... # Predicted label, e.g. y = tf.matmul(X, W) + b
y_true = ... # True label, one-hot encoded

Если вы интерпретируете оценки в y_hat как ненормализованные логарифмические вероятности, то они logits.

Кроме того, общая потеря поперечной энтропии, вычисленная таким образом:

y_hat_softmax = tf.nn.softmax(y_hat)
total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))

по существу эквивалентно полной потери поперечной энтропии, вычисленной с помощью функции softmax_cross_entropy_with_logits():

total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))

Длинная версия:

В выходном слое вашей нейронной сети вы, вероятно, вычислите массив, который содержит оценки классов для каждого из ваших учебных экземпляров, например, из расчета y_hat = W*x + b. Чтобы служить примером, ниже я создал y_hat как массив 2 x 3, где строки соответствуют экземплярам обучения, а столбцы соответствуют классам. Итак, здесь есть 2 учебных примера и 3 класса.

import tensorflow as tf
import numpy as np

sess = tf.Session()

# Create example y_hat.
y_hat = tf.convert_to_tensor(np.array([[0.5, 1.5, 0.1],[2.2, 1.3, 1.7]]))
sess.run(y_hat)
# array([[ 0.5,  1.5,  0.1],
#        [ 2.2,  1.3,  1.7]])

Обратите внимание, что значения не нормируются (т.е. строки не складываются до 1). Чтобы нормализовать их, мы можем применить функцию softmax, которая интерпретирует вход как ненормализованные логарифмические вероятности (aka logits) и выводит нормированные линейные вероятности.

y_hat_softmax = tf.nn.softmax(y_hat)
sess.run(y_hat_softmax)
# array([[ 0.227863  ,  0.61939586,  0.15274114],
#        [ 0.49674623,  0.20196195,  0.30129182]])

Важно понять, что говорит softmax. Ниже я показал таблицу, которая более четко отражает результат выше. Можно видеть, что, например, вероятность того, что учебный экземпляр 1 будет "Класс 2", равна 0,619. Вероятности класса для каждого учебного экземпляра нормированы, поэтому сумма каждой строки равна 1.0.

                      Pr(Class 1)  Pr(Class 2)  Pr(Class 3)
                    ,--------------------------------------
Training instance 1 | 0.227863   | 0.61939586 | 0.15274114
Training instance 2 | 0.49674623 | 0.20196195 | 0.30129182

Итак, теперь у нас есть вероятности классов для каждого учебного экземпляра, где мы можем взять argmax() каждой строки для генерации окончательной классификации. Сверху мы можем сгенерировать, что учебный экземпляр 1 относится к "классу 2", а учебный экземпляр 2 относится к "классу 1".

Правильны ли эти классификации? Нам нужно измерить истинные метки из набора тренировок. Вам понадобится один горячий закодированный массив y_true, где снова строки - это учебные экземпляры, а столбцы - классы. Ниже я создал пример y_true одного горячего массива, где истинная метка для учебного экземпляра 1 является "Класс 2", а истинной меткой для учебного экземпляра 2 является "Класс 3".

y_true = tf.convert_to_tensor(np.array([[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]))
sess.run(y_true)
# array([[ 0.,  1.,  0.],
#        [ 0.,  0.,  1.]])

Является ли распределение вероятности в y_hat_softmax близким к распределению вероятности в y_true? Мы можем использовать кросс-энтропийную потерю для измерения ошибки.

Формула потери кросс-энтропии

Мы можем вычислить потери поперечной энтропии по-разному и увидеть результаты. Ниже мы видим, что учебный экземпляр 1 имеет потерю 0,479, тогда как учебный экземпляр 2 имеет более высокую потерю 1.200. Этот результат имеет смысл, потому что в нашем примере выше y_hat_softmax показал, что учебный экземпляр 1 наивысшая вероятность была для "класса 2", которая соответствует учебному экземпляру 1 в y_true; однако предсказание для учебного экземпляра 2 показало наивысшую вероятность для "класса 1", который не соответствует истинному классу "класс 3".

loss_per_instance_1 = -tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1])
sess.run(loss_per_instance_1)
# array([ 0.4790107 ,  1.19967598])

То, что мы действительно хотим, это полная потеря над всеми учебными примерами. Поэтому мы можем вычислить:

total_loss_1 = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1]))
sess.run(total_loss_1)
# 0.83934333897877944

Использование softmax_cross_entropy_with_logits()

Вместо этого мы можем вычислить полную потерю поперечной энтропии с помощью функции tf.nn.softmax_cross_entropy_with_logits(), как показано ниже.

loss_per_instance_2 = tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true)
sess.run(loss_per_instance_2)
# array([ 0.4790107 ,  1.19967598])

total_loss_2 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
sess.run(total_loss_2)
# 0.83934333897877922

Обратите внимание, что total_loss_1 и total_loss_2 дают существенно эквивалентные результаты с некоторыми небольшими отличиями в самых последних цифрах. Тем не менее, вы также можете использовать второй подход: он занимает одну меньшую строку кода и накапливает меньше числовой ошибки, потому что softmax выполняется для вас внутри softmax_cross_entropy_with_logits().

Ответ 3

tf.nn.softmax вычисляет прямое распространение через слой softmax. Вы используете его во время оценки модели при вычислении вероятностей, которые выводит модель.

tf.nn.softmax_cross_entropy_with_logits вычисляет стоимость слоя softmax. Он используется только во время обучения.

Логиты - это ненормализованные логарифмические вероятности, выводимые моделью (значения, выданные до того, как к ним применяется нормализация softmax).

Ответ 4

В ответах есть достаточно описания для заданного вопроса.

Добавив к этому, Tensorflow оптимизировал работу приложения активации, а затем вычислил стоимость, используя свою собственную активацию, за которой следуют функции затрат. Следовательно, рекомендуется использовать: tf.nn.softmax_cross_entropy() over tf.nn.softmax(); tf.nn.cross_entropy()

Вы можете найти заметную разницу между ними в ресурсоемкой модели.

Ответ 5

Если кому-то нужна простая визуализация, я нашел видео на YouTube, в котором объясняется логика перекрестного сравнения энтропии. Он охватывает тему полиномиальной логистической классификации.

Вот

Ответ 6

То, что когда-либо идет к softmax является logit, это то, что Дж. Хинтон повторяет в видео клипах все время.