寫完發現名字有點拗口。。- -#
大家在做deep learning的時候,應該都遇到過顯存不夠用,然后不得不去痛苦的減去batchszie,或者砍自己的網絡結構呢? 最后跑出來的效果不盡如人意,總覺得自己被全世界針對了。。遇到這種情況怎么辦? 請使用MXnet的天奇大法帶你省顯存! 魯迅曾經說過:你不去試試,怎么會知道自己的idea真的是這么糟糕呢?
首先是傳送門附上 mxnet-memonger,相應的paper也是值得一看的 Training Deep Nets with Sublinear Memory Cost。
實際上repo和paer里面都說的很清楚了,這里簡單提一下吧。
一、Why?
節省顯存的原理是什么呢?我們知道,我們在訓練一個網絡的時候,顯存是用來保存中間的結果的,為什么需要保存中間的結果呢,因為在BP算梯度的時候,我們是需要當前層的值和上一層回傳的梯度一起才能計算得到的,所以這看來顯存是無法節省的?當然不會,簡單的舉個例子:一個3層的神經網絡,我們可以不保存第二層的結果,在BP到第二層需要它的結果的時候,可以通過第一層的結果來計算出來,這樣就節省了不少內存。 提醒一下,這只是我個人的理解,事實上這篇paper一直沒有去好好的讀一下,有時間在再個筆記。不過大體的意思差不多就是這樣。
二、How?
怎么做呢?分享一下我的trick吧,我一般會在symbol的相加的地方如data = data+ data0這種后面加上一行 data._set_attr(force_mirroring='True'),為什么這么做大家可以去看看repo的readme,symbol的地方處理完以后,只有如下就可以了,searchplan會返回一個可以節省顯存的的symbol給你,其它地方完全一樣。
1 import mxnet as mx 2 import memonger 3 4 # configure your network 5 net = my_symbol() 6 7 # call memory optimizer to search possible memory plan. 8 net_planned = memonger.search_plan(net) 9 10 # use as normal 11 model = mx.FeedForward(net_planned, ...) 12 model.fit(...)
PS:使用的時候要注意,千萬不要在又隨機性的層例如dropout后面加上mirror,因為這個結果,再算一次就和上一次不同了,會讓你的symbol的loss變得很奇怪。。
三、總結
天奇大法吼啊!