Несбалансированные наборы данных — распространенная проблема в задачах классификации, когда количество экземпляров в одном классе значительно меньше, чем количество экземпляров в другом классе. Это приведет к предвзятым моделям, которые плохо работают с классом меньшинства.

Взвешенная функция потерь — это модификация стандартной функции потерь, используемой при обучении модели. Веса используются для назначения более высокого штрафа за неправильную классификацию класса меньшинства. Идея состоит в том, чтобы сделать модель более чувствительной к классу меньшинства за счет увеличения стоимости неправильной классификации этого класса.

Наиболее распространенный способ реализации взвешенной функции потерь — присвоить больший вес классу меньшинства и меньший вес классу большинства. Веса могут быть обратно пропорциональны частоте классов, так что класс меньшинства получает больший вес, а класс большинства получает меньший вес.

В этом посте я покажу вам, как добавить веса к общим функциям потерь pytorch.

Бинарная классификация

Функция torch.nn.BCEWithLogitsLoss — это обычно используемая функция потерь для задач бинарной классификации, где выход модели представляет собой значение вероятности от 0 до 1. Она сочетает в себе сигмовидную функцию активации с бинарной кросс-энтропийной потерей.

Для несбалансированных наборов данных, где количество экземпляров в одном классе значительно меньше, чем в другом, функцию torch.nn.BCEWithLogitsLoss можно изменить, добавив параметр веса в функцию потерь. Параметр веса позволяет назначать разные веса для положительных и отрицательных классов.

Параметр веса представляет собой тензор размера [batch_size], который содержит значение веса для каждого образца в пакете.

Вот пример:

import torch
 import torch.nn as nn
 ​
 # Define the BCEWithLogitsLoss function with weight parameter
 weight = torch.tensor([0.1, 0.9]) # higher weight for positive class
 criterion = nn.BCEWithLogitsLoss(weight=weight)
 ​
 # Generate some random data for the binary classification problem
 input = torch.randn(3, 1)
 target = torch.tensor([[0.], [1.], [1.]])
 ​
 # Compute the loss with the specified weight
 loss = criterion(input, target)
 ​
 print(loss)

мы устанавливаем вес положительного класса на 0,9 и вес отрицательного класса на 0,1. input тензор содержит логиты, предсказанные моделью. target тензор содержит метки истинности для задачи бинарной классификации.

Примечание. Установите веса вручную на 0,1 и 0,9, исходя из предположения, что положительный класс имеет только 10% образцов.

Чтобы рассчитать веса, вы можете вычислить вес для каждого класса следующим образом:

weight_for_class_i = total_samples / (num_samples_in_class_i * num_classes)

где total_samples — общее количество выборок в наборе данных, num_samples_in_class_i — количество выборок в классе i, а num_classes — общее количество классов (в случае двоичной классификации num_classes равно 2).

Если у вас есть проблема бинарной классификации с 1000 выборками, где 900 выборок относятся к классу 0, а 100 — к классу 1, рассчитывайте веса следующим образом:

weight_for_class_0 = 1000 / (900 * 2) = 0.5556
 weight_for_class_1 = 1000 / (100 * 2) = 5.0000

и весовой параметр torch.nn.BCEWithLogitsLoss для тензора весов размера 2:

import torch
 import torch.nn as nn
 ​
 weight = torch.tensor([0.5556, 5.0000]) # higher weight for class 1
 criterion = nn.BCEWithLogitsLoss(weight=weight)

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

В дополнение к параметру weight, torch.nn.BCEWithLogitsLoss также имеет параметр pos_weight, который представляет собой более простой способ указать вес для положительного класса в задаче бинарной классификации.

Параметр pos_weight — это скаляр, представляющий вес для положительного класса. Это эквивалентно установке для параметра weight значения [1, pos_weight], где вес для отрицательного класса равен 1.

import torch
 import torch.nn as nn
 ​
 # Define the BCEWithLogitsLoss function with pos_weight parameter
 pos_weight = torch.tensor([3.0])  # higher weight for positive class
 criterion = nn.BCEWithLogitsLoss(pos_weight=pos_weight)
 ​
 # Generate some random data for the binary classification problem
 input = torch.randn(3, 1)
 target = torch.tensor([[0.], [1.], [1.]])
 ​
 # Compute the loss with the specified pos_weight
 loss = criterion(input, target)
 ​
 print(loss)

Установите для параметра pos_weight значение 3.0, что означает, что вес для положительного класса в 3 раза больше, чем для отрицательного класса. Мы вычисляем убыток, используя функцию criterion с указанным pos_weight.

Если вы укажете оба параметра weight и pos_weight, параметр pos_weight имеет приоритет над весом для положительного класса.

Если вы установите для pos_weight значение, отличное от 1,0, вес для положительного класса в тензоре weight будет игнорироваться.

Мультиклассовая классификация

Cross-Entropy Loss обычно используется в задачах классификации нескольких классов. Он вычисляет отрицательное логарифмическое правдоподобие предсказанного распределения классов по сравнению с истинным распределением классов. При работе с несбалансированными наборами данных некоторые классы могут иметь больше или меньше выборок, чем другие, и это может привести к смещению прогнозов модели в сторону более частых классов.

Чтобы решить эту проблему, можно использовать параметр weight в torch.nn.CrossEntropyLoss для применения веса к каждому классу. Веса могут быть указаны в виде одномерного тензора или списка и должны иметь ту же длину, что и количество классов. Тогда потери рассчитываются следующим образом:

loss(x, y) = -weight[y] * log(exp(x[y]) / sum(exp(x)))

где x — результат модели, y — целевой класс, exp — экспоненциальная функция, а sum(exp(x)) — сумма экспонент по всем классам. Вес для истинного класса умножается на отрицательную логарифмическую вероятность истинного класса, поэтому потеря взвешивается для недопредставленных классов.

Вот пример использования параметра weight в torch.nn.CrossEntropyLoss для задачи классификации с тремя несбалансированными классами.

Предположим, у нас есть набор данных с 1000 выборками, а целевая переменная имеет три класса: класс A, класс B и класс C. Распределение выборок в наборе данных выглядит следующим образом:

  • Класс А: 100 образцов
  • Класс B: 800 образцов
  • Класс C: 100 образцов

Чтобы устранить дисбаланс классов, мы можем присвоить каждому классу вес, обратно пропорциональный его частоте. Вес каждого класса можно рассчитать следующим образом:

  • Класс А: 1000/100 = 10
  • Класс В: 1000/800 = 1,25
  • Класс С: 1000 / 100 = 10

Мы можем создать тензор весов, отражающий эти веса, следующим образом:

import torch
 ​
 weights = torch.tensor([10, 1.25, 10])

И используйте этот весовой тензор в torch.nn.CrossEntropyLoss следующим образом:

loss_fn = torch.nn.CrossEntropyLoss(weight=weights)

Когда мы используем эту функцию потерь для обучения модели, классы A и C будут вносить больший вклад в потери, чем класс B, из-за взвешенного эффекта тензора веса. Это помогает сбалансировать влияние различных классов на обучение модели и может улучшить производительность модели в недостаточно представленных классах.

В PyTorch параметр torch.nn.CrossEntropyLoss, label_smoothing используется для сглаживания целевых значений с горячим кодированием, чтобы побудить модель быть менее уверенной в своих прогнозах и предотвратить переоснащение обучающих данных.

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

Параметр label_smoothing принимает значение от 0 до 1, 0 означает, что сглаживание не применяется, а 1 означает, что применяется максимальное сглаживание. Типичное значение label_smoothing составляет около 0,1. Тогда потери рассчитываются следующим образом:

loss(x, y) = -((1 - label_smoothing) * log(exp(x[y]) / sum(exp(x))) + (label_smoothing / K))

x — результат модели, y — целевой класс, exp — экспоненциальная функция, sum(exp(x)) — сумма экспонент по всем классам, а K — количество классов. Коэффициент сглаживания умножается на равномерную априорную вероятность для каждого класса, которая равна 1/K, и получается более обобщенная модель.

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

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

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

В общем, параметр weight полезен при работе с несбалансированными наборами данных, где стоимость неправильной классификации не одинакова для всех классов. С другой стороны, параметр label_smoothing полезен при работе с переобучением и высоконадежными прогнозами, когда модель слишком уверена в своих прогнозах и не исследует широкий спектр решений.

оба параметра weight и label_smoothing можно использовать вместе для решения проблем дисбаланса классов и переобучения в задачах классификации с несколькими классами.

Однако два параметра не всегда могут использоваться вместе, и их использование зависит от конкретных характеристик набора данных и рассматриваемой проблемы. Важно поэкспериментировать с различными комбинациями гиперпараметров, включая label_smoothing и weight, чтобы определить наилучший подход к данной проблеме.

Многоуровневая классификация

Классификация с несколькими метками — это тип задачи классификации, когда объект или экземпляр могут одновременно принадлежать к одному или нескольким классам. Другими словами, вместо того, чтобы назначать каждому экземпляру одну метку, ему можно назначить несколько меток. Это отличается от традиционных задач классификации, где каждому экземпляру присваивается одна метка.

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

мы можем установить параметр weight, и pos_weightподобно двоичной классификации.

В итоге

Несбалансированные наборы данных — распространенная проблема в машинном обучении, когда один класс данных может быть значительно более распространенным, чем другой. Это может привести к проблемам при попытке обучить модель классификации, поскольку модель может стать смещенной в сторону более распространенного класса. Одно из решений этой проблемы проблема заключается в использовании функции взвешенных потерь во время обучения. Функция взвешенных потерь присваивает более высокий вес ошибкам, сделанным в классе меньшинства, тем самым помогая модели уделять больше внимания этим образцам. Используя функцию взвешенных потерь, модель может научиться лучше различать классы меньшинства и большинства, что приводит к повышению производительности несбалансированных наборов данных.

Если этот пост был вам полезен, пожалуйста, хлопайте👏 и подписывайтесь на меня😊.