(добавлено обновление к этому вопросу.)
Я аспирант в университете Гента, Бельгия; мои исследования касаются распознавания эмоций глубокими сверточными нейронными сетями. Я использую Caffe для реализации CNN.
Недавно я столкнулся с проблемой дисбаланса классов. Я использую 9216 учебных образцов, прибл. 5% помечены положительно (1), остальные образцы обозначены отрицательно (0).
Я использую слой SigmoidCrossEntropyLoss для вычисления потерь. Во время обучения потери уменьшаются, и точность достигается даже после нескольких эпох. Это связано с дисбалансом: сеть просто всегда предсказывает отрицательный (0). (Точность и отзыв ноль, поддерживая это требование)
Чтобы решить эту проблему, я хотел бы масштабировать вклад в потерю в зависимости от комбинации предсказания-истины (строго наказать ложные негативы). Мой наставник также посоветовал мне использовать масштабный коэффициент, когда backpropagating через стохастический градиентный спуск (sgd): фактор будет коррелирован с дисбалансом в партии. Партия, содержащая только отрицательные образцы, вообще не обновляет веса.
Я добавил только один пользовательский слой в Caffe: чтобы сообщить другие показатели, такие как точность и отзыв. Мой опыт с кодом Caffe ограничен, но у меня много опыта написания кода на С++.
Может ли кто-нибудь помочь мне или указать мне в правильном направлении, как настроить SigmoidCrossEntropyLoss и Sigmoid для размещения следующих изменений:
- отрегулировать вклад образца в общую потерю в зависимости от комбинации предсказания-истины (истинный положительный, ложноположительный, истинный отрицательный, ложноотрицательный).
- масштабировать обновление веса, выполняемое стохастическим градиентным спуском, в зависимости от дисбаланса в партии (отрицательные и положительные).
Спасибо заранее!
Update
Я включил InfogainLossLayer, как было предложено Shai. Я также добавил еще один настраиваемый уровень, который создает infogain-матрицу H
на основе дисбаланса в текущей партии.
В настоящее время матрица конфигурируется следующим образом:
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.!!