Практические заметки по интерактивной сегментации 2
Одна из проблем, которую необходимо учитывать при обучении сети глубокому обучению, — это выбор функции потерь. В последние годы Focal Loss был очень популярен в сегментации, но во многих проектах все еще используются базовые функции потерь, такие как Dice и CrossEntropy, и разница в эффекте неудивительна.Видно, что есть еще много мест, которые стоит изучить в традиционных Потеря.
В этой статье в основном проводится анализ функции потерь в стиле справочника в задаче сегментации и классификации, а также описываются характеристики различных потерь, которые я знаю, с упором на фактический метод расчета, чтобы интуитивно понять их значение.
Версия, на которой основан эксперимент, — это текущая стабильная версия pytorch-1.7.1.
содержание
Детали формулы расчета
Формула расчета общих потерь выполняется, поэтому следующие формулы записывают толькорасчетная часть.
nn.L1Loss
Это MAE (средняя абсолютная ошибка), а формула расчетаЕсть два режима среднего и суммы, которые контролируются редукцией.
пример
target = torch.tensor([1,1,0,1,0]).float()
output = torch.tensor([1,0,0,0,0]).float()
loss_fn = torch.nn.L1Loss(reduction='mean')
loss = loss_fn(output, target)
print(loss)
loss_fn = torch.nn.L1Loss(reduction='sum')
loss = loss_fn(output, target)
print(loss)
результат
tensor(0.4000)
tensor(2.)
nn.MSELoss
Как следует из названия, среднеквадратическая ошибка, которая является обычным членом L2, рассчитывается какЕсть два режима среднего и суммы, которые контролируются редукцией.
пример
target = torch.tensor([1,0,0,1,0]).float()
output = torch.tensor([1,2,0,0,0]).float()
loss_fn = torch.nn.MSELoss(reduction='mean')
loss = loss_fn(output, target)
print(loss)
loss_fn = torch.nn.MSELoss(reduction='sum')
loss = loss_fn(output, target)
print(loss)
результат
tensor(1.)
tensor(5.)
nn.SmoothL1Loss
Небольшое сглаживание выполняется на уровне L1, который менее чувствителен к выбросам, чем MSELoss.
Используется в Fast-RCNN, чтобы избежать взрывных градиентов.
nn.NLLLoss
отрицательная логарифмическая потеря вероятности для обучения классификаторов n-класса, Для несбалансированных наборов данных к категориям можно добавить веса, формула
Ожидаемая форма ввода,в— размер партии, а C — количество категорий;
Вычислите отрицательное значение вероятности соответствующей категории цели каждого случая, а затем получите среднее значение/сумму, которое обычно используется в сочетании с LogSoftMax для получения логарифмической вероятности.
пример
target = torch.tensor([1,0,3])
output = torch.randn(3,5)
print(output)
loss_fn = torch.nn.NLLLoss()
loss = loss_fn(output, target)
print(loss)
результат
tensor([[ 0.1684, -0.2378, -0.5189, 1.5398, -1.1828],
[-0.4370, 0.3035, 1.3718, -0.2823, -0.4714],
[ 0.2863, -0.3008, 0.8902, 0.4902, -0.4487]])
tensor(0.0615)
результат
nn.CrossEntropyLoss
Классический убыток, формула расчета:
Это эквивалентно первому сопоставлению выходного значения с каждым значением через softmax в, и на пространстве, где сумма равна 1. Есть надежда, что чем меньше потери, соответствующие правильному классу, тем лучше, так что даспросить, Пучоксопоставить сЧем выше вероятность правильных элементов, тем меньше общий проигрыш.
CrossEntropyLoss(x) в факеле эквивалентен NLLLoss(LogSoftmax(x))
Ожидаемый ввод представляет собой ненормализованную оценку, а форма ввода такая же, как у NLL, т. е.
Пример 1
target = torch.tensor([1,0,3])
output = torch.randn(3,5)
print(output)
loss_fn = torch.nn.CrossEntropyLoss()
loss = loss_fn(output, target)
print(loss)
результат
tensor([[-0.6324, 0.1134, 0.0695, -1.6937, -0.3634],
[ 1.2044, 2.0876, -1.6558, -0.4869, -0.8516],
[-0.7290, -0.4808, 0.8488, -0.3595, -1.3598]])
tensor(1.4465)
Пример 2 — CrossEntropyLoss, реализованный в numpy
target = torch.tensor([1,0,3])
output = torch.randn(3,5)
print(output)
result = np.array([0.0, 0.0, 0.0])
for ix in range(3):
log_sum = 0.0
for iy in range(5):
if(iy==target[ix]): result[ix] += -output[ix, iy]
log_sum += exp(output[ix, iy])
result[ix] += log(log_sum)
print(result)
print(np.mean(result))
loss_fn = torch.nn.CrossEntropyLoss()
loss = loss_fn(output, target)
print(loss)
результат
tensor([[ 1.6021, 0.5762, -1.9105, -1.0844, -0.0256],
[ 1.0483, 0.8033, 1.1037, -1.2296, 1.2662],
[ 0.7592, -2.6041, -1.6092, -0.2643, 1.2362]])
[1.52833433 1.43165374 2.15453246]
1.704840179536648
tensor(1.7048)
nn.BCELoss и nn.BCEWithLogitsLoss
Бинарная перекрестная энтропия, формула выглядит следующим образом:
Двунаправленная кросс-энтропия, эквивалентная упрощенной версии формулы кросс-энтропии для бинарной классификации, может использоваться для задач множественной классификации, где классификация не является взаимоисключающей.
BCELoss необходимо сначала вручную ввести сигмоид, а затем добавить 1 для каждой позиции, если классификация равна 1.иначе добавить, и, наконец, усредняется.
BCEWithLogitsLoss сигмоид не нужен, все остальное точно так же.
пример
target = torch.tensor([[1,0,1],[0,1,1]]).float()
raw_output = torch.randn(2,3)
output = torch.sigmoid(raw_output)
print(output)
result = np.zeros((2,3), dtype=np.float)
for ix in range(2):
for iy in range(3):
if(target[ix, iy]==1):
result[ix, iy] += -log(output[ix, iy])
elif(target[ix, iy]==0):
result[ix, iy] += -log(1-output[ix, iy])
print(result)
print(np.mean(result))
loss_fn = torch.nn.BCELoss(reduction='none')
print(loss_fn(output, target))
loss_fn = torch.nn.BCELoss(reduction='mean')
print(loss_fn(output, target))
loss_fn = torch.nn.BCEWithLogitsLoss(reduction='mean')
print(loss_fn(raw_output, target))
результат
tensor([[0.3370, 0.2463, 0.4499],
[0.2124, 0.3505, 0.7828]])
[[1.08756434 0.28280236 0.79866814]
[0.23878274 1.04849163 0.24483089]]
0.6168566833989618
tensor([[1.0876, 0.2828, 0.7987],
[0.2388, 1.0485, 0.2448]])
tensor(0.6169)
tensor(0.6169)
nn.MultiLabelMarginLoss
многоклассовая многоклассовая потеря шарнира В отличие от BCELoss, который переводит проблему в 2 категории, этот проигрыш рассчитан на не взаимоисключающую мультикатегорию (мультикатегория мультикатегория),
Распространенной формой HingeLoss являетсявдля предсказания,является истинным значением. еслииСимволы те же, тогдаЧем больше потеря, тем меньше потеря, до 0 Если знаки разные, потери должны быть больше 1, аЧем больше потеря, тем больше потеря.
В общем, цель этой тренировки функции потерь состоит в том, чтобы подогнать кучуМетка, чтобы вывод окончательно определял результат в соответствии со знаком.
nn.MultiLabelSoftMarginLoss
Диапазон значений, метод расчета аналогичен BCE, т. е. положитьзаполнено до н.э.среди. В документации сказано, что для многоклассовых (взаимоисключающих) задач эта формула рассчитывается на основе максимальной энтропии. Формула BCELoss выглядит следующим образом
nn.MultiMarginLoss
Формула выглядит следующим образом:
Это очень похоже на формулу MultiLabelMarginLoss.Если вы внимательно посмотрите, то обнаружите, что это другой интерфейс той же функции, но nn.MultiMarginLoss не поддерживает мульти-метки и мульти-классификацию, поэтому вход y_true должен бытьТаким образом, категория с несколькими категориями напрямую задается в форматеи.
nn.HingeEmbeddingLoss
Формула выглядит следующим образом:
Подобно стандартной форме HingeLoss для nn.MultiLabelMarginLoss, метка, которую вы хотите разместить,,вуказанная маржа, по умолчанию 1,0;в действительности.
Обычно используется при нелинейном встраивании или полуконтролируемом.
nn.PoissonNLLLoss
версия NLL с распределением Пуассона, входная форма становитсяи, Формула
считается удовлетворяющимРаспределение Пуассона , я не очень часто использовал этот вид Loss, и в Интернете нет ничего, связанного с ним.
nn.KLDivLoss
Дивергенция KL, также известная как относительная энтропия, используется для сравнения потери информации между двумя распределениями. Формула расчета:
Здесь добавлено, что общая формула расчета информационной энтропии:
Формула для расчета перекрестной энтропии:
Очевидно, что KL-расхождение напрямую вычисляет ожидаемый разрыв в собственной информации (логарифмический член) между двумя распределениями по y и не может быть непосредственно понят как расстояние (поскольку KLDiv(x,y)!=KLDiv(y,x) ) , что можно понимать как количество информации, потерянной при подгонке y к x
Резюме
- Самый базовый L1, MSE, SmoothL1 ни о чем не говорит, это оценка схожести последовательностей, которую можно использовать где угодно
- NLL, CrossEntropy, BCE (WithLogits) — это набор базовых Loss, которые повсеместно используются в задачах классификации. Лично на данный момент разница невелика. BCE может быть более чувствительным.
- MultiLabelMargin, MultiLabelSoftMargin и MultiMarginLoss — это реализации стандартного HingeLoss в различных сценариях, общая потеря для задач множественной классификации, но в настоящее время я видел слишком мало статей, и неясно, какие сети использовались.