有沒有必要把機器學習演算法自己實現一遍?

視學演算法發表於2020-04-06

編輯:機器學習演算法與自然語言處理-憶臻,Charlotte資料探勘-小杜https://www.zhihu.com/question/36768514

作者:微調
https://www.zhihu.com/question/36768514/answer/376510114

不少自學的朋友很容易陷入到焦慮當中,尤其是在學習理論受挫之後。再加上不少人是碼農出身,實現演算法是就成了最容易緩解焦慮的途徑。

然而要警惕掉到“用忙碌而逃避困難“的陷阱當中去,更好的緩解焦慮的方法是應用演算法,去解決具體問題。眾所周知,機器學習最不友好的部分不是程式設計,而是背後的數學原理,以及如何使用它來解決問題。照我來看,只有兩種情況值得動手造輪子:

  • 做研究,沒現成的輪子可用。以我的個人經驗和觀察,大部分研究的demo質量都比較堪憂。側面上反映了“科研工作者不等於好工程師”

  • 對自己的學習進度感到懷疑,可以試著實現一下演算法。但這種實現最多是驗證你學會了思路,而不能用於生產,因為效率和優化都比較差

  • 除此之外,對於研究者來說,復現前沿研究也有一定的價值,因為可能:

  • 作者並沒有開源(必須自己造輪子)

  • 在復現過程中你可能會發現作者值得改進的方向,發掘了新的灌水方向

  • 在復現過程中你可能發現作者的思路其實根本就是錯的,這也是為什麼很多paper不會公開程式碼,那麼避開這個陷阱

  • 對於大部分人而言,想要了解怎麼調參、每個引數的含義,都不必重新實現演算法。可以直接閱讀文件,也可以在在各種場景中慢慢摸索。比如參加比賽的過程中,或者實際工作裡,甚至看看部落格、讀讀知乎都可以有些收穫。同時,如果能夠通過解決實際問題來加深對模型的理解,還可以增強自己的信心,比實現演算法可能要更為划算且有效。

在不少公司,機器學習研究員和工程師是兩個崗位,前者提出思路和理論,後者去高效的實現。從這點上也不難看出一個實踐者不一定需要具備兩方面技能,畢竟時間有限。如果你對自己的定位是使用者(更接近工程師的話),多補補理論是當務之急。如果你想成為一個研究者,必要的程式設計能力要有,但不要花過多的時間在提高碼力上,能做好理論已經很難,可以交給工程師實現、優化你的理論。

所以,沒什麼特殊情況,實現演算法可以當做玩票,多看看模型、瞭解一些理論、應用到具體案例上去才是正事。

作者:陳默
https://www.zhihu.com/question/36768514/answer/83577695

我想這個題目我還是比較有發言權的,讀書時候曾經把PRML所有演算法實現過一遍。最後釋出了一個庫,現在是Github上星星最多的Matlab庫之一(應該是排第二)。讀PRML的同學可以參考一下,程式碼註釋給出了重要部分對應的公式在PRML的出處。變數命名也儘量與書做了統一。希望對學習PRML的同學有所幫助。大家覺得有用請幫忙點星星。

https://github.com/PRML/PRMLT

這個經歷對我的幫助大概有以下幾個方面:
1) 對演算法細節的理解更加深刻了。書中畢竟不會給出所有細節,而且書本身可能就是錯的。為了寫出程式碼,我幾乎是把所有公式重新推了一遍,自己存下的note裡面公式數量絕對遠遠多於書本身,期間也發現了書中無數的錯誤,這些錯誤在初讀的時候根本意識不到。這樣一遍下來,讓我對推公式的信心大增,看論文不會怕看不懂公式了。遇到看不懂的就推一遍,推不出的就抄一遍,之後總會懂的。一個side effect就是讓我變得憤青了,看什麼paper都覺得爛。因為讀paper的時候,你會發現,很多paper違背基本常識,即使影響力非常大的一些paper裡也有這樣那樣的錯誤。

2) 可以瞭解很多看書學不到的各種trick。所有演算法幾乎都有坑。比如hyper-parameter什麼意義怎麼設,怎麼初始化,numerical stability的怎麼保證,如何保證矩陣正定,計算機rounding error的影響,numerical underflow和overflow問題等等。

3) 對整個領域各個演算法的關聯有更深刻的瞭解,思維形成一個關係網。看到一個演算法就會自然的去想跟其他演算法的聯絡,怎麼去擴充套件。如果一篇paper我不能把它納入到這個關係網裡,我就覺得自己沒懂。要麼推出聯絡,要麼推出矛盾證明這篇paper垃圾。另一個side effect就是我看paper從來不根據實驗好壞判斷優劣。
雖然自己動手實現演算法有好處,但是價效比幾何還是個見仁見智的問題,畢竟這是一個很費時的過程。我並不認為一定有必要自己實現書上所有演算法,畢竟每個人所能關注的領域還是有限的,懂得演算法大致原理,具體用的時候在細研究就可以。很多演算法我也是寫完了從來沒用過。幾年過去後,我在回頭看自己的程式碼也很難看的懂,細節還得看公式。

但是對於自己的研究領域我建議還是有必要把經典演算法動手實現一遍加深理解。

作者:唐家聲
https://www.zhihu.com/question/36768514/answer/69348950

更新一段話,Quora上對於Yoshua Bengio的最新訪談,關於一個問題:
對於進入機器學習領域的年輕研究人員,你有什麼建議?(What advise do you have for young researchers entering the field of Machine Learning?)

他回答到:

Make sure you have a strong training in math and computer science (including the practical part, i.e., programming). Read books and (lots of) papers but that is not enough: you need to develop your intuitions by (a) programming a bunch of learning algorithms yourself, e.g., trying to reproduce existing papers, and (b) by learning to tune hyper-parameters and explore variants (in architecture, objective function, etc.), e.g., by participating in competitions or trying to improve on published results once you have been able to reproduce them. Then, find collaborators with whom you can brainstorm about ideas and share the workload involved in exploring and testing new ideas.  Working with an existing group is ideal, of course, or recruit your own students to work on this with you, if you are a faculty.

實現很有必要,甚至一定要。都實現一遍倒是不必。

1. 在掌握基本的演算法流程、加深對演算法的理解之外,實現機器學習演算法能夠幫助我們建立起一種直覺:資料--模型之間的關係。這一點可能有點玄學的味道...稍微往黑了點說,就是調參的直覺、模型選擇的直覺、特徵選擇/設計的直覺等...經驗有的時候是事半功倍的效果。

2. 在實際應用場景中,其實經常會遇到需要實現一些特殊設計的演算法。比如要實現某篇paper中的演算法/或者自己跑實驗,一般情況下這些演算法並不是(甚至肯定不是)通用演算法包提供的演算法,一定要自己實現。這樣的時候,如果以前有實現過基礎的演算法的經驗,會有很大幫助。

3. 實現基本的演算法,幫助掌握演算法流程。這樣會更容易應對新的程式設計框架。

4. 其實很多模型也有很多種解法。拿LR來說,常見的一階的Gradient Descent、二階的BFGS/L-BFGS之外(這些是好多庫的預設方法),一階的Back-tracking Line Search方法、Nesterov's Line Search等方法,實現起來(特別是分散式實現)比較複雜,讓沒有自己實現過任何機器學習演算法的人來寫。還是算了吧。

5. 演算法的細節:優化、高效計算等(矩陣乘法的加速等)在實際工作中是蠻重要的。因為機器學習在大規模資料下最大的挑戰就是如何『算』得更快:收斂速度/計算時間、計算資源/機器開銷等。所以得要知道在哪裡有優化的空間才行。

6. 但是全部實現一遍確實沒必要,不過常用的演算法的基本版還是要儘量都寫一寫的。


其實第一條是最重要的。

說了這麼多有沒有覺得不寫一遍簡直有罪?

*隨時修正答案,歡迎指出任何不足的地方!

作者:匿名使用者
https://www.zhihu.com/question/36768514/answer/664241510

看的人有點多了,也有人指出了之前言論中的不足,為了防止原答案產生誤導這裡重新補充一下。

1、是否要實現取決於需求,原答案預設假設大家之後不會以科研為主要出路

2、之前那麼寫是因為傳統機器學習在實際工作中已經很少用到了。比如SVM運算速度慢,rbf核的穩定性不高;GBDT,有XGBoost和LightGBM可以替代,實現GBDT的意義並不大,因為和後兩者還是有很多區別;Lasso和Ridge只是一階和二階範數約束,最小二乘會寫基本就ok,原答案寫了非要實現的話LR實現一下,LR如果會了基本一般迴歸都不是問題;聚類的話,內容差別很大,kmeans演算法實際使用也有很大限制,而別的比如吸引力聚類無需只定類別。在經典機器學習的使用頻率很少的情況下那麼去實現的優先順序就比較低。

3、看書+調包,這個似乎很有爭議。原回答有個大前提是提高自己的程式設計水平,可以刷leetcode,也可以去多看看github專案原始碼。比如別人寫一個虛擬碼能否自己用程式語言實現一下或者能寫個大概?如果不行,那麼首要的任務是提高程式設計水平,不然即使實現了一個演算法也僅僅是實現來一個演算法而已。不過這個問題似乎和專業有關,不同專業對這個的看法似乎會不同,一般而言理解原理不容易忘記,實現程式碼更容易遺忘,所以推薦看書為主,因為原理吃透的話,幾個月後或者是更久當提到這個演算法的話,特別是和別人溝通更方便,有人喜歡寫程式碼的話也行。但是如果完全掌握理論,自身程式設計水平也不錯的話,即使調包也不會很疑惑。

3、提到tf和sklearn框架的熟練使用是因為真的很重要且前者更重要,而tf和經典機器學習可以說完全不同,那要把各種神經網路都實現嗎?不然為什麼只實現經典機器學習而不實現神經網路呢?比如LSTM,CNN,MLP。實際工作中的主要框架是tf。

NLP用的模型是BERT和LSTM,重點是什麼?使用騰訊語料庫,基於向量加減算出新特徵,調整lstm引數,例如層數64,128,跑模型,接下一個業務,重複上面過程,然後看下最新論文。

推薦系統,一般公司大多會有原來系統,如果好就用新的,否則換舊的。推薦系統可以使用MLP,資料量大會涉及到分散式spark,然後最好會點scala,同理資料匯入(資料清洗會花去很多時間),上傳伺服器跑模型,連開幾十個程式,所以一般python程式池pool隨便開,不同的是這裡需要對tf最終話目標函式的調整,這個調整就很藝術性,同時要有一點低維嵌入的知識embeding,這個也很重要。

影像處理,模型主流CNN,重點在資料的獲取,有從網上爬蟲的,購買圖片的,甚至公司花錢請別人畫的都有,然後就是看最新論文,github開源專案,CNN的框架整體已經在那裡,不需要底層修改,重點在前期資料獲取(核心),調參,影像會比較麻煩因為有些會涉及到CAD,3DMAX方便各部門溝通,還有渲染的,但演算法主流還是CNN,只不過最新定會論文需要時時關注並復現。

量化交易,和上面稍有不同tf可以用,但用的多的反而是sklearn和xgboost/lightgbm,一個事實是金融特徵相比於傳統影像和自然語言更符合邏輯,如果純粹用深度學習自己產生特徵很容易過擬合,當然不是說不能用。這裡就是純粹調包俠了。

4、關於優勢,這個說實話很看學校和專案經歷以及是否發表論文,現在搞深度學習還有機器學習的學生水平比幾年前好很多很多了,以前你會個SVM推導,西瓜書,李航看下就可以找份不錯的工作。但現在很難,所以原答案強調書多看幾遍,《百面機器學習》,《美團機器學習》去看一下,基本理論知識大家都有了,所以需要應用方面的知識,還有就是理論知識越鞏固越好,剩下的競爭力不在於是否實現所有演算法,而在於程式設計水平是否足夠,是否有專案(kaggle也可以算)

5、最後在說下關於調包,雖然不太好,但是這個優先順序可以放在最前面,原因在於,所花時間最短收穫最高,詳細去看sklearn官網的話,很多演算法基本都是有數學公式寫出來的,看一下的話也可以明白演算法最終的求解表示式,tf官網寫的也很不錯,學習tf的話北大有一門mooc好像是《tensorflow筆記》,不長入門很快。也有人說按照這樣學面試一定掛,原答案其實也寫了,多投簡歷。BAT招的人畢竟不多而學機器學習的人已經過飽和了,微軟亞研院等也類似,如果想去這些公司那肯定還有很多工作要做。原文提到的幾家,漫道金服稅前21k,進去相對容易。平安系(有很多)大概30萬左右,攜程即使不做演算法,資料分析25萬,招行也很好,不過招的也少。網易33萬多,其實有很多可以去的公司,這些公司的薪水網上也是公開的。更何況還有一些人是去做量化交易的,不過機器學習量化交易類的起薪會相對低一些。

6、結論和之前一樣:

1)sklearn/tf官網優先看,不是說實現所有演算法不好,而是說優先順序不高,把LR實現一下。

2)書可以多看幾遍,而且每多看一遍話費的時間就會越短,經驗是可以積累的,比如曾經我看李航的書,第一次看是有點費勁,但是反覆看N遍,到最後看完一本書應該不需要1小時,因為很多早已爛熟於胸的內容就可以完全跳過。這樣當你以後複習時,看書話費的時間是很少的。因為記在腦子裡的東西很難忘記,同樣我曾經實現過《機器學習實戰》所有演算法,抄一遍,自己寫一遍,花了很多時間。但現在忘得差不多了,因為演算法實現有很多細枝末節的地方並不是演算法核心本身。

3)提高自己的程式設計水平,當你猶豫看書看完,然後對調包充滿疑惑甚至是覺得很空動時,問題出在程式設計水平不足而非機器學習演算法本身。這時你可以理解為實現演算法也在提高程式設計水平,但是提高程式設計水平不是說實現一個演算法就行的,僅僅實現忘得很快,之前說了刷leetcode是一個方式,github找一些開源專案看看別人寫的也是一種方式這兩種對程式設計水平的提高都有好處。

4)成為一個出色的調包俠,也許這個詞本身含有貶義所以很多人會不以為意,但是一個優秀的調包俠是不會對原理一竅不通的,一個很簡單的例子,比如有個任務使用卡爾曼濾波實現資料過濾,會去實現卡爾曼濾波嗎?一般的流程就是查下什麼是卡爾曼濾波,理解卡爾曼濾波原理,找下包呼叫,如果沒有自己實現。當新的任務不是你知識範圍內的內容需要把底層完全實現一遍還是去理解原理用別人造的輪子呢?論文復現使用基礎輪子比自己完全構造輪子效率高得多,而且運算速度也會快不少。

PS:每個人都有自己的看法,我只說出自己的經歷以及我所見到的情況,之前講過可能存在樣本偏差。

以下為原答案

——————————————————————

結論:沒必要。

相信很多學習機器學習都是從李航,西瓜書,各種公開課(林軒田,ag等等),然後拿本《機器學習實戰》基本演算法全部實現一邊。本人也是這麼做的,當時特有成就感,事實證明沒什太大用處。

1、程式設計水平的提高不會說實現了這幾個演算法就有長足進步,花這個時間不如多看幾遍sklearn和tf的文件成為一個合格調包俠

2、沒實現過演算法對演算法細節無法吃透?有這個時間不如把《西瓜書》,《統計學習方法》,《深度學習》再看一下,工程上的看下《百面機器學習》,《美團機器學習》,tf官網多掃幾遍。

3、身邊有人同時拿到阿里達摩院,京東,網易,360 4個offer的也沒見去實現底層演算法,去平安科技做NLP的師弟和同屆,同樣沒見人家去實現底層,同樣拿到漫道金服offer的也沒實現等等,還有很多很多,當然這也可能存在樣本偏差,但還是那句話有這個時間不如成為一個出色的碉包俠。

4、實際使用過程中經典的演算法基本就是LR,然後會用LightGBM等繼承演算法,剩下的不倫是做推薦系統、NLP、CV的基本是tensorflow或者同類深度學習框架,模型總體而言是經典的MLP,LSTM,CNN,BERT這些或者讀論文的一些變種模型。別的機器學習模型可以用但很少。

作者:李大貓
連結:https://www.zhihu.com/question/36768514/answer/598230450

1)寫linear regression時候才知道beta_hat的公式雖然是(x’x)^(-1)x‘y,但各種軟體包並不會這麼實現,原來qr或者svd分解更常用;

2)寫svm才知道sequential minimal optimization是1998年才發明的,才真的感覺到Microsoft research的強大;

3)寫logistic regression才發現原來reweighted least square名副其實,竟然真的可以直接呼叫linear regression的solver函式來解logistic regression

4)寫ridge regression發現通過簡單的擴充套件x和y(在下面加一些行),ridge regression就竟然又可以直接呼叫linear regression的solver!

5)寫完ridge regression結果不理想,才意識到penalized regression通常需要先對資料normalize

6)寫lasso/ridge時候才發現原來對intercept的處理挺微妙

7)常常被問到為什麼lasso的解sparse?看過the element of statistical learning的朋友都知道可以從constraint和likelihood function的contour展開說,或者從bayesian角度講講Laplace prior。直到寫了cyclic coordinate descent解lasso才知道程式裡soft thresholding operator (STO)到底是怎麼工作讓beta_hat變得sparse的

8)自己寫一個gradient boosting machine 才知道xgboost速度是真快

9)嘗試寫knn才發現原來資料結構和演算法在機器學習裡面的重要性

綜上,如果非要實現的話LR實現一下差不多了,剩下的時間提高自己的程式設計能力,上面的書多看幾遍,Leetcode刷一些,Paper能發就發,不能發也沒事,反正簡歷投的多就行。如果不走網際網路那隻要原理記牢,成為一個出色的調包俠即可,如果還沒時間,首先成為一個出色的調包俠。

- END -
如果看到這裡,說明你喜歡這篇文章,請轉發、點贊掃描下方二維碼或者微信搜尋「perfect_iscas」,新增好友後即可獲得10套程式設計師全棧課程+1000套PPT和簡歷模板向我私聊「進群」二字即可進入高質量交流群。
掃描二維碼進群↓
有沒有必要把機器學習演算法自己實現一遍?
有沒有必要把機器學習演算法自己實現一遍?

有沒有必要把機器學習演算法自己實現一遍?

在看 有沒有必要把機器學習演算法自己實現一遍?

相關文章