通俗理解深度学习梯度累加(Gradient Accumulation)的原理
首先你得明白什么是梯度,可以看我之前寫(xiě)的一篇博客 :
微分與梯度的概念理解
本質(zhì)上,梯度是一種方向?qū)?shù),是一個(gè)矢量,因此這里的梯度累加并不是簡(jiǎn)單的相加,而是類(lèi)似于初高中物理學(xué)的力的合成,梯度作為一種方向?qū)?shù)(矢量)的其累加的效果就是將各個(gè)小的梯度合成為一個(gè)指向Loss function 最終優(yōu)化方向的梯度。
這里結(jié)合代碼理解一下:
正常訓(xùn)練的過(guò)程
for i, (images, labels) in enumerate(train_data):# 1. forwared 前向計(jì)算outputs = model(images)loss = criterion(outputs, labels)# 2. backward 反向傳播計(jì)算梯度optimizer.zero_grad()loss.backward()optimizer.step()梯度累加的訓(xùn)練過(guò)程
# 梯度累加參數(shù) accumulation_steps = 4for i, (images, labels) in enumerate(train_data):# 1. forwared 前向計(jì)算outputs = model(imgaes)loss = criterion(outputs, labels)# 2.1 loss regularization loss正則化loss += loss / accumulation_steps# 2.2 backward propagation 反向傳播計(jì)算梯度loss.backward()# 3. update parameters of netif ((i+1) % accumulation)==0:# optimizer the netoptimizer.step()optimizer.zero_grad() # reset grdient以上代碼來(lái)自:
https://www.zhihu.com/question/435093513/answer/2302992975
可以看出,梯度累加的訓(xùn)練過(guò)程中,每次反向傳播都會(huì)計(jì)算出一個(gè)梯度,但是并不會(huì)使用optimizer.step() 更新參數(shù),直到達(dá)到設(shè)定的累計(jì)次數(shù)后,才一次性的將參數(shù)依據(jù)累積的梯度進(jìn)行更新。(殊途同歸,每次計(jì)算出來(lái)的梯度可以看作是一個(gè)具有微弱方向變化的矢量,不斷疊加,最終合成一個(gè)具有特定方向的矢量。每次變化一點(diǎn)點(diǎn),和將每次一點(diǎn)點(diǎn)的變化累積起來(lái)形成一個(gè)最終的變化方向,這在效果上是沒(méi)有太大差異的),梯度累積可以實(shí)現(xiàn)和使用大的Batch Size 接近的效果,但是消耗的GPU顯存卻不會(huì)顯著增加,這在GPU顯存有限的情況下,是一種較為不錯(cuò)的訓(xùn)練方法。
總結(jié)
以上是生活随笔為你收集整理的通俗理解深度学习梯度累加(Gradient Accumulation)的原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Accumulation Degree
- 下一篇: Pytorch跑深度学习显存不足的问题