硬件太差不要慌 做时间的朋友
背景
天之道,損有余以補(bǔ)不足。
深度學(xué)習(xí),那是先富的游戲。窮導(dǎo)致硬件不行,非科班導(dǎo)致工程也不行,每次比賽數(shù)據(jù)量一大,我心里浮現(xiàn)的都是水滸傳名場(chǎng)面
相聲,講究的是說(shuō)學(xué)逗唱;而工程,講究的是一個(gè)吹德偶夫(trade-off)。那,我們就用時(shí)間換空間。時(shí)間是每個(gè)人的朋友,跑的慢,就多等等。之前kdd cup百度比賽,我在嘗試復(fù)現(xiàn)baseline的時(shí)候就遇到了麻煩。
215天的訓(xùn)練歷史,產(chǎn)生了400萬(wàn)樣本。batch_size選擇1024,但每個(gè)step大概耗時(shí)800ms,單個(gè)epoch慢的離譜。不禁感慨生活太殘忍了。
本文記錄一下,我做了哪些改動(dòng)。很多人喜歡強(qiáng)調(diào):什么算法工程師先要是一個(gè)工程師。我雖然不懂這話的含義,但工地上,他們都叫我Yue工,贏麻了。
讀取
首先是讀取文件過(guò)程,想把csv保存為pickle后加載。但發(fā)現(xiàn)csv讀取只花2秒??梢越邮?#xff0c;未采納。
dataset中窗口滑動(dòng)轉(zhuǎn)化為時(shí)序樣本,原本pandas操作變?yōu)閚umpy操作。單個(gè)樣本處理時(shí)間從2e-4s 降低為2e-6s,訓(xùn)練單個(gè)step從800ms可以降為250ms。但二者切片時(shí)對(duì)左開(kāi)右閉的設(shè)置不一樣,坑了很久
原本我沾沾自喜的設(shè)計(jì)了,一個(gè)day到index到樣本的數(shù)據(jù)提取路線,每個(gè)過(guò)程都封裝的很好。實(shí)際跑起來(lái),發(fā)現(xiàn)訓(xùn)練前啥預(yù)處理沒(méi)有,要花三十分鐘(1933s)。從所有index選取不在drop_list的,普通寫(xiě)法特別耗時(shí),轉(zhuǎn)化為集合求差。三十分鐘變成3秒。
很慢
idx = [i for i in all_idx if i not in dropidx] # very slow
很快
idx = sorted(list(set(all_idx) - set(dropidx)))
樣本選取idx過(guò)程中,通過(guò)分布式提取并保存為pickle,訓(xùn)練可以開(kāi)始的快些?groupby還是很耗時(shí)。
tensorflow可以存成tf-records二進(jìn)制文件加速加載,這里我沒(méi)有使用。
特征
本來(lái)我最喜歡的結(jié)構(gòu)是數(shù)據(jù)原始列原封不動(dòng),作為網(wǎng)絡(luò)輸入。特征部分盡量在神經(jīng)網(wǎng)絡(luò)里使用tf實(shí)現(xiàn),感覺(jué)只適合簡(jiǎn)單任務(wù)與小數(shù)據(jù)。因此,把特征工程部分采用多進(jìn)程完成并保存?;蛘卟捎胻f.data里的多線程map
pipeline
tensorflow本身的一個(gè)優(yōu)勢(shì)是其自帶的tf.data模塊,可以高效的給模型喂子彈。官方文檔里有如何
Profiling tf.profiler.experimental.Trace
原來(lái)Tensorboard 里有個(gè)profile_batch的參數(shù),可以直接幫著分析。由于每次都要端口轉(zhuǎn)發(fā),后來(lái)用tensorboard就比較少了, 不過(guò)實(shí)際訓(xùn)練的時(shí)候,還是去掉TB吧,很粘時(shí)間也
metrics
預(yù)測(cè)48小時(shí),并迭代15天。因此可以很多值預(yù)測(cè)了多遍,可以轉(zhuǎn)化一下,用向量方法求出來(lái)。在嘗試規(guī)則模型的時(shí)候,發(fā)現(xiàn)本地評(píng)分過(guò)程消耗了兩個(gè)小時(shí)。單個(gè)風(fēng)機(jī)消耗的是6秒,為啥到134,就到兩小時(shí)了。
首先看了一下代碼,看起來(lái)沒(méi)有很容易優(yōu)化的地方。那第一步就是把采樣加上去,因?yàn)椴徊蓸幼约簯{一次分要2小時(shí),太久。另一方面,我發(fā)現(xiàn)比賽規(guī)則我第一印象是按個(gè)滾動(dòng),現(xiàn)在里面也是有采樣的。所以既可以減少時(shí)間,也與線上評(píng)價(jià)更吻合。
發(fā)現(xiàn)循環(huán)的時(shí)候,其實(shí)可以更簡(jiǎn)單點(diǎn),就是逐行循環(huán),而不是每一輪都篩選。
還是不行的感覺(jué),如果換成多線程感覺(jué)比較麻煩。其實(shí),之前我?guī)缀鯖](méi)怎么用過(guò)多線程。我一直都有一顆仁慈的人。很多人對(duì)待電腦,就像資本家對(duì)我們一樣,就不讓閑著。我干完了等別人結(jié)果都不行,非要整什么異步。
最終版本:
做出多線程版本。發(fā)現(xiàn)需要保存下來(lái),才能方便序列化,多核之后從7000秒降到600秒了,幾乎可以達(dá)到實(shí)用了。
如果再有心思的話,可以用numba和cython進(jìn)一步優(yōu)化速度。
實(shí)驗(yàn)迭代
另外關(guān)于迭代,就是可以采樣部分?jǐn)?shù)據(jù)進(jìn)行實(shí)驗(yàn),加速迭代歷程。時(shí)序里,當(dāng)然是選擇最后的,或者同期的。
家里條件好的,可以把a(bǔ)pex和多卡都搞上。1080這種卡收益不大,那就讓老爺們先走吧。
深刻的感受到了從30分鐘轉(zhuǎn)化為3秒完成,都是因?yàn)樽约罕∪醯幕A(chǔ)。
再比如,主辦方給的tensorflow版本較低,我甚至要降cuda版本才能用。我就給主辦方以時(shí)間,一個(gè)月沒(méi)做比賽,他們就把版本升了。
最后,即使成績(jī)暫時(shí)不夠好,或生活不如意,問(wèn)題不大。做時(shí)間的朋友,慢慢積累。也許,成績(jī)提高了,也許期待就降低了。牢記:給文明以歲月,給自己以時(shí)間,路線對(duì)了,穩(wěn)贏,無(wú)非是小贏、中贏,還是大贏的問(wèn)題。
以上措施幫助我可以在兩個(gè)小時(shí)左右完成訓(xùn)練和驗(yàn)證
總結(jié)
以上是生活随笔為你收集整理的硬件太差不要慌 做时间的朋友的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 测试app发文
- 下一篇: 双网卡访问冲突的问题 解决