新智元AI WORLD 2018世界人工智能峰會
左手“底層AI框架”,右手“上層AI應用”,如何選擇?
對於做AI相關工作的人來說,具體選擇做哪個方向,可能是需要深深糾結的一個問題。
知乎上就用戶提出了此問題,引起了不小的關注和討論:
新智元獲得瞭解浚源和微調兩位用戶的授權,將他們對此問題的深度解析做了整理,與讀者共享。
要有側重,但兩方面都需瞭解
作為一個深度學習轉系統的人,我最近也在反思一個問題:深度學習系統(Deep Learning System)的核心到底是深度學習還是系統?
先放結論:無論你想做深度學習還是深度學習系統,都需要同時瞭解兩方面的知識,根據自己的方向可以有所側重,但一定不能對一方面完全不懂,否則是很難做出在實踐中有用的成果的。
首先我們來看一下目前流行框架的開發團隊和他們開發框架的驅動力:
Caffe:賈揚清和伯克利視覺實驗室的小夥伴們開發。開始主要是自己用,屬於需求驅動。
Torch:Yann LeCun的學生。需求驅動。
Theano:Yoshua Benjio的學生。用於自己科研,但是也發了系統的paper,屬於需求+科研驅動。
Tensorflow:Jeff Dean帶領的Google員工,主要是系統出身。源於Google在AI領域的佈局需求,資本驅動。
Neon:nervana員工,作為創業公司的產品。資本驅動。
MXNet:DMLC(主要是華人機器學習和分佈式系統學生)的小夥伴。主要是Minerva,Purine,和cxxnet的開發團隊合在一起,一半搞機器學習的,一半搞系統的。需求+興趣驅動。
剩下還有很多搞系統的人出於興趣或者科研目的開發的框架,但大多沒有流行起來,就不再贅述了。
可以看出,除了Google強推的Tensorflow,大多都是從自用和興趣開始的。而Tensorflow的開發經費比其他所有框架的經費加起來還要多出幾十倍,但是一年下來並沒能一統江湖。可見需求驅動的力量,所謂“需要是發明之母”。
為什麼主流深度學習框架多數出自“懂一點系統的搞深度學習的人”之手,而不是“懂一點深度學習的搞系統的人”呢?
我認為主要是因為深度學習系統和傳統系統(比如操作系統,數據庫)有一個本質區別:深度學習算法各部分的耦合非常緊密,牽一髮而動全身。
搞系統的人的思路是,我做一個系統,定義好接口,保證接口正確,用戶用就可以了,不需要了解實現細節。畢竟你用操作系統並不需要了解文件系統格式,用數據庫並不需要了解一致性是怎麼實現的。
但是這套思維用在深度學習系統上卻不合適。
其一,一個數據矩陣流過整個系統,每一步的細節都可能對一百步以後的結果造成影響。而對於中間結果,你無法嚴格定義什麼是正確的,一個好的算法不是N個好的部分的簡單疊加。Hinton就說過,Dropout看起來像個Bug,但是它提高了精度,所以是個“好bug”。
其二,因為深度學習算法複雜,需要控制的因素多,一個固定接口很難滿足所有用戶的需要。還不如把系統寫的簡單靈活一點,讓用戶根據需要可以很方便的自己修改。
反過來對搞深度學習的人來說,如果你不瞭解系統內部細節,當你的算法效果好的時候,你並不知道到底是哪些因素導致了效果好。可能換了一個框架,效果就不好了,而原因是你根本不知道的某個實現細節。當效果不好時,你也不知道如何改進。
另一方面來說,當你需要實現一個新的算法的時候,經常會發現框架現有的接口不能解決你的問題,這時候就需要對系統內部的瞭解才能修改系統已實現自己的目的。
底層開發較難,上層更接地氣
上週開會時遇到了TAMU的胡俠老師,他介紹了他們組最近開發的一個自動機器學習開源框架Auto Keras。胡老師原話是這麼說的:“做開源框架是非常有意義的事情,尤其是你的工作在短時間內被很多人關注並使用是非常有成就感的。”
確實如此,很多業內人士在逐漸把目光投向到更底層更接近“基礎設施”的方向上,比如自動調參、大規模機器學習、並行式機器學習。畢竟好的算法想要被更多人使用,就需要降低使用門檻,提供通用的框架。假設如果沒有Sklearn,估計做機器學習的人最起碼要少一半。如果沒有TF或者Torch,做深度學習的人估計也要少一半。
其實嚴格意義上來說,從提出算法,封裝算法,到應用在現實數據集上是一個流水線作業,是從上游到下游的工作。我的一個觀察是,做算法研究的很多人代碼寫的很糙,運行效率可能非常低。
舉個簡單例子,當你展示一個簡單的K近鄰算法時,你可以寫成每次都進行重新搜索,也可以先構造一課K-D樹來降低時間複雜度。僅聰邏輯角度來看,前者和後者都是正確的,但效率可能相差不少。
這種現象造成了大部分前沿研究的結果不容易落地,因為代碼未經優化或者在實現時存在各種各樣的bug。我覺得一個非常好的突破角度就是研究如何高效實現各種傳統及前沿算法,從最簡單的向量化、並行運算,到更復雜的結構設計甚至到大規模的並行計算。如果把底層框架做好,那麼對於工業界和科研界都有很大的意義:
工業界可以快速嘗試前沿算法,在真實數據上驗證算法的可靠性及實用性。
科研界可以公平的對比前沿算法,防止科研造假。很多論文聲稱他們的算法是遠超當前的最佳算法(SOTA),但事實上可能僅僅是因為他們沒有正確實現SOTA而已。
我從去年起開始嘗試造一些小輪子,也做了一些小框架。這個過程中由不少全新的感受:
設計、實現框架很容易,發現原有算法中的不足,有助於激發新的點子。以基於K近鄰的算法為例,假設在實現時你發現整個程序效率受制於K近鄰部分,你就可以嘗試用K-D樹來加速,甚至替換掉K近鄰的步驟,用聚類來模擬這個過程。所以當你瞭解算法的瓶頸時,你就可以提出新的有意義改進,反哺學術研究。
增強自己的實現能力,避免沉溺研究後的紙上談兵。近兩年最受關注的傳統分類方法要數陳天奇的XGBOOST,的確非常的好用。我認為XGBOOST的成功要歸功於算法很早就被封裝成了成熟的工具庫,這是基於陳天奇老師深厚的系統設計和實現功力。我想過去十年肯定有一些很優秀的算法蒙塵,只是因為它們的作者無法把它們封裝成成熟的輪子供大家使用,非常可惜。
更符合工業界的定位,為求職路加分。其實大部分情況下,工業界並不在意你發過多少厲害的文章,而更在意你是否可以把公司的需求落地。我自己的經驗是即使是學術參會,也沒有多少人對我的水文感興趣,而更多的是聊我開發框架的經歷,因為他們不僅聽說過可能還是使用者。
成就感。框架的使用者遠比論文的閱讀者要多得多,當你發現你設計的框架被全世界的人廣泛使用時,會有很強的成就感,會覺得自己為這個領域發展做出了一點點貢獻,而不是僅僅寫出了一些這輩子不會再有人看的水文。
以上觀點主要在討論要不要嘗試學習開發框架,嘗試造出一些新的輪子。回到正題,「底層框架」哪個「上層應用」更好?我的觀點是這取決於你所擁有的技能:
底層框架:難點在於封裝和性能。比如如何設計API(接口),如何提高運行速度進行優化,如何寫好測試保證方法正確。
上層應用:難點在於如何把已有的輪子用在現實數據上去,這涉及裡很多現實的問題比如數據清理,比如理解如何正確的調用底層的功能。
一般來說,大部分人不適合寫底層。畢竟優秀的框架已經很多,而且對於系統架構以及代碼優化的要求很高,大部分人並不具備所需的知識。
而上層應用就顯得更接地氣,可以加深我們對於數據的敏感度,擅長做上層應用的同學也會是職場offer收割機。其實能夠做好上層應用並不容易,這需要對於問題的深入理解。
換句話說,底層框架和上層應用分的是不同的蛋糕,側重點各不相同。
從做研究的角度來看,發明一個算法其實不該是終點。作為算法的提出者更應該自己動手實現自己的模型,畢竟酒香也怕巷子深。
閱讀更多 新智元 的文章