Каков правильный способ реализовать накопление градиента в pytorch?

#pytorch #pytorch-lightning

#pytorch #pytorch-lightning

Вопрос:

В целом существует два способа:

  1. Вызывайте loss.backward() каждый пакет, но только вызывайте optimizer.step() и optimizer.zero_grad() каждые N пакетов. Это тот случай, когда градиенты N пакетов суммируются? Следовательно, чтобы поддерживать одинаковую скорость обучения для каждого эффективного пакета, мы должны разделить скорость обучения на N?

  2. Накапливать потери вместо градиента и вызывать (loss / N).backward() каждые N пакетов. Это легко понять, но противоречит ли это цели экономии памяти (потому что градиенты N пакетов вычисляются одновременно)? Скорость обучения не требует настройки для поддержания одинаковой скорости обучения для каждого эффективного пакета, но ее следует умножить на N, если вы хотите поддерживать одинаковую скорость обучения для каждого примера.

Какой из них лучше или чаще используется в таких пакетах, как pytorch-lightning? Кажется, что optimizer.zero_grad() идеально подходит для накопления градиента, поэтому следует рекомендовать (1).

Ответ №1:

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