[英]Performance gap between `batch_size==32` and `batch_size==8, gradient_accumulation==4`
我嘗試在我的項目中使用梯度累積。 據我了解,梯度累積與將批大小增加 x 倍相同。 我在我的項目中嘗試了batch_size==32
和batch_size==8, gradient_accumulation==4
,但是即使我在數據加載器中禁用了shuffle
,結果也會有所不同。 batch_size==8, accumulation==4
變體的結果明顯較差。
我想知道為什么?
這是我的片段:
loss = model(x)
epoch_loss += float(loss)
loss.backward()
# step starts from 1
if (step % accumulate_step == 0) or (step == len(dataloader)):
if clip_grad_norm > 0:
nn.utils.clip_grad_norm_(model.parameters(), max_norm=clip_grad_norm)
optimizer.step()
if scheduler:
scheduler.step()
optimizer.zero_grad()
假設你的loss
是平均減少的,那么你需要將損失擴大1/accumulate_step
大多數損失函數的默認行為是返回每個批次元素的平均損失值。 這被稱為均值減少,並且具有批量大小不影響損失幅度(或損失梯度的幅度)的特性。 但是,在實現梯度累積時,每次backward
調用時,都會將梯度添加到現有梯度中。 因此,如果您在四分之一大小的批次上backward
調用四次,您實際上會產生比在全尺寸批次上向后調用一次時大四倍的梯度。 為了解釋這種行為,您需要將梯度除以accumulate_step
,這可以通過在反向傳播之前將損失縮放1/accumulate_step
來實現。
loss = model(x) / accumulate_step
loss.backward()
# step starts from 1
if (step % accumulate_step == 0) or (step == len(dataloader)):
if clip_grad_norm > 0:
nn.utils.clip_grad_norm_(model.parameters(), max_norm=clip_grad_norm)
optimizer.step()
if scheduler:
scheduler.step()
optimizer.zero_grad()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.