Накопление градиентов - PullRequest
       15

Накопление градиентов

0 голосов
/ 16 ноября 2018

Я хочу накопить градиенты, прежде чем сделать обратный проход. Так интересно, как правильно это сделать. Согласно этой статье это:

model.zero_grad()                                   # Reset gradients tensors
for i, (inputs, labels) in enumerate(training_set):
    predictions = model(inputs)                     # Forward pass
    loss = loss_function(predictions, labels)       # Compute loss function
    loss = loss / accumulation_steps                # Normalize our loss (if averaged)
    loss.backward()                                 # Backward pass
    if (i+1) % accumulation_steps == 0:             # Wait for several backward steps
        optimizer.step()                            # Now we can do an optimizer step
        model.zero_grad()

тогда как я ожидал, что это будет:

model.zero_grad()                                   # Reset gradients tensors
loss = 0
for i, (inputs, labels) in enumerate(training_set):
    predictions = model(inputs)                     # Forward pass
    loss += loss_function(predictions, labels)       # Compute loss function                              
    if (i+1) % accumulation_steps == 0:             # Wait for several backward steps
        loss = loss / accumulation_steps            # Normalize our loss (if averaged)
        loss.backward()                             # Backward pass
        optimizer.step()                            # Now we can do an optimizer step
        model.zero_grad()     
        loss = 0  

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

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

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

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

Второй метод продолжает накапливать график, поэтому потребует в accumulation_steps раз больше памяти. Первый метод вычисляет градиенты сразу (и просто добавляет градиенты), поэтому требует меньше памяти.

0 голосов
/ 16 ноября 2018

обратный проход loss.backward() - это операция, которая фактически вычисляет градиенты .

Если вы выполняете только прямой проход (predictions = model(inputs)), градиенты не будут вычисляться, и, таким образом, накопление невозможно.

...