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