累积渐变

时间:2018-11-16 04:40:36

标签: python pytorch gradient-descent

我想在进行反向传递之前积累梯度。所以想知道什么是正确的方法。根据{{​​3}} 它是:

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 :(得分:2)

因此,根据答案here,第一种方法是内存有效的。两种方法所需的工作量大致相同。

第二种方法会不断累积图形,因此需要多accumulation_steps倍的内存。第一种方法可以立即计算梯度(并简单地添加梯度),因此需要较少的内存。

答案 1 :(得分:0)

后退遍历loss.backward()是实际计算梯度的操作。

如果仅执行前向通过(predictions = model(inputs)),将不会计算梯度,因此无法进行累加。