本文主要譯介自graphcore在2023年1月的這篇部落格: why is so much memory needed for deep neural networks。介紹了深度學習中記憶體的開銷,以及降低記憶體需求的幾種解決方案。考慮乙個單層線性網路,附帶乙個啟用函式:
h =w
1x+w
2h=w_1x+w_2
h=w1x
+w2y=
f(h)
y=f(h)
y=f(h)
代價函式:e=∣
∣y−y
‾∣∣2
e=||y-\overline||^2
e=∣∣y−
y∣∣
2在訓練時,每乙個迭代要記錄以下資料:
這樣,可以在後向運算中用梯度下降更新引數:
δ w1
=η⋅∂
e∂w1
=η⋅2
(y−y
‾)⋅f
′(h)
⋅x
\delta w_1=\eta\cdot \frac=\eta \cdot 2(y-\overline)\cdot f'(h) \cdot x
δw1=η
⋅∂w1
∂e
=η⋅2
(y−y
)⋅f
′(h)
⋅xδ w2
=η⋅∂
e∂w1
=η⋅2
(y−y
‾)⋅f
′(h)
\delta w_2=\eta\cdot \frac=\eta \cdot 2(y-\overline)\cdot f'(h)
δw2=η
⋅∂w1
∂e
=η⋅2
(y−y
)⋅f
′(h)
很小,不做考量。
256256的彩色影象:25625631 byte= 192kb較大,和模型複雜度有關。
入門級的mnist識別網路有6.6 million引數,使用32-bit浮點精度,佔記憶體:6.6m * 32 bit = 25mb當然,你可以設計精簡的網路來處理很複雜的問題。50層的resnet有26 million引數,佔記憶體:26m * 32 bit = 99mb
較大,同樣和模型複雜度有關。
50層的resnet有16 million響應,佔記憶體:16m*32bit = 64mb響應和模型引數的數量並沒有直接關係。卷積層可以有很大尺寸的響應,但只有很少的引數;啟用層甚至可以沒有引數。
– 這樣看起來也不大啊?幾百兆而已。為了有效利用gpu的simd機制,要把資料以mini-batch的形式輸入網路。– 往下看。
如果要用32 bit的浮點數填滿常見的1024 bit通路,需要32個樣本同時計算。
在使用mini-batch時,模型引數依然只儲存乙份,但各層響應需要按mini-batch大小翻倍。
50層的resnet,mini-batch=32,各層相應佔記憶體:64mb*32 = 2gb設h×w
h\times w
h×w的輸入影象為x
xx,k×k
k\times k
k×k的卷積核為r
rr,符合我們直覺的卷積是這樣計算的。
對每乙個輸出位置,計算小塊對位乘法結果之和。但是,這種零碎運算很慢。y (h
,w)=
∑xk,
ks(h
,w)⊙
ry(h,w) = \sum(h,w) \odot r}
y(h,w)
=∑xk
,ks
(h,w
)⊙r
h =1
:h,w
=1:w
h=1:h, w=1:w
h=1:h,
w=1:
w其中,xk,
ks(h
,w
)x^s_(h,w)
xk,ks
(h,w
)表示輸入影象中,以h,w
h,wh,
w為中心,尺寸為k×k
k\times k
k×k的子影象。
在深度學習庫中,一般會採用lowering的方式,把卷積計算轉換成矩陣乘法。
首先,把輸入影象分別平移不同距離,得到k輸入輸出為多通道時,方法類似,詳情參見這篇部落格。2k^2
k2個h ×w
h\times w
h×w的位移影象,串接成h×w
×k
2h\times w \times k^2
h×w×k2
的矩陣x
‾\overline
x。之後,把k×k
k\times k
k×k的卷積核按照同樣順序拉伸成k2×
1k^2\times 1
k2×1
的矩陣r
‾\overline
r卷積結果通過一次矩陣乘法獲得:
y =x
‾⋅r‾
y=\overline\cdot \overline
y=x⋅
r
在計算此類卷積時,前層響應x
xx需要擴大k
2k^2
k2倍。
50層的resnet,考慮lowering效應時,各層響應佔記憶體7.5gb為了有效利用simd,如果精度降低一倍,batch大小要擴大一倍。不能降低記憶體消耗。
不開闢新記憶體,直接重寫原有響應。
很多啟用函式都可以這樣操作。
複雜一些,通過分析整個網路圖,可以找出只需要用一次的響應,它可以和後續響應共享記憶體。例如mxnet的memory sharing機制。
綜合運用這種方法,mit在2023年的這篇**能夠把記憶體降低兩到三倍。
找出那些容易計算的響應結果(例如啟用函式層的輸出)不與儲存,在需要使用的時候臨時計算。
使用這種方法,mxnet的這個例子能夠把50層的resnet網路占用的記憶體減小四倍。
類似地,deepmind在2023年的這篇**用rnn處理長度為1000的序列,記憶體占用降低20倍,計算量增加30%。
當然,還有graphcore自家的ipu,也通過儲存和計算的平衡來節約資源。
graphcore本身是一家機器學習晶元初創公司,行文中難免夾帶私貨,請明辨。
為什麼需要深度學習
為了科研專案的需求,作為在博一快結束時轉而進行機器學習領域的研究。周圍沒有同事從事相關的研究,用最快的速度完成了對機器學習和深度學習的了解。我感覺經常問自己的乙個問題就是為什麼要從機器學習到深度學習?對我的科研工作有沒有幫助。我主要看了兩個資料 deep learning book mit intr...
什麼是深度學習?為何需要深度學習?
深度學習有如下一些眾所周知且被廣泛接受的定義。1 深度學習是機器學習的子集。2 深度學習使用級聯的多層 非線性 處理單元,稱為人工神經網路 ann 以及受大腦結構和功能 神經元 啟發的演算法。每個連續層使用前一層的輸出作為輸入。3 深度學習使用ann進行特徵提取和轉換,處理資料,查詢模式和開發抽象。...
為什麼是深度學習
是不是深度學習的hidden layer越多越好,我們並不是單純的研究引數增多的所帶來的效能改善,我們關注的是相同的引數情況下,是不是深度越深越好。那麼是什麼樣的原因出現上邊的情況呢?乙個合理的解釋就是modularization。modularization把本來複雜的問題變簡單,即使traini...