0
本文作者: AI研習(xí)社 | 2017-11-28 17:49 |
雷鋒網(wǎng)按:本文作者紫杉,本文由雷鋒網(wǎng)整理自作者在知乎《有沒有必要把機(jī)器學(xué)習(xí)算法自己實(shí)現(xiàn)一遍?》問題下的回答。雷鋒網(wǎng)已獲得轉(zhuǎn)載授權(quán)。
哈哈哈哈,我覺得很多人都有這個(gè)疑問吧。機(jī)器學(xué)習(xí)好高大上,多么牛逼的東西,光是看公式就已經(jīng)眼花繚亂了,總覺得自己該全部去實(shí)現(xiàn)一遍,有的時(shí)候太懶,有的時(shí)候覺得能力不夠。道理雖然明白——任何事情自己親手做一做還是更好的,但機(jī)器學(xué)習(xí)已經(jīng)有了大量的庫了,SVM-Light,R里面的glm()方程,自己實(shí)現(xiàn)一遍,最后又不敢用(因?yàn)椴恢浪惴ň烤故欠裾_),或者不能用(一是速度趕不上大神寫的庫那么快,二是精度沒有專業(yè)庫那么高),耗時(shí)耗力的寫了一堆后究竟有什么用?
這里很多答案都提供了一些解釋,但我想從另一個(gè)角度來聊聊這個(gè)問題。
我在1年半前(本科階段)就開始接觸計(jì)算心理學(xué)和機(jī)器學(xué)習(xí)方面的研究,在NAACL(自然語言處理排名第三的論壇)上發(fā)表了一篇文章,用的計(jì)算機(jī)教授寫的算法庫,跑的是經(jīng)過AdaGrad優(yōu)化的向量支持機(jī)(SVM)算法。在這種論壇發(fā)文章,你是必須去做海報(bào)展示的,站在自己的大幅海報(bào)面前傻傻的待4個(gè)小時(shí),我的兩位教授(一位是認(rèn)知語言學(xué)教授,一位是計(jì)算機(jī)教授)都在那里。我的位置不太好,在最邊緣的角落里,本來以為就可以贏得一份清凈,Philip Resnik走了過來。直到那一剎那之前,我一直不知道他是誰。但經(jīng)過教授介紹后,他是馬里蘭大學(xué)的機(jī)器學(xué)習(xí)和自然語言處理教授,在這個(gè)領(lǐng)域混了多年,在Google Schoar上的論文引用數(shù)高達(dá)12,853。
他走過來的第一句話是:“假設(shè)我一點(diǎn)也不懂?dāng)?shù)學(xué),告訴我你這篇論文做的是什么?!蔽医忉尯?,看到我的計(jì)算機(jī)教授走了過來和Resnik聊天,Resnik問我的教授:“你用的是不是hinge loss(辛基損失函數(shù))?”我的教授說:“是。但不是全局優(yōu)化,所以我沒有叫這玩意SVM……”(我憑回憶打出來的,可能不完全精確)。當(dāng)時(shí)我站在一旁覺得這他們能這樣大聊特聊數(shù)學(xué),甚至是向量支持機(jī)(我當(dāng)時(shí)認(rèn)為這是最厲害的算法——除神經(jīng)網(wǎng)絡(luò)以外),簡直是太厲害了,我一點(diǎn)也聽不懂他們?cè)谥v什么。
直到現(xiàn)在,我才明白所謂的“辛基損失函數(shù)(Hinge loss)”其實(shí)就是Max(a,b)函數(shù),就是比較 a 和 b 誰大誰小,然后選大的那個(gè)。這玩意究竟有什么難理解的?為什么要那么高大上?你讓一個(gè)五歲的小孩,問他:“有一堆紅球,一堆綠球,哪一堆的球更多???”這個(gè)小孩都能告訴你正確答案。
當(dāng)然這說的有點(diǎn)偏題了。后來我非常幸運(yùn)的考上了研究生,才終于開始了對(duì)“高檔”算法的學(xué)習(xí)。第一個(gè)學(xué)期被Christopher Manning(克里斯多夫·曼寧)的CS224N自然語言處理虐了一番,這個(gè)學(xué)期開始上Andrej Karpathy(安杰·卡帕西)的神經(jīng)網(wǎng)絡(luò)(CS231N),該君是李菲菲教授(音譯,F(xiàn)ei-Fei Li)的愛徒,在推特上有14.9K關(guān)注者,我越看他那張方塊臉,越覺得他長得像賈斯丁·汀布萊克(Justin Timberlake)。
我其實(shí)也是自控能力很差的人,在上安杰·卡帕西的課之前,也從沒有萌生過自己去寫機(jī)器學(xué)習(xí)算法的想法。原因在文章開頭有提過:1. 我的代碼運(yùn)行速度肯定趕不上經(jīng)過多次迭代的專業(yè)庫的運(yùn)行速度;2. 我咋知道我的代碼寫的就是對(duì)的呢?
我直到現(xiàn)在都這樣認(rèn)為:不考慮對(duì)方的環(huán)境和條件,知識(shí)與技能,就一味要求對(duì)方把機(jī)器學(xué)習(xí)算法都實(shí)現(xiàn)一遍,估計(jì)是最無理取鬧的行為了吧。前天晚上,我跟另一個(gè)研究生Jason Freeman(杰森·弗里曼)聊天,他在微軟的西雅圖總部工作了4年,在目前越來越有名的TypeScript團(tuán)隊(duì)工作了3年(TypeScript是靜態(tài)的JavaScript語言,正在國內(nèi)和國外開始流行)——他告訴我他和安德斯·海爾斯伯格(Anders Hejlsberg)一起工作,他還經(jīng)常頂撞安德斯。我的第一反應(yīng)是:“他是誰……”(安德斯·海爾斯伯格是Delphi和C#之父,但我不熟悉這兩門語言,所以不會(huì)崇拜他——小廣告:Scala是我目前最喜歡的語言)。
我和杰森討論的是3月份開始究竟要不要選吳恩達(dá)(Andrew Ng)的機(jī)器學(xué)習(xí)課(CS229)。我持的立場是我可能不打算上那門課,因?yàn)槲乙呀?jīng)看過大部分他的視頻了,還讀了他講義的一部分(這里是講義鏈接: CS 229: Machine Learning (Course handouts))。因?yàn)槲乙呀?jīng)確定以后要做神經(jīng)網(wǎng)絡(luò)方面的研究,所以覺得他課上的一些其他內(nèi)容比如特征降維(PCA),對(duì)我而言用處不大,我只需要會(huì)用就行了。我不僅用過特征降維,還用過更好的降維可視化(tSNE算法)。這玩意和我的領(lǐng)域不搭,為什么我要浪費(fèi)時(shí)間去學(xué)?
杰森的論點(diǎn)是,如果我學(xué)了它們的理論(甚至把它們實(shí)現(xiàn)一遍),就能更好的應(yīng)用它們。我說:你把直覺(intuition)當(dāng)什么了?在我看來,對(duì)算法進(jìn)行“直觀”上的了解,就已經(jīng)很足夠了。什么是向量支持機(jī)?就是拿一個(gè)平面去分隔一堆點(diǎn)。更術(shù)語一點(diǎn)的解釋不外乎是拿一個(gè)超平面(Hyperplane)在高維空間里去分割。什么是特征降維?就是看如何把高維度的點(diǎn)陣降到兩三個(gè)維度。什么是alpha值?就是看這個(gè)算法學(xué)得有多快。什么是正則化(regularization)?就是別讓你的算法過度擬合數(shù)據(jù)(當(dāng)然L1,L2等等都有區(qū)別,但這些區(qū)別都很簡單,L1讓你關(guān)注某個(gè)值,L2讓你利用所有的值)。
為什么我談這么多關(guān)于理論的問題?在我看來,學(xué)習(xí)機(jī)器學(xué)習(xí)的算法的進(jìn)度是這樣的:應(yīng)用 -》理論 -》實(shí)現(xiàn)。就跟教小孩折射一樣,你先讓他看看筷子在水中如何彎折(應(yīng)用),再告訴他光的折射原因(理論),再讓他自己用其他物體來試試(實(shí)現(xiàn))。實(shí)現(xiàn),是這個(gè)漫長學(xué)習(xí)過程的最后一步。一開始就來談實(shí)現(xiàn),實(shí)在是很神奇的事情。
讓我準(zhǔn)確論述一下我的觀點(diǎn):如果你是學(xué)界精英,那么去學(xué)習(xí)那些你將要使用的算法的理論,最后再自己嘗試著實(shí)現(xiàn)他們,是很有必要的,除非你是只做應(yīng)用(比如社會(huì)科學(xué),心理學(xué),商學(xué)等等)。如果是普通的程序員/工程師,不需要強(qiáng)迫自己去實(shí)現(xiàn)這些算法。沒人會(huì)給你一個(gè)小獎(jiǎng)?wù)拢蠊菊羞@類員工的時(shí)候,也是更看重學(xué)歷,而不是看“哦,我把‘所有’的機(jī)器學(xué)習(xí)算法都實(shí)現(xiàn)了一遍”。
最后送上一點(diǎn)我覺得實(shí)現(xiàn)機(jī)器學(xué)習(xí)算法最好的路徑:
最好用Python和Numpy庫。這兩樣寶具會(huì)讓你非常輕松。安杰·卡帕西(Andrej)推薦用ipython notebook(現(xiàn)在改名叫Jupyter了),來可視化數(shù)據(jù),以及實(shí)驗(yàn)算法。昨天有一個(gè)下午茶會(huì),我們系舉辦的,也邀請(qǐng)了安杰,我跑去湊熱鬧,跟安杰談到了這個(gè)問題,他說就算是大公司做研究,也是這種路徑,先從ipython notebook開始(這點(diǎn)讓我很驚訝)。
機(jī)器學(xué)習(xí)算法最難的部分其實(shí)不是寫出來,而是高效率的實(shí)現(xiàn),讓你的算法跑快一點(diǎn)。其中一個(gè)技巧叫做“矢量化”(Vectorization)。矢量化就是說,能做矩陣操作就矩陣操作,最好連一個(gè)外循環(huán)都不寫。
這是我寫的Softmax算法的測評(píng):(在500個(gè)樣本上跑的)
naive loss: 2.384533e+00 computed in 0.255952s
vectorized loss: 2.384533e+00 computed in 0.004148s
第一個(gè)是用普通的Python和循環(huán)寫出來的,第二個(gè)是用矢量化操作寫出來的,可以看到64倍速度的提升——側(cè)面也可以看到Python有多垃圾(慢)。
這個(gè)是SVM(支持向量機(jī))算法的測評(píng):(同樣500個(gè)樣本)
Naive loss: 9.102322e+00 computed in 0.136226s
Vectorized loss: 9.102322e+00 computed in 0.005909s
這次的速度提升沒有那么明顯,但也是26倍的提速。
但我只想說:矢量化真是很難的事情。數(shù)學(xué)家隨便就寫公式,也不考慮考慮可憐的計(jì)算機(jī)科學(xué)孩子們。原初的公式幾十分鐘就搞定,矢量化要一兩個(gè)小時(shí)的冥思苦想。
最后,對(duì)于那些讀懂了理論,實(shí)在是閑得無聊,或者想要進(jìn)軍更高級(jí)的學(xué)術(shù)界的同志們,這里是安杰·卡帕西課代碼的鏈接:CS231n Convolutional Neural Networks for Visual Recognition。如果你不屬于這個(gè)類別,就不要瞎摻合啦,用用別人的庫又怎么了?駭客精神(Hacker Code)中一條就是:“不要重復(fù)勞動(dòng),有庫就要用庫,不然就是對(duì)庫寫作者的不尊重?!?/p>
這篇文章有點(diǎn)接近“反智”文章的邊緣,大意是實(shí)用主義至上,自己實(shí)現(xiàn)的必要性不大。這個(gè)觀點(diǎn)還是有很多爭議的,比如目前有一個(gè)答案就“實(shí)名”反對(duì)這個(gè)答案。機(jī)器學(xué)習(xí)是一個(gè)交叉學(xué)科,作為學(xué)生而言,從不同的部門學(xué)到的機(jī)器學(xué)習(xí),必然是不一樣的。在統(tǒng)計(jì)學(xué)部門學(xué)到的機(jī)器學(xué)習(xí),和在計(jì)算機(jī)部門學(xué)的機(jī)器學(xué)習(xí),肯定是兩個(gè)樣。我秋天的時(shí)候跟一位概率教授上了一節(jié)課,當(dāng)我告訴他斯坦福計(jì)算機(jī)入門概率課要介紹MLE(最大擬然估值)和蒙特拉羅模擬(Monte Carlo Simulation)的時(shí)候,他沉重的搖搖頭,說這么早就介紹這樣深刻的概念,是很不應(yīng)該的,在他的部門,要第三年的學(xué)生才接觸這樣的知識(shí),因?yàn)橹钡侥菚r(shí),學(xué)生才有足夠的知識(shí)框架去理解這些知識(shí)。
我寫這篇文章是有一定的原因的。我認(rèn)識(shí)一些國內(nèi)的大學(xué)同學(xué),都異常優(yōu)秀,他們努力的程度是我一輩子都比不上的,他們中一部分人因?yàn)檫\(yùn)氣不好(高考),不幸去了一些相對(duì)不是那么優(yōu)異的大學(xué),但是他們用努力彌補(bǔ)這個(gè)缺陷,對(duì)數(shù)學(xué)和各種學(xué)科展開攻克,很多人的閱讀量和數(shù)學(xué)解題技巧也是我不能企及的。還有一部分人,是處于業(yè)界轉(zhuǎn)型邊緣,本來已是成熟的程序員,或者數(shù)據(jù)分析師,但是想要進(jìn)一步提升自己,亦或是轉(zhuǎn)型。我把這兩類人定做這篇回答的目標(biāo)受眾。我希望為他們寫一篇回答,不讓他們走我走過的彎路,不受太多的誤導(dǎo)。
開復(fù)先生(李開復(fù))最近說深度學(xué)習(xí)急缺人才。我非常的不贊同。深度學(xué)習(xí)領(lǐng)域是處于半飽和狀態(tài)的,實(shí)際上就業(yè)情況就是一堆熠熠生輝(Scintillating)的博士們?cè)趯W(xué)術(shù)界待膩了,想要去賺點(diǎn)錢玩玩,就跑去業(yè)界晃一圈的狀況。這和大部分人的就業(yè)狀況根本是不搭邊的。深度學(xué)習(xí),以及理論機(jī)器學(xué)習(xí),除非是平臺(tái)很高,起點(diǎn)很高,是很難得到廣泛認(rèn)可的。
我最近剛買了一本書:
這本書很詳細(xì)的在講Lasso Loss(L1),寫SVM的部分也非常不錯(cuò),很神奇的是,三位作者,兩位是斯坦福統(tǒng)計(jì)學(xué)系的,一位是伯克利的。如果我能讀完這本書,會(huì)上來改進(jìn)一下這個(gè)答案的。
最近我想提一提答案末尾寫的,關(guān)于“實(shí)現(xiàn)”的問題。我過去幾周一直在寫我自己的Theano庫(是的,放著牛逼的Lasagne不用,非要自己手寫),終于把CNN寫完后,現(xiàn)在在寫RNN的部分。當(dāng)我已經(jīng)花費(fèi)這么多的時(shí)間,然后意識(shí)到,我的代碼暫時(shí)還只能在CPU上跑,因?yàn)槲視簳r(shí)還沒有用Theano的CUDA庫,又意識(shí)到,僅僅幾周后,我的兩門春季課已經(jīng)開始教TensorFlow了,于是覺得自己是個(gè)傻子。
所以我自己都陷入了我回答中所寫的那個(gè)陷阱:實(shí)現(xiàn)之后卻不能使用,但又不愿意放棄自己的代碼,于是只有投入更多的時(shí)間去改代碼,而不是去理解數(shù)學(xué)。愿與各位共勉。
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。