深度學習 為什麼深度學習需要大記憶體?

2021-07-31 21:15:30 字數 3570 閱讀 5095

本文主要譯介自graphcore在2023年1月的這篇部落格: why is so much memory needed for deep neural networks。介紹了深度學習中記憶體的開銷,以及降低記憶體需求的幾種解決方案。

考慮乙個單層線性網路,附帶乙個啟用函式:

h =w

1x+w

2h=w_1x+w_2

h=w1​x

+w2​y=

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...