Gradient Accumulation 梯度累加 (Pytorch)
? ? ? ? 我們在訓(xùn)練神經(jīng)網(wǎng)絡(luò)的時候,batch_size的大小會對最終的模型效果產(chǎn)生很大的影響。一定條件下,batch_size設(shè)置的越大,模型就會越穩(wěn)定。batch_size的值通常設(shè)置在 8-32 之間,但是當(dāng)我們做一些計算量需求大的任務(wù)(例如語義分割、GAN等)或者輸入圖片尺寸太大的時候,我們的batch size往往只能設(shè)置為2或者4,否則就會出現(xiàn) “CUDA OUT OF MEMORY” 的不可抗力報錯。
? ? ? 那么如何在有限的計算資源的條件下,訓(xùn)練時采用更大的batch size呢?這就是梯度累加(Gradient Accumulation)技術(shù)了。
常規(guī)訓(xùn)練過程
for i, (inputs, labels) in enumerate(trainloader):optimizer.zero_grad() # 梯度清零outputs = net(inputs) # 正向傳播loss = criterion(outputs, labels) # 計算損失loss.backward() # 反向傳播,計算梯度optimizer.step() # 更新參數(shù)if (i+1) % evaluation_steps == 0:evaluate_model()使用梯度累加的訓(xùn)練過程
for i, (inputs, labels) in enumerate(trainloader):outputs = net(inputs) # 正向傳播loss = criterion(outputs, labels) # 計算損失函數(shù)loss = loss / accumulation_steps # 損失標(biāo)準(zhǔn)化loss.backward() # 反向傳播,計算梯度if (i+1) % accumulation_steps == 0:optimizer.step() # 更新參數(shù)optimizer.zero_grad() # 梯度清零if (i+1) % evaluation_steps == 0:evaluate_model()就是加了個if
注意這里的loss每次要除以accumulation_step,所以當(dāng)累加到一定步數(shù)optimizer更新的值其實是這些累加值的均值。其實就相當(dāng)于擴(kuò)大了batch_size,讓更新的loss更加平穩(wěn)。一個batch的數(shù)據(jù)最后算的loss也是這個batch的數(shù)據(jù)個數(shù)的均值。
??總結(jié)來講,梯度累加就是每計算一個batch的梯度,不進(jìn)行清零,而是做梯度的累加(平均),當(dāng)累加到一定的次數(shù)之后,再更新網(wǎng)絡(luò)參數(shù),然后將梯度清零。
? 通過這種參數(shù)延遲更新的手段,可以實現(xiàn)與采用大batch_size相近的效果。知乎上有人說
"在平時的實驗過程中,我一般會采用梯度累加技術(shù),大多數(shù)情況下,采用梯度累加訓(xùn)練的模型效果,要比采用小batch_size訓(xùn)練的模型效果要好很多"。
總結(jié)
以上是生活随笔為你收集整理的Gradient Accumulation 梯度累加 (Pytorch)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通俗理解深度学习梯度累加(Gradien
- 下一篇: [换根] Accumulation De