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

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

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

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

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

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

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


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

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

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


Обновить

Я включил InfogainLossLayer как предложено Шай. Я также добавил еще один пользовательский слой, который строит матрицу 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. !!

29

Решение

Почему бы вам не использовать InfogainLoss слой, чтобы компенсировать дисбаланс в вашем тренировочном наборе?

Потеря Infogain определяется с использованием весовой матрицы H (в вашем случае 2 на 2) смысл его записей

[cost of predicting 1 when gt is 0,    cost of predicting 0 when gt is 0
cost of predicting 1 when gt is 1,    cost of predicting 0 when gt is 1]

Таким образом, вы можете установить записи H отражать разницу между ошибками в прогнозировании 0 или 1.

Вы можете найти, как определить матрицу H для кофе в эта тема.

Что касается выборочных весов, вы можете найти эта почта Интересно: это показывает, как изменить SoftmaxWithLoss слой для учета веса образца.


Недавно была предложена модификация кросс-энтропийной потери Цунг-Йи Лин, Прия Гоял, Росс Гиршик, Кайминг Хе, Петр Доллар Фокусная потеря для обнаружения плотных объектов, (ICCV 2017).
Идея фокальной потери заключается в назначении разного веса для каждого примера на основе относительной сложности прогнозирования этого примера (скорее на основе размера класса и т. Д.). С того короткого времени, которое я получил, чтобы поэкспериментировать с этой потерей, я чувствую себя лучше "InfogainLoss" с весами размера класса.

20

Другие решения

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

Расчет веса

Вес каждого класса обратно пропорционален номеру изображения в этом классе. Вот фрагмент кода для расчета веса для всех классов с использованием NumPy,

cls_num = []
# train_labels is a list of class labels for all training samples
# the labels are in range [0, n-1] (n classes in total)
train_labels = np.asarray(train_labels)
num_cls = np.unique(train_labels).size

for i in range(num_cls):
cls_num.append(len(np.where(train_labels==i)[0]))

cls_num = np.array(cls_num)

cls_num = cls_num.max()/cls_num
x = 1.0/np.sum(cls_num)

# the weight is an array which contains weight to use in CrossEntropyLoss
# for each class.
weight = x*cls_num
0

По вопросам рекламы [email protected]