Борьба с дисбалансом классов: масштабирование вклада в потери и сгд

(Обновление к этому вопросу было добавлено.)

Я аспирант в университете Гента, Бельгия; мое исследование касается распознавания эмоций с помощью глубоких сверточных нейронных сетей. Я используюCaffe рамки для реализации CNN.

Недавно я столкнулся с проблемой дисбаланса классов. Я использую 9216 учебных образцов, ок. 5% помечены положительно (1), остальные образцы помечены отрицательно (0).

Я используюSigmoidCrossEntropyLoss слой для расчета потерь. При обучении потери уменьшаются, а точность чрезвычайно высока даже после нескольких эпох. Это связано с дисбалансом: сеть просто всегда прогнозирует отрицательный (0).(Точность и отзыв равны нулю, подтверждая это утверждение)

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

Я добавил в Caffe только один специальный слой: для отчета по другим показателям, таким как точность и отзыв. Мой опыт работы с кодом Caffe ограничен, но у меня большой опыт написания кода на C ++.

Может ли кто-нибудь помочь мне или указать мне в правильном направлении, как настроитьSigmoidCrossEntropyLoss а такжесигмоид слои для размещения следующих изменений:

скорректировать вклад выборки в общую потерю в зависимости от комбинации «предсказание-истина» (истинно положительный, ложноположительный, истинно отрицательный, ложно отрицательный).масштабировать обновление веса, выполняемое стохастическим градиентным спуском, в зависимости от дисбаланса в партии (отрицательные и положительные значения).

Заранее спасибо!

Обновить

Я включилInfogainLossLayer как предложеноШай, Я также добавил еще один пользовательский слой, который строит матрицу infogainH на основе дисбаланса в текущей партии.

В настоящее время матрица настроена следующим образом:

H(i, j) = 0          if i != j
H(i, j) = 1 - f(i)   if i == j (with f(i) = the frequency of class i in the batch)

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

Я проверил это на дисбалансе 10: 1. Результаты показали, что сейчас сеть изучает полезные вещи:(результаты после 30 эпох)

Точность ок. ~ 70% (по сравнению с ~ 97%);Точность ок. ~ 20% (по сравнению с 0%);Напомним, ок. ~ 60% (по сравнению с 0%).

Эти цифры были достигнуты примерно в 20 эпох и после этого существенно не изменились.

!! Вышеуказанные результаты являются лишь подтверждением концепции, они были получены путем обучения простой сети с несбалансированным набором данных 10: 1. !!

Ответы на вопрос(2)

Ваш ответ на вопрос