MSELoss при использовании маски

Я пытаюсь вычислить MSELoss при использовании маски. Предположим, что у меня есть тензор с batch_size 2: [2, 33, 1] в качестве цели и другой входной тензор с той же формой. Поскольку длина последовательности может отличаться для каждого экземпляра, у меня также есть двоичная маска, указывающая на существование каждого элемента во входной последовательности. Итак, вот что я делаю:

mse_loss = nn.MSELoss(reduction='none')

loss = mse_loss(input, target)
loss = (loss * mask.float()).sum() # gives \sigma_euclidean over unmasked elements

mse_loss_val = loss / loss.numel()

# now doing backpropagation
mse_loss_val.backward()

loss / loss.numel() это хорошая практика? Я скептически отношусь к этому, так как мне приходится использовать reduction='none', и при расчете окончательного значения потерь я думаю, что должен рассчитывать потери только с учетом тех элементов потерь, которые не равны нулю (т.е. немаскированные), однако я беру среднее значение по всему тензору. элементы с torch.numel(). На самом деле я пытаюсь принять во внимание 1/n фактор MSELoss. Есть предположения?


person inverted_index    schedule 03.05.2020    source источник


Ответы (1)


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

mse_loss = nn.MSELoss(reduction='none')

loss = mse_loss(input, target)
loss = (loss * mask.float()).sum() # gives \sigma_euclidean over unmasked elements

non_zero_elements = mask.sum()
mse_loss_val = loss / non_zero_elements

# now doing backpropagation
mse_loss_val.backward()

Это лишь немного хуже, чем использование .mean(), если вас беспокоят числовые ошибки.

person Umang Gupta    schedule 03.05.2020
comment
Спасибо! Я думал об этом решении и раньше, потому что для меня не имеет смысла брать среднее значение по всем элементам (нулевым и ненулевым). - person inverted_index; 04.05.2020