Какая функция потерь для задач мультиклассовой классификации с несколькими метками в нейронных сетях?

64

Я тренирую нейронную сеть, чтобы классифицировать набор объектов в n-классы. Каждый объект может принадлежать нескольким классам одновременно (несколько классов, несколько меток).

Я читал, что для многоклассовых задач обычно рекомендуется использовать softmax и категориальную кросс-энтропию в качестве функции потерь вместо mse, и я более или менее понимаю, почему.

Для моей проблемы мультимаркировки не имеет смысла использовать softmax, конечно, поскольку вероятность каждого класса должна быть независимой от другой. Итак, мой последний слой - просто сигмовидные единицы, которые раздавливают свои входные данные в диапазоне вероятностей 0..1 для каждого класса.

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

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

Я использую Python и Keras для обучения в случае, если это имеет значение.

AKZENT
источник
1
Я считаю, что softmax - это «сигмовидные единицы, которые раздавливают свои входные данные в диапазоне вероятностей 0..1 для каждого класса».
Хонг Уй
Вы можете использовать softmax в качестве функции потерь, а затем использовать вероятности для мультиметки ваших данных.
бальбоа

Ответы:

30

Если вы используете keras, просто поместите сигмоиды на выходной слой, а binary_crossentropy на функцию стоимости.

Если вы используете tenorflow, то можете использовать sigmoid_cross_entropy_with_logits . Но для моего случая эта функция прямой потери не сходилась. Таким образом, я в конечном итоге использовал явную потерю сигмоидальной перекрестной энтропии . Вы можете сделать свой собственный, как в этом примере(yln(sigmoid(logits))+(1y)ln(1sigmoid(logits)))

Сигмоид, в отличие от softmax, не дает распределения вероятностей вокруг качестве выходных данных, но независимых вероятностей.nclasses

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

Алок Наяк
источник
Уважаемый Алок, можете ли вы объяснить ОП, как они будут использовать эту функцию и почему это имеет смысл? Как вы увидите в туре , ссылки только на ответы не приветствуются на сайте.
Антуан Верне
Хорошее краткое объяснение можно увидеть в keras github: github.com/fchollet/keras/issues/741
Дрор
1
Не рекомендуется писать свою собственную функцию стоимости при использовании кросс-энтропии - это может привести к проблемам с числовой стабильностью. См. Github.com/tensorflow/tensorflow/issues/2462 для обсуждения.
kbrose
Одна вещь - мультиклавиша, другая вещь - мультиклавиша мультикласс. Sigmoid сдавливает ваш вывод между 0 и 1, но у OP есть несколько классов, поэтому выходы должны быть Eg 0 - 10. Таким образом, выходы должны выглядеть так: [0,5,2,3,1] <--- это не то, что сигмоид делает.
Mimoralea
Должен ли я использовать tf.round (logits) перед использованием в функции стоимости или я могу напрямую использовать logits из скрытого слоя в tf.nn.sigmoid ....?
Монах
9

ОБНОВЛЕНИЕ (18/04/18): Старый ответ все еще оказался полезным для моей модели. Хитрость заключается в том, чтобы моделировать функцию разделения и распределения по отдельности, используя, таким образом, силу softmax.

Считайте, что ваш вектор наблюдения содержит меток. (1, если образец i содержит метку m, 0 в противном случае). Таким образом, цель состоит в том, чтобы смоделировать матрицу для каждого образца. Следовательно, модель оценивает . Рассмотрим расширение чтобы получить два свойства:ymyim=δimF(yi,xi)=logP(yi|xi)yim=ZP(ym)

  1. Функция распределения:mP(ym)=1
  2. Функция разделения: оценивает количество метокZ

Тогда это вопрос моделирования двух по отдельности. Функция распределения лучше всего моделируется со слоем softmax , а функция разделения может моделироваться линейной единицей (на практике я ограничил ее как . Более сложное моделирование, такое как единица Пуассона, вероятно, будет работать лучше). Затем вы можете применить распределенную потерю (KL для распределения и MSE для раздела) или попробовать следующую потерю для их продукта.max(0.01,output)

На практике выбор оптимизатора также имеет огромное значение. Мой опыт работы с подходом факторизации заключается в том, что он лучше всего работает под Adadelta (Adagrad у меня не работает, пока не пробовал RMSprop, производительность SGD зависит от параметров).

Побочный комментарий к сигмовидной кишке: я, конечно, попробовал сигмоидную + кроссентропию, и это не сработало. Модель склонна прогнозировать только и не смогла уловить изменение функции распределения. (ака, это как-то весьма полезно для моделирования раздела и может быть математическая причина)Z

ОБНОВЛЕНИЕ : (Случайная мысль) Кажется, использование процесса Дирихле позволит включить некоторые из предшествующих по количеству меток?

ОБНОВЛЕНИЕ : Экспериментально, измененная дивергенция KL все еще склонна давать вывод мультикласса, а не вывод нескольких меток.


(Старый ответ)

Мой опыт с сигмоидальной перекрестной энтропией был не очень приятным. На данный момент я использую модифицированную KL-дивергенцию. Принимает форму

Loss(P,Q)=x|P(x)Q(x)||logP(x)Q(x)|=x|(P(x)Q(x))logP(x)Q(x)|
Где - это целевое псевдораспределение, а - это предсказанное псевдораспределение (но функция на самом деле симметрична, поэтому это не имеет значения)P(x)Q(x)

Они называются псевдораспределениями за ненормализованность. Таким образом, вы можете иметь если у вас есть 2 метки для конкретного образца.xP(x)=2

Керас импелментация

def abs_KL_div(y_true, y_pred):
    y_true = K.clip(y_true, K.epsilon(), None)
    y_pred = K.clip(y_pred, K.epsilon(), None)
    return K.sum( K.abs( (y_true- y_pred) * (K.log(y_true / y_pred))), axis=-1)
должны увидеть
источник
на моем конкретном наборе данных, adamбыл намного лучше, чемrmsprop
Шади
Если вы используете такую ​​потерю для обучения, как это сделать на этапе тестирования? Также используйте softmax для прогноза, но как выбрать порог для определения классов с несколькими метками?
karl_TUM
1

Я еще не использовал керас. Взяв, например, кофе, вы можете использовать его SigmoidCrossEntropyLossLayerдля решения нескольких задач.

Минтака
источник
1
Хотите объяснить, почему это хороший подход?
Firebug
0

На самом деле в tenorsflow вы все еще можете использовать sigmoid_cross_entropy_meanфункцию расчета потерь в мульти-лейбле, я очень подтверждаю это

уникальная обезьяна
источник
Дайте нам ссылку на документацию
Ивелин
0

Я новичок здесь, но я постараюсь дать ему шанс с этим вопросом. Я искал то же самое, что и вы, и, наконец, я нашел очень хороший учебник по классификации мультиклассов keras @ http://machinelearningmastery.com/multi-class-classification-tutorial-keras-deep-learning-library/ .

Автор этого руководства использует функцию категориальной кросс-энтропийной потери, а также существует другая ветка, которая может помочь вам найти решение @ здесь .

Вилли Сатрио Нугрохо
источник
3
Это не только мультикласс, это также мульти лейблы.
Монах