經常造輪子的 AI 工程師水平通常不會太差
引子 | 造輪子還是不造輪子,這是一個問題
理查德·費曼教授去世後,人們在他的黑板上發現了 What I cannot create, I do not understand 這句話。其實,費曼教授的本意是:除非你能由基本原理推匯出某個結論,否則就沒有真正理解它。記結論或背公式是沒有用的,只有從一張白紙開始一步步地將結論構建出來,你才是真正理解了一個理論或一個事物。
程式設計師愛說一句話:不要重複造輪子。在工作和生產中的確不應該重複造輪子,但在學習和理解的過程中卻需要重複。
費曼教授的黑板上還有一句話:Know how to solve every problem that has been solved(應該知道每一個已被解決的問題的解決方法)。許多教師都會強調習題的重要性,這是對的。在座的諸位“做題家”對此自然也體會深刻。但費曼教授更高一籌,他所傳達的思想是做題不是目的,目的是教人學會自己動手構造。光看明白是不夠的,只有會造輪子才能改進輪子;只有會解有答案的問題,才能去解決還沒有答案的問題。
1.重新構建整棵樹才能真正認識一棵知識樹
如果將一個領域的知識比作一棵大樹,那麼我們對它的認識過程不應該是從外向裡、從頂向下的,不應該只滿足於認識並記住它那繁多的樹葉。以神經網路與深度學習為例,初學者往往會陷入茴字四種寫法的誤區,並且以知道各種模型、各個網路為榮,從而陷入概念和術語的迷宮卻看不到它們之間存在的更深刻的聯絡。
也就是說,要想認識一棵樹,從樹冠開始一片一片認識每個樹葉無疑是效率低下的。更重要的是,通過這種方式根本無法達到真正理解。我們應該從樹根出發,沿著樹幹向上,並嘗試重新構建整棵樹。在此期間,可以在某個樹枝的根部就停下來,因為那時會發現,剩下的細枝末節(字面意思)已經不再重要了,只要在需要的時候再檢視那個分支就行了。
總之,要想真正地理解(understand)一個領域,就必須能從基本原理出發重新建造(create)它們,最終你會具備統一的、非碎片化的眼光。
2. 從零開始打造一款深度學習框架
1984 年,《現代作業系統》(俗稱馬戲團書)的作者塔嫩鮑姆教授(Andrew S. Tanenbaum)開發了一個教學用的作業系統 Minix。受其啟發(多大程度未知),Linus Torvalds 創造了 Linux 系統。
這裡我們決定效仿前輩,帶領讀者用 Python 語言從零開始實現一個基於計算圖的機器學習/深度學習框架,我們稱其 MatrixSlow。取這個謙卑的名字是為了表明它只是一個用於教學的框架。若在座諸君中有哪位能受其啟發並創造一個專業的深度學習框架,我們將深感欣慰。
3. 為何實現基於計算圖的深度學習框架
計算圖是一個強大的工具,用它可以搭建並訓練從簡單的線性迴歸、邏輯迴歸到複雜的深度神經網路等一大類機器學習模型。計算圖通過自動求導和梯度下降法,以統一的方式給這一類機器學習模型提供了訓練演算法。因此,實現了計算圖也就等於實現了大部分機器學習演算法。
在一步步帶領讀者實現計算圖框架的同時,我們還介紹了機器學習、模型、訓練等相關概念和原理(我們假設所有讀者都沒有前導知識,完全從空白講起)。
此外,本書以相當大的篇幅介紹了線性模型、邏輯迴歸、多層全連線神經網路、非全連線深度神經網路、迴圈神經網路和卷積神經網路等模型的原理和結構,並且尤其注重它們之間的聯絡。讀者會看到,動機和思路是如何被反覆應用並逐漸發展的。我們還以一些實際問題為例展示了這些模型的應用。
最後,我們討論了一些工程方面的問題,例如模型的儲存與服務、分散式訓練以及要想實現專業級深度學習框架還需應對的若干問題。
4. 是否有必要親手實現模型
雖然本書的主旨為理解與建造,但是通過建造達成理解才是關鍵。時常會有朋友問:“是否有必要親手實現模型?”必要與否很難界定,這取決於想要實現模型的人的目的和工作層次(這裡的層次並無高低褒貶之意)。所以,我們不談目的與必要性,只談親手實現模型的好處。以我的淺見以及親身經歷來看,親手實現模型極其有助於夯實理解。
在動手實現模型的過程中,你不得不把對理論的理解釐清到最細微處,這裡容不得半點含糊。更重要的是,當自己實現的模型運轉起來,應用於實際問題以測試其正確性時,現實會逼迫你反覆測試,這個過程可以極大地幫助你加深對於模型行為的理解。作為程式設計師,測試本來是一件在概念上簡單明確的事情。在設計程式的時候,預測有如此這般的輸出,它就應該有如此這般的輸出。對於一個斷言(assert)來說,它過就是過,不過就是不過。但是在機器學習領域,這個正規化就會有一定程度上的失效。
我們知道,模型(起碼本書討論的這類模型)的訓練是一個近似迭代優化的過程,其中到處存在隨機性:引數的隨機初始化,樣本的隨機洗牌(shuffle)以及一些例如 Drop Out 之類引入隨機性的正則化方法等,都會帶來不確定性。訓練的結果,比如模型引數、損失和評價指標等,都只具有統計意義。
更重要的是,模型在樣本集上的損失取決於問題本身,我們不可能知道這個高維函式的真實“地形”。基於梯度的優化演算法也不能保證可以找到全域性最優點。全域性最優點可能根本就不存在或者存在但不唯一。所以,模型訓練根本沒有嚴格的正確與否一說。
但是,模型的實現總有對錯。錯的實現在各個測試問題上都不會有好的表現。簡單來說,好的表現就是隨著訓練的進行,損失值降低而指標上升。但是,受制於問題本身、模型結構以及超引數,對的實現有時也未見得會有好表現,或者好表現的現象需要很久才能顯現。
這迫使實現者必須反覆在各類問題上驗證自己的實現,嘗試各種模型結構和超引數的組合,這是一個永無終點的過程。實現者對自己的實現的信心會隨著無數次嘗試而逐漸堅定。更為寶貴的是,所有的這些操作和觀察都能幫助實現者建立起對模型行為的認知和直覺。
我們知道,結構和超引數控制著模型的自由度,自由度又決定了模型的偏差方差權衡,進而影響了模型的過擬合/欠擬合。
在物理學中,一套完整的約束可將動力系統的自由度降低一個整數值。由此,之後就可以用數量更少的廣義座標表示該系統。類比到模型訓練,正則化方法施加的約束並不是完整的,模型的自由度也不是整數。
狹義的正則化之外的超引數,乃至模型結構,都在以複雜的方式影響著模型的自由度。我們常說調參,就是以一種經驗的、半猜半試的方式控制模型自由度,以改進模型的表現。當然,我們還有網格搜尋和隨機搜尋,以及一些非引數優化演算法,如遺傳、貝葉斯等,但是它們都需要較大的計算量,使得我們在大部分時候難以承受。
瞭解每一個超引數的原理和含義,以及它們對自由度的大致影響,是建模工程師的必備能力。
各種超引數在具體問題、具體模型上究竟會以什麼形式產生什麼影響,只有經過觀察和經驗的積累才能形成認識。實現並驗證模型的過程,就是一個密集經歷這種觀察和經驗積累的過程。
在複雜的科學和技術領域,親身經歷與體驗是必不可少的,這是一個經歷生命的過程。魔鬼梅菲斯特曾對拜訪浮士德博士的青年學生說:“理論是灰色的,而生命之樹長青。”
5. 讀程式碼的終極大招在機器學習中失效了
既然說到了理論,這又是一個機器學習領域與程式設計師熟悉的其他領域不同的地方。實現和應用機器學習必須要理解其原理,而閱讀其他領域的原始碼時,只要把程式碼讀透也就徹底理解了。你也許會這樣想,在完全知道記憶體、匯流排和CPU 中發生的每一件事後,我難道還不能理解這個程式在幹什麼嗎?對於機器學習來說,這還真不夠。比如,你在某處看到了一個計算,但是這裡為什麼要計算?計算的目的是什麼?為什麼有效?這些可不是程式碼能告訴你的。“讀程式碼”原本是程式設計師瞭解一個東西的終極大招,但是在機器學習這裡又失效了。
有種常見的說法是把公式推導一遍。理解機器學習的數學原理可不能只是簡單地“推導公式”,而應該要理解公式究竟說了什麼。當然,在初學時能夠把公式推導的每一步都弄明白就已經不易了。但是如果把注意力都集中到推導,又容易使人難以看清這些公式究竟表達了什麼。這就好比雖然踩著腳印亦步亦趨,最後確實也走到了目的地,但始終沒有抬頭看清這是什麼路,目的地是哪裡,為什麼走這條路,而這些才是最重要的。
人們總是希望(妄想)生活中不要有數學。實際上,所謂數學和非數學,無非都是在說事說理而已。要想把事情說得精確深刻,就必須把相關的量以及量之間的關係說清楚,而數學就是簡潔地表達這些關係的一種手段。
由於本書面向的是初學者,因此在數學上沒有搞得太深入、太複雜。我們會盡力闡述,以幫助讀者掌握機器學習的數學所說的“事”是什麼,也就是“推導公式”時容易看不清的那些東西。
本書不避諱使用公式,因為這是必不可少的,但量確實不大。我們把一些較為高階的主題放在了選讀框中。讀者可以根據實際需要選擇是否略過這些高階主題,而不至於干擾閱讀。記住,數學永遠都是必要的。鑑於此,讀者可以參考本書的姊妹篇《深入理解神經網路:從邏輯迴歸到CNN》。
6. 內容簡單介紹
本書分為三個部分。第一部分是原理篇,包含第 1 章至第 3 章。其中,第 1 章介紹機器學習的基本概念,引入了一個簡單的線性模型 ADALINE,這一章介紹的概念貫穿本書。第 2 章介紹計算圖,其核心內容是計算圖的原理、梯度下降法以及計算圖上的自動求導。第 3 章介紹梯度下降法的各種變體。在前三章中,我們帶領讀者實現 MatrixSlow 框架的核心基礎設施,並在此過程中滲透講解基礎原理和概念。
第二部分是模型篇。有了基礎設施,我們就可以搭建各種模型了。本部分包括第 4 章至第 8 章。其中,第 4 章介紹邏輯迴歸,第5 章介紹多層全連線神經網路,第 6 章介紹幾種非全連線神經網路,第 7 章介紹迴圈神經網路,第 8 章介紹卷積神經網路。這些模型/網路的選擇和順序不是任意的。我們的想法是由簡到繁、由淺至深地介紹其動機和思路的發展演變,使讀者看到這些典型的、常用的模型/網路之間的聯絡。雖然原則上讀者可以按照興趣選讀這些章節,但是我們還是建議大家能按順序閱讀,特別是第 4 章和第 5 章。模型雖然簡單,但它們是後續一切複雜延伸的基礎和出發點。
第三部分是工程篇。在這一部分中,我們將討論一些與深度學習框架相關的工程問題。本部分包括第 9 章至第 12 章。其中,第 9 章對訓練邏輯做進一步封裝,並討論模型評估;第 10 章介紹模型的儲存、載入、預測和服務部署;第 11 章介紹分散式訓練,在大資料和深度學習時代,樣本量和網路規模都是巨大的,這些使得分散式訓練必不可少;第 12 章簡單討論要實現一個專業級的深度學習框架還需面對和處理的一些問題。
7. 大佬推薦
這是一本引人入勝的書,它通過由淺入深地講解讓你瞭解深度學習的原理、模型和實現方法,內容清晰易懂,表達生動形象。
——邱錫鵬,復旦大學計算機學院教授
我們團隊做了好幾年深度學習框架研發,一直苦於沒有好的入門教材。現在終於有一本書把深度學習框架的工作原理通俗易懂地講了出來。
——袁進輝,一流科技創始人兼 CEO
對於複雜難懂的概念,除非親手實現,否則很難真正理解掌握。我非常贊同這個理念,很高興作者把這個建造與理解的過程分享出來,為眾多對這個領域感興趣的朋友提供參考。
——趙勇,格靈深瞳創始人兼 CEO
本書提供了框架本身和構建各類模型的程式碼,既深入核心原理,又淺顯易懂。所謂“不能創造,無法理解”,相信通過自己打造一個深度學習框架,讀者可以更深入地理解其中的原理。
——鄧亞峰,奇虎 360 集團副總裁、人工智慧研究院院長
8. 作者簡介
張覺非
本科畢業於復旦大學計算機系,於中國科學院古脊椎動物與古人類研究所取得古生物學碩士學位,目前在網際網路行業從事機器學習演算法相關工作。
陳震
碩士畢業於北京大學。現任奇虎 360 智慧工程部總監、負責人,帶領團隊建設集團的機器學習計算排程平臺、機器學習建模平臺、機器學習推理引擎以及推薦平臺等AI基礎設施。
9. 跟著這本書造個大輪子
相關文章
- 造輪子 -- RxRouter
- 造輪子-ThreadPoolExecutorthread
- 程式設計師應該造的五大輪子程式設計師
- 造輪子之EventBus
- 造輪子-strace(一)
- ?揭祕vue/react元件庫中?5個"作者不造的輪子"VueReact元件
- 好久不見,我造了一個輪子:微開發
- 造一個「輪子」musionUIUI
- 造輪子之整合GraphQL
- 造輪子之ORM整合ORM
- 談談程式設計師重複造輪子的幾點思考程式設計師
- 造了個滾輪控制元件輪子控制元件
- 造輪子之圖片輪播元件(swiper)元件
- 在NPM釋出自己造的輪子NPM
- 造後臺輪子引發的思考
- 那些年我造的輪子之RPCRPC
- Go~避免重複造輪子Go
- 造輪子之多語言管理
- 給 Java 造個輪子 - ChainJavaAI
- 造輪子-strace(二)實現
- 也造了一個 dump 的小輪子
- 高年薪的Web前端工程師經常思考哪些問題?Web前端工程師
- 「造個輪子」——cicada 原始碼分析原始碼
- 造輪子之許可權管理
- 什麼水平的java工程師月薪3萬起?Java工程師
- 造輪子之訊息實時推送
- 造輪子之自定義授權策略
- smol 作者造新輪子 futures-lite
- 原生JavaScript實現造日曆輪子JavaScript
- 工程師基本常識工程師
- 華為校招三輪面經:通用軟體開發工程師工程師
- 一年前端造的輪子是什麼樣子?前端
- 程式設計師為什麼熱衷於造輪子,升職加薪嗎?程式設計師
- 原生js造輪子之模仿JQ的slideDown()與slideUp()JSIDE
- 手動造輪子——基於.NetCore的RPC框架DotNetCoreRpcNetCoreRPC框架
- 重複造輪子了, 自己開發的 Laravel RepositoryLaravel
- 我造了個好大的"輪子",居然還不是"圓"的!
- 造輪子之圖片預覽元件(preview)元件View