Что такое 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, это то, что Дж. Хинтон повторяет в видео клипах все время.