機器學習的問與答 ── 常見的開發問題和如何學習

最近有機會和一位朋友──鄭穎鍾──討論我們在做資料科學及機器學習上所遇到的一些問題。由於我們都是數學背景出身,所以在經歷和做事的方法上多少有些雷同。但因為我們在不同的產業工作,會遇到不同的問題,我和穎鍾討論後,決定把我們的想法寫下來,提供大家參考。

討論

1. 為什麼你會想聽建議? 是覺得自己遇到瓶頸, 或覺得轉進業界還是有斷層?

穎鍾:會想知道學長的經驗跟建議,主要跟這半年來參與公司的案子息息相關,或者說成就感吧。不得不說這段時間學了很多純數之外的ML、DL相關知識,但是很常發生以下事情:

  1. 模型無法real time,但就是因為DL比起傳統演算法的靈活度更高但是參數更多所以運算量變大
  2. 沒有解決問題的SOP,或者是說都是因緣際會下調了某個架構、設了某個參數後做出某個好結果才去解釋,但是同一套架構用在不同的training data,結果又有所出入時,又會換另外一套架構與解釋…
  3. 神經網路是黑盒子,他為什麼做對、錯,什麼時候會做對、錯,不知道,只有按下predict後才會知道,比如判斷性別的model去預測同一張圖的同個男生可能因為背景不同而去導致不同的預測結果

以上三點算是冰山中的一角吧,也算是在做DL的都會遇到的問題,但是每個案子最後都陷入這種循環才讓我思考是否自己在正確的方向…【一件案子冒出來→建個模型並調整,去達到高的準確率,然後也只能在達到準確率門檻時再解釋為什麼這麼做會對→一個模型不可能達到100%準確,所以別人詢問時也只能以”猜測模型在幹嘛”去做解釋→最後因為DL參數量大不能 real time prediction,先擱著吧,因為不可能在應用時搭載GPU】

因此,我才想知道學界或是其他業界在ML、DL的開發生態與經歷是如何…這算瓶頸…吧XD 又或者是我不清楚在業界到怎樣的地步才算有成就感,之前當學生只要考高分就有成就感XD

2. 或許你可以列出幾個想討論/想聽的點?

穎鍾:最想聽的大約是:

  1. 學長在做ML有遇過我如上提的那些模型問題嗎(不過你說你不是做DL我不知道問題一不一樣@@)
  2. 如何知道在這家公司學的東西與方向正確否?我知道這個問題可能太空泛,要看自己的目標之類的,但是我還是這樣問就是因為【一開始很開心學了很多東西→但學的這些東西很常遇到第一題所說的那些問題,而且目前無解→那我學的這些東西是正確方向嗎】
  3. 承 2,或許是第一份工作的關係吧,我真的不知道該用什麼價值觀去看待目前遇到的問題耶@@?

3. 數學和業界接軌?

我:這是拋給你的問題 - 之前我有個朋友在大學教書, 數學系. 她問我在學校學的東西有什麼和我現在在業界做的相關, 要怎麼改課綱才能讓學生和業界接軌. 我想了半天, 除了看一些計算過程以外, 實在沒有特別跟數學系相關的部分. 你對這件事有什麼看法? 是如何改課綱以便接軌?還是我認不認同接不了軌?

穎鍾:以我沒任何準備就休學,沒有純數之外的知識基礎上就去面試金融與科技業的經驗,確實…不用說接軌了,連邊都碰不上XDDD

講難聽點,如果時間重來,最快的接軌方法只有先 破釜沉舟 選定一個方向,比如科技業,然後再把範圍縮小,比如軟體工程師,然後花一兩個月苦學coding與看開放式課程,然後考證照、用程式做些作品放在履歷….咦,怎麼在做資工系在學校就在做的事?因為數學系學的東西完全用不到,唉~原本我還很樂觀,不相信現實的殘酷,覺得還是會有業界看上的,但是念數學唯一能說出最具像化的東西只有邏輯思考能力,沒了!而且這還很抽象,你邏輯思考很好,證明給我看阿!但是不能用你所學的東西證明給他看,因為這些東西面試官看不懂也不care…

我覺得這問題存在很久了,說真的也希望看到數學系產學合作的一天,以我個人而言,我還是很喜歡數學,但是我沒有辦法不顧及【學這些能幹嘛?】,我就是因為這句話從碩一以來一直盤繞在我腦中,越念越沒動力,【考得高、考得過、也有成就感,正向循環,所以我就繼續念】這心態能帶給我的力量越來越少了…

因此,本質上要解決這問題,最根本的就是不是自我安慰【數學可以幹嘛】,而是去證明【數學真的可以幹嘛】,這也是我對自己的長遠要求,我真的不想相信花了快十年而且自己有興趣的東西到現實世界就是一坨屎QQ 雖然一堆coding 與ML 知識都是統計與數學的結合,但,比如以PCA 為例,不知道原理的也是call API 就可以做PCA,知道原理的也只是心理快活很多知道他在幹嘛,但是以結果論而言這兩個人的產物都是一樣的,會數學的那個人並沒有多出什麼…

最後,像我有這份工作,很感謝主管當初因為我是數學系&學流形的才找我,雖然manifold learning 跟 Riemannian manifold 關聯很少XDDD 純數出來的只能靠面試官願意給你一個機會,而不是自己去爭取來的一個職位…在我觀念裡,覺得一份好的工作應該是自己在這領域有一定程度的理解與表現,對方也肯定你的能力,但是就是因為純數在業界並沒有一席之地,所以我在面試官面前就是一個什麼都不會的人,要拿到某個工作只能自己私下惡補,那我乾脆當初就念那個系就好啦XDDD

我的回答

其實為了回答你的問題,我想了很久。

原因無他,因為不只是你有這個問題──我也不知道什麼叫學到一定水準。

舉例來說,如果你叫我現在建一個影像辨識用的神經網路,我大概也沒辦法作得比網路上一些教學來得好,因為平常並沒有花很多時間在實作類似的東西。

所以到現在我還沒辦法給你一個確切答案。我現在的作法是,看自己想做的是什麼東西,再去蒐集相關工作的人會用到的工具和作法,來幫助自己擬定一個計畫。

遇到瓶頸的感覺真的很幹 遇到瓶頸的感覺真的很幹

常見的開發問題

根據我在美國的觀察,會說每個案子都陷入這樣的循環也是相當正常。畢竟沒按下 predict 之前真的沒人知道會發生什麼事。但換個想法來看,要怎麼作才能在同樣的時間內按下 predict 更多次,而且每次 predict 都是實踐不同的想法?

這就牽涉到軟體工程的方法,所以我最近讀了不少寫程式相關的書。不一定是學什麼語言或怎麼寫,而是學除了在寫程式碼之外,要怎麼測試自己的程式,要怎麼作 version control 來和同事合作,諸如此類的問題。把會浪費時間的部分處理掉,才能更快的試不同的想法。因為在探索的過程中,其實大部分寫出來的程式碼到最後都派不上用場,所以動作越快,就能撈更多東西,撈到寶的機會也就會變高。

換句話說,就是從每天做重複的事的框架中跳脫出來,以抽象的角度來思考整個專案的過程。很像是數學在寫證明時,寫完一次以後,過一陣子又回來重寫一次。或許這就是數學界的強項也說不定?

很多實作上遇到的問題,當我從抽象的步驟下去考慮,就會發現其實我做了好幾次同樣的事。既然如此,那我是不是可以寫一個小程式,我下次遇到重複的問題的時,就可以省去處理這個步驟的時間?

舉例來說,我能不能從資料庫抓資料抓得更快?能不能更快的作圖把資料中的例外點更快的抓出來?能不能讓程式幫我整理模型預測出的值,讓我更快抓出這個模型在資料的哪些部份特別不準?要進 production 前有哪些難題,我要怎麼解決?甚至是和程式完全無關的:在開始寫程式碼前,要怎麼更快理解業務或客戶到底在想什麼,或把專案帶往較有可能有結果的方向?之類的。

而關於實作上的抽象步驟,我最近有些想法會放在其他文章裏面討論。預計會至少寫三篇。

怎麼學東西

常常有人問我到底要學什麼東西,要學了多少,才能找資料科學相關工作。其實不管什麼工作都一樣。判斷我程度到哪裡是其他人的事──又沒有人付錢給我。我能作的就是不斷進步。

所以我現在不會去問自己要學到什麼程度,但我會問「這件事要花我多少時間」:一年之後的我,能不能用同樣的時間作更多的事?

開始的第一步就是自己寫下自己想要做什麼,然後擬訂計畫。就像體育選手一樣,每個選手都有自己的訓練菜單。而訓練的目的是讓自己在某個方面變得更好。自己設定了目標,就能規劃自己的時間,就能有效利用這些時間不斷進步。

我研究所時修過最沒用的一門課叫做李代數。那時博士班二年級不知道要選什麼課,想到以前在念相對論時常常聽到李群、李代數,所以看到系上有開,就選下去。過了一個半月以後興趣完全消磨殆盡。最後兩個月我還有去上課,但都沒交作業,老師人很好還給我一個C- (比當掉高一階)。但這個問題就是源自於課表不是我自己寫的,而是系上已經定好了。等別人來幫我設計課表,我再去挑,不管怎麼挑都不會合身。

所以現在,當我在設定自己接下來六個月、一年、三年要做什麼的時候,我會認真考慮計畫,並盡早開始實行。自己寫下來的總是至少我有些熱情的東西。如果兩個月過去了,發現這不是我想要的,那也沒有人幫我打成績,也不用硬要做完,再把精力花去投資其他有回報的地方就是了。

學習 = 投資

最近我讀到一本書叫 Pragmatic Programmer (中國翻譯為程序員修煉之道),其中一段我非常喜歡。

書中講到,學知識其實就和理財的投資組合一樣。如果要有好的報酬率,就必須養成定期投資的習慣,並且分散風險—有時候要買投報率穩定的績優股,有時候要買有爆發力的新創企業,並且定期回顧,把沒有價值的資產砍掉,投資到能賺錢的方向。

學習也是這樣。如果在規畫自己的生涯時不知道該學什麼,那就先都學一點吧。如果短線看不出來,那就分散風險,每個籃子都放一點。用長線投資的方法,應用到如何獲取知識上。每天讀30分鐘的技術文章,額外寫30分鐘的 code,參加一些小型的集會等,都是很好的方法。

不需要把雞蛋放在同一個籃子裡 不需要把雞蛋放在同一個籃子裡

我覺得數學念久了,會有想把學到的東西分門別類的想法。但其實在社會上分類並沒有那麼細。所以我目前大致上會用下面這個準則來學東西:

長期技能和短期技能

所謂的長期技能,意思是可以帶著走,不會因為換環境或換工作就失效的技能。舉例來說,

短期技能: 像是網頁前端的各種架構 (React 之類),大約每一兩年就會變。學了以後時效性有限。 長期技能: 有和工作直接相關的,像是專案管理的技巧,演算法,或是不會退燒的 C++。也包括專業技能,像是和客戶的溝通能力,寫作能力,架設網站等等。

我認為長期技能比短期技能值得投資。

以我最近的作法當個例子:

短期技能: 我目前在用這本書 學 pytest。pytest是 一個 Python 的測試框架,我因為在探討要怎麼寫出更好維護的程式碼,而且平常工作是用 Python ,所以就挑了一本書來讀並且實作。

長期技能: 要怎麼錄音、剪接影片等等。目標是做出有一定品質的影片放到 Youtube 上。

註:個人興趣則不在此列,想學什麼就學什麼。

破釜沉舟

我很喜歡你用的一個詞”破釜沉舟”

「如果要拿到某個工作只能自己私下惡補,那我當初念那個系就好啦!」 這句話滿中肯的。只是最大的問題就是──沒有能透視未來的水晶球。我想回到過去、改變未來這件事,目前是不可能的,所以我能做的就是認清事實,讓自己的技能變得更有價值,而不是回頭說「阿,其實這件事很有用阿」。因為沒用就是沒用。

像我的家人,常常會問我「你現在工作跟你學的有什麼關係」啊就沒什麼關係你是要問什麼?我的經歷讓我現在有這樣的思考模式和想法,為什麼我還非得作跟我以前相關和一樣的事?美國生活讓我見識到其實人的潛力是無窮的。雖然我現在叫我去練身體然後上大聯盟打全壘打這件事大概是不太可能以外(其實人生沒有不可能,但現在叫我去練到上大聯盟的期望值和其他能做的事相比實在太低,比買彩券還低),很多事我都還能做啊。

但這種問題也不奇怪。來到美國以後,我發現台灣教育環境訓練出的思考模式是線性的,生涯就是鋪好的路,從畢業的A點到退休的B點,念電機就是進竹科, 念醫科就是當醫生。但我在美國的看了形形色色的人,發現人生比較像布朗運動,到底這顆花粉最後會到哪裡,沒有人知道。

Written on November 9, 2018