Почему мы усредняем потери всех элементов партии, если мы обычно должны усреднять градиенты (а не потери)? - PullRequest
1 голос
/ 01 мая 2020

Мой loss вывод равен

tensor([0.0430, 0.0443, 0.0430, 0.0430, 0.0443, 0.0466, 0.0466, 0.0466],
       grad_fn=<AddBackward0>)

Когда я выполняю loss.backward(), я получаю *** RuntimeError: grad can be implicitly created only for scalar outputs

В некоторых местах они скорее предлагают loss.mean().backward() или loss.sum().backward() .

Почему используется .mean().backward(), т.е. почему мы усредняем потери всех элементов партии, если мы обычно должны усреднять градиенты (а не потери)?

Вот мой код

1 Ответ

0 голосов
/ 01 мая 2020

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

loss.backward(torch.Tensor([1, 1, 1, 1, 1, 1, ... ,1])) 

или

loss.backward(torch.ones(batch_size)) 

количество единиц = количество элементов в 1D-тензоре в вашем случае.

Чтобы ответить, почему мы используем среднее и все, потому что это действует как нормализующий термин. Вместо того, чтобы вся потеря отдельной партии влияла в огромных количествах, мы нормализуем ее эффект. Это проблема? Скорее, масштабируя, мы получаем гораздо более разумное представление о том, как ведет себя кривая потерь.

...