經(jīng)常造輪子的 AI 工程師水平通常不會(huì)太差
引子?| 造輪子還是不造輪子,這是一個(gè)問(wèn)題
理查德·費(fèi)曼教授去世后,人們?cè)谒暮诎迳习l(fā)現(xiàn)了 What I cannot create, I do not understand 這句話。其實(shí),費(fèi)曼教授的本意是:除非你能由基本原理推導(dǎo)出某個(gè)結(jié)論,否則就沒(méi)有真正理解它。記結(jié)論或背公式是沒(méi)有用的,只有從一張白紙開(kāi)始一步步地將結(jié)論構(gòu)建出來(lái),你才是真正理解了一個(gè)理論或一個(gè)事物。
程序員愛(ài)說(shuō)一句話:不要重復(fù)造輪子。在工作和生產(chǎn)中的確不應(yīng)該重復(fù)造輪子,但在學(xué)習(xí)和理解的過(guò)程中卻需要重復(fù)。
費(fèi)曼教授的黑板上還有一句話:Know how to solve every problem that has been solved(應(yīng)該知道每一個(gè)已被解決的問(wèn)題的解決方法)。許多教師都會(huì)強(qiáng)調(diào)習(xí)題的重要性,這是對(duì)的。在座的諸位“做題家”對(duì)此自然也體會(huì)深刻。但費(fèi)曼教授更高一籌,他所傳達(dá)的思想是做題不是目的,目的是教人學(xué)會(huì)自己動(dòng)手構(gòu)造。光看明白是不夠的,只有會(huì)造輪子才能改進(jìn)輪子;只有會(huì)解有答案的問(wèn)題,才能去解決還沒(méi)有答案的問(wèn)題。
1. 重新構(gòu)建整棵樹(shù)才能真正認(rèn)識(shí)一棵知識(shí)樹(shù)
如果將一個(gè)領(lǐng)域的知識(shí)比作一棵大樹(shù),那么我們對(duì)它的認(rèn)識(shí)過(guò)程不應(yīng)該是從外向里、從頂向下的,不應(yīng)該只滿足于認(rèn)識(shí)并記住它那繁多的樹(shù)葉。以神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)為例,初學(xué)者往往會(huì)陷入茴字四種寫法的誤區(qū),并且以知道各種模型、各個(gè)網(wǎng)絡(luò)為榮,從而陷入概念和術(shù)語(yǔ)的迷宮卻看不到它們之間存在的更深刻的聯(lián)系。
也就是說(shuō),要想認(rèn)識(shí)一棵樹(shù),從樹(shù)冠開(kāi)始一片一片認(rèn)識(shí)每個(gè)樹(shù)葉無(wú)疑是效率低下的。更重要的是,通過(guò)這種方式根本無(wú)法達(dá)到真正理解。我們應(yīng)該從樹(shù)根出發(fā),沿著樹(shù)干向上,并嘗試重新構(gòu)建整棵樹(shù)。在此期間,可以在某個(gè)樹(shù)枝的根部就停下來(lái),因?yàn)槟菚r(shí)會(huì)發(fā)現(xiàn),剩下的細(xì)枝末節(jié)(字面意思)已經(jīng)不再重要了,只要在需要的時(shí)候再查看那個(gè)分支就行了。
總之,要想真正地理解(understand)一個(gè)領(lǐng)域,就必須能從基本原理出發(fā)重新建造(create)它們,最終你會(huì)具備統(tǒng)一的、非碎片化的眼光。
2. 從零開(kāi)始打造一款深度學(xué)習(xí)框架

1984 年,《現(xiàn)代操作系統(tǒng)》(俗稱馬戲團(tuán)書)的作者塔嫩鮑姆教授(Andrew S. Tanenbaum)開(kāi)發(fā)了一個(gè)教學(xué)用的操作系統(tǒng) Minix。受其啟發(fā)(多大程度未知),Linus Torvalds 創(chuàng)造了 Linux 系統(tǒng)。
這里我們決定效仿前輩,帶領(lǐng)讀者用 Python 語(yǔ)言從零開(kāi)始實(shí)現(xiàn)一個(gè)基于計(jì)算圖的機(jī)器學(xué)習(xí)/深度學(xué)習(xí)框架,我們稱其 MatrixSlow。取這個(gè)謙卑的名字是為了表明它只是一個(gè)用于教學(xué)的框架。若在座諸君中有哪位能受其啟發(fā)并創(chuàng)造一個(gè)專業(yè)的深度學(xué)習(xí)框架,我們將深感欣慰。
3. 為何實(shí)現(xiàn)基于計(jì)算圖的深度學(xué)習(xí)框架
計(jì)算圖是一個(gè)強(qiáng)大的工具,用它可以搭建并訓(xùn)練從簡(jiǎn)單的線性回歸、邏輯回歸到復(fù)雜的深度神經(jīng)網(wǎng)絡(luò)等一大類機(jī)器學(xué)習(xí)模型。計(jì)算圖通過(guò)自動(dòng)求導(dǎo)和梯度下降法,以統(tǒng)一的方式給這一類機(jī)器學(xué)習(xí)模型提供了訓(xùn)練算法。
因此,實(shí)現(xiàn)了計(jì)算圖也就等于實(shí)現(xiàn)了大部分機(jī)器學(xué)習(xí)算法。在一步步帶領(lǐng)讀者實(shí)現(xiàn)計(jì)算圖框架的同時(shí),我們還介紹了機(jī)器學(xué)習(xí)、模型、訓(xùn)練等相關(guān)概念和原理(我們假設(shè)所有讀者都沒(méi)有前導(dǎo)知識(shí),完全從空白講起)。
此外,本書以相當(dāng)大的篇幅介紹了線性模型、邏輯回歸、多層全連接神經(jīng)網(wǎng)絡(luò)、非全連接深度神經(jīng)網(wǎng)絡(luò)、循環(huán)神經(jīng)網(wǎng)絡(luò)和卷積神經(jīng)網(wǎng)絡(luò)等模型的原理和結(jié)構(gòu),并且尤其注重它們之間的聯(lián)系。讀者會(huì)看到,動(dòng)機(jī)和思路是如何被反復(fù)應(yīng)用并逐漸發(fā)展的。我們還以一些實(shí)際問(wèn)題為例展示了這些模型的應(yīng)用。
最后,我們討論了一些工程方面的問(wèn)題,例如模型的保存與服務(wù)、分布式訓(xùn)練以及要想實(shí)現(xiàn)專業(yè)級(jí)深度學(xué)習(xí)框架還需應(yīng)對(duì)的若干問(wèn)題。
4. 是否有必要親手實(shí)現(xiàn)模型
雖然本書的主旨為理解與建造,但是通過(guò)建造達(dá)成理解才是關(guān)鍵。時(shí)常會(huì)有朋友問(wèn):“是否有必要親手實(shí)現(xiàn)模型?”必要與否很難界定,這取決于想要實(shí)現(xiàn)模型的人的目的和工作層次(這里的層次并無(wú)高低褒貶之意)。所以,我們不談目的與必要性,只談?dòng)H手實(shí)現(xiàn)模型的好處。以我的淺見(jiàn)以及親身經(jīng)歷來(lái)看,親手實(shí)現(xiàn)模型極其有助于夯實(shí)理解。
在動(dòng)手實(shí)現(xiàn)模型的過(guò)程中,你不得不把對(duì)理論的理解厘清到最細(xì)微處,這里容不得半點(diǎn)含糊。更重要的是,當(dāng)自己實(shí)現(xiàn)的模型運(yùn)轉(zhuǎn)起來(lái),應(yīng)用于實(shí)際問(wèn)題以測(cè)試其正確性時(shí),現(xiàn)實(shí)會(huì)逼迫你反復(fù)測(cè)試,這個(gè)過(guò)程可以極大地幫助你加深對(duì)于模型行為的理解。作為程序員,測(cè)試本來(lái)是一件在概念上簡(jiǎn)單明確的事情。在設(shè)計(jì)程序的時(shí)候,預(yù)測(cè)有如此這般的輸出,它就應(yīng)該有如此這般的輸出。對(duì)于一個(gè)斷言(assert)來(lái)說(shuō),它過(guò)就是過(guò),不過(guò)就是不過(guò)。但是在機(jī)器學(xué)習(xí)領(lǐng)域,這個(gè)范式就會(huì)有一定程度上的失效。
我們知道,模型(起碼本書討論的這類模型)的訓(xùn)練是一個(gè)近似迭代優(yōu)化的過(guò)程,其中到處存在隨機(jī)性:參數(shù)的隨機(jī)初始化,樣本的隨機(jī)洗牌(shuffle)以及一些例如 Drop Out 之類引入隨機(jī)性的正則化方法等,都會(huì)帶來(lái)不確定性。訓(xùn)練的結(jié)果,比如模型參數(shù)、損失和評(píng)價(jià)指標(biāo)等,都只具有統(tǒng)計(jì)意義。
更重要的是,模型在樣本集上的損失取決于問(wèn)題本身,我們不可能知道這個(gè)高維函數(shù)的真實(shí)“地形”?;谔荻鹊膬?yōu)化算法也不能保證可以找到全局最優(yōu)點(diǎn)。全局最優(yōu)點(diǎn)可能根本就不存在或者存在但不唯一。所以,模型訓(xùn)練根本沒(méi)有嚴(yán)格的正確與否一說(shuō)。
但是,模型的實(shí)現(xiàn)總有對(duì)錯(cuò)。錯(cuò)的實(shí)現(xiàn)在各個(gè)測(cè)試問(wèn)題上都不會(huì)有好的表現(xiàn)。簡(jiǎn)單來(lái)說(shuō),好的表現(xiàn)就是隨著訓(xùn)練的進(jìn)行,損失值降低而指標(biāo)上升。但是,受制于問(wèn)題本身、模型結(jié)構(gòu)以及超參數(shù),對(duì)的實(shí)現(xiàn)有時(shí)也未見(jiàn)得會(huì)有好表現(xiàn),或者好表現(xiàn)的現(xiàn)象需要很久才能顯現(xiàn)。
這迫使實(shí)現(xiàn)者必須反復(fù)在各類問(wèn)題上驗(yàn)證自己的實(shí)現(xiàn),嘗試各種模型結(jié)構(gòu)和超參數(shù)的組合,這是一個(gè)永無(wú)終點(diǎn)的過(guò)程。實(shí)現(xiàn)者對(duì)自己的實(shí)現(xiàn)的信心會(huì)隨著無(wú)數(shù)次嘗試而逐漸堅(jiān)定。更為寶貴的是,所有的這些操作和觀察都能幫助實(shí)現(xiàn)者建立起對(duì)模型行為的認(rèn)知和直覺(jué)。
我們知道,結(jié)構(gòu)和超參數(shù)控制著模型的自由度,自由度又決定了模型的偏差方差權(quán)衡,進(jìn)而影響了模型的過(guò)擬合/欠擬合。
在物理學(xué)中,一套完整的約束可將動(dòng)力系統(tǒng)的自由度降低一個(gè)整數(shù)值。由此,之后就可以用數(shù)量更少的廣義坐標(biāo)表示該系統(tǒng)。類比到模型訓(xùn)練,正則化方法施加的約束并不是完整的,模型的自由度也不是整數(shù)。狹義的正則化之外的超參數(shù),乃至模型結(jié)構(gòu),都在以復(fù)雜的方式影響著模型的自由度。我們常說(shuō)調(diào)參,就是以一種經(jīng)驗(yàn)的、半猜半試的方式控制模型自由度,以改進(jìn)模型的表現(xiàn)。當(dāng)然,我們還有網(wǎng)格搜索和隨機(jī)搜索,以及一些非參數(shù)優(yōu)化算法,如遺傳、貝葉斯等,但是它們都需要較大的計(jì)算量,使得我們?cè)诖蟛糠謺r(shí)候難以承受。
了解每一個(gè)超參數(shù)的原理和含義,以及它們對(duì)自由度的大致影響,是建模工程師的必備能力。
各種超參數(shù)在具體問(wèn)題、具體模型上究竟會(huì)以什么形式產(chǎn)生什么影響,只有經(jīng)過(guò)觀察和經(jīng)驗(yàn)的積累才能形成認(rèn)識(shí)。實(shí)現(xiàn)并驗(yàn)證模型的過(guò)程,就是一個(gè)密集經(jīng)歷這種觀察和經(jīng)驗(yàn)積累的過(guò)程。
在復(fù)雜的科學(xué)和技術(shù)領(lǐng)域,親身經(jīng)歷與體驗(yàn)是必不可少的,這是一個(gè)經(jīng)歷生命的過(guò)程。魔鬼梅菲斯特曾對(duì)拜訪浮士德博士的青年學(xué)生說(shuō):“理論是灰色的,而生命之樹(shù)長(zhǎng)青?!?/p>
5. 讀代碼的終極大招在機(jī)器學(xué)習(xí)中失效了
既然說(shuō)到了理論,這又是一個(gè)機(jī)器學(xué)習(xí)領(lǐng)域與程序員熟悉的其他領(lǐng)域不同的地方。實(shí)現(xiàn)和應(yīng)用機(jī)器學(xué)習(xí)必須要理解其原理,而閱讀其他領(lǐng)域的源代碼時(shí),只要把代碼讀透也就徹底理解了。你也許會(huì)這樣想,在完全知道內(nèi)存、總線和CPU 中發(fā)生的每一件事后,我難道還不能理解這個(gè)程序在干什么嗎?對(duì)于機(jī)器學(xué)習(xí)來(lái)說(shuō),這還真不夠。比如,你在某處看到了一個(gè)計(jì)算,但是這里為什么要計(jì)算?計(jì)算的目的是什么?為什么有效?這些可不是代碼能告訴你的。“讀代碼”原本是程序員了解一個(gè)東西的終極大招,但是在機(jī)器學(xué)習(xí)這里又失效了。
有種常見(jiàn)的說(shuō)法是把公式推導(dǎo)一遍。理解機(jī)器學(xué)習(xí)的數(shù)學(xué)原理可不能只是簡(jiǎn)單地“推導(dǎo)公式”,而應(yīng)該要理解公式究竟說(shuō)了什么。當(dāng)然,在初學(xué)時(shí)能夠把公式推導(dǎo)的每一步都弄明白就已經(jīng)不易了。但是如果把注意力都集中到推導(dǎo),又容易使人難以看清這些公式究竟表達(dá)了什么。這就好比雖然踩著腳印亦步亦趨,最后確實(shí)也走到了目的地,但始終沒(méi)有抬頭看清這是什么路,目的地是哪里,為什么走這條路,而這些才是最重要的。
人們總是希望(妄想)生活中不要有數(shù)學(xué)。實(shí)際上,所謂數(shù)學(xué)和非數(shù)學(xué),無(wú)非都是在說(shuō)事說(shuō)理而已。要想把事情說(shuō)得精確深刻,就必須把相關(guān)的量以及量之間的關(guān)系說(shuō)清楚,而數(shù)學(xué)就是簡(jiǎn)潔地表達(dá)這些關(guān)系的一種手段。
由于本書面向的是初學(xué)者,因此在數(shù)學(xué)上沒(méi)有搞得太深入、太復(fù)雜。我們會(huì)盡力闡述,以幫助讀者掌握機(jī)器學(xué)習(xí)的數(shù)學(xué)所說(shuō)的“事”是什么,也就是“推導(dǎo)公式”時(shí)容易看不清的那些東西。
本書不避諱使用公式,因?yàn)檫@是必不可少的,但量確實(shí)不大。我們把一些較為高級(jí)的主題放在了選讀框中。讀者可以根據(jù)實(shí)際需要選擇是否略過(guò)這些高級(jí)主題,而不至于干擾閱讀。記住,數(shù)學(xué)永遠(yuǎn)都是必要的。鑒于此,讀者可以參考本書的姊妹篇《深入理解神經(jīng)網(wǎng)絡(luò):從邏輯回歸到CNN》。
6. 內(nèi)容簡(jiǎn)單介紹
本書分為三個(gè)部分。第一部分是原理篇,包含第 1 章至第 3 章。其中,第 1 章介紹機(jī)器學(xué)習(xí)的基本概念,引入了一個(gè)簡(jiǎn)單的線性模型 ADALINE,這一章介紹的概念貫穿本書。第 2 章介紹計(jì)算圖,其核心內(nèi)容是計(jì)算圖的原理、梯度下降法以及計(jì)算圖上的自動(dòng)求導(dǎo)。第 3 章介紹梯度下降法的各種變體。在前三章中,我們帶領(lǐng)讀者實(shí)現(xiàn) MatrixSlow 框架的核心基礎(chǔ)設(shè)施,并在此過(guò)程中滲透講解基礎(chǔ)原理和概念。
第二部分是模型篇。有了基礎(chǔ)設(shè)施,我們就可以搭建各種模型了。本部分包括第 4 章至第 8 章。其中,第 4 章介紹邏輯回歸,第5 章介紹多層全連接神經(jīng)網(wǎng)絡(luò),第 6 章介紹幾種非全連接神經(jīng)網(wǎng)絡(luò),第 7 章介紹循環(huán)神經(jīng)網(wǎng)絡(luò),第 8 章介紹卷積神經(jīng)網(wǎng)絡(luò)。這些模型/網(wǎng)絡(luò)的選擇和順序不是任意的。我們的想法是由簡(jiǎn)到繁、由淺至深地介紹其動(dòng)機(jī)和思路的發(fā)展演變,使讀者看到這些典型的、常用的模型/網(wǎng)絡(luò)之間的聯(lián)系。雖然原則上讀者可以按照興趣選讀這些章節(jié),但是我們還是建議大家能按順序閱讀,特別是第 4 章和第 5 章。模型雖然簡(jiǎn)單,但它們是后續(xù)一切復(fù)雜延伸的基礎(chǔ)和出發(fā)點(diǎn)。
第三部分是工程篇。在這一部分中,我們將討論一些與深度學(xué)習(xí)框架相關(guān)的工程問(wèn)題。本部分包括第 9 章至第 12 章。其中,第 9 章對(duì)訓(xùn)練邏輯做進(jìn)一步封裝,并討論模型評(píng)估;第 10 章介紹模型的保存、加載、預(yù)測(cè)和服務(wù)部署;第 11 章介紹分布式訓(xùn)練,在大數(shù)據(jù)和深度學(xué)習(xí)時(shí)代,樣本量和網(wǎng)絡(luò)規(guī)模都是巨大的,這些使得分布式訓(xùn)練必不可少;第 12 章簡(jiǎn)單討論要實(shí)現(xiàn)一個(gè)專業(yè)級(jí)的深度學(xué)習(xí)框架還需面對(duì)和處理的一些問(wèn)題。
7. 大佬推薦
這是一本引人入勝的書,它通過(guò)由淺入深地講解讓你了解深度學(xué)習(xí)的原理、模型和實(shí)現(xiàn)方法,內(nèi)容清晰易懂,表達(dá)生動(dòng)形象。——邱錫鵬,復(fù)旦大學(xué)計(jì)算機(jī)學(xué)院教授
我們團(tuán)隊(duì)做了好幾年深度學(xué)習(xí)框架研發(fā),一直苦于沒(méi)有好的入門教材?,F(xiàn)在終于有一本書把深度學(xué)習(xí)框架的工作原理通俗易懂地講了出來(lái)?!?strong>袁進(jìn)輝,一流科技創(chuàng)始人兼 CEO
對(duì)于復(fù)雜難懂的概念,除非親手實(shí)現(xiàn),否則很難真正理解掌握。我非常贊同這個(gè)理念,很高興作者把這個(gè)建造與理解的過(guò)程分享出來(lái),為眾多對(duì)這個(gè)領(lǐng)域感興趣的朋友提供參考?!?strong>趙勇,格靈深瞳創(chuàng)始人兼 CEO
本書提供了框架本身和構(gòu)建各類模型的代碼,既深入核心原理,又淺顯易懂。所謂“不能創(chuàng)造,無(wú)法理解”,相信通過(guò)自己打造一個(gè)深度學(xué)習(xí)框架,讀者可以更深入地理解其中的原理?!?strong>鄧亞峰,奇虎 360 集團(tuán)副總裁、人工智能研究院院長(zhǎng)
8. 作者簡(jiǎn)介
張覺(jué)非
本科畢業(yè)于復(fù)旦大學(xué)計(jì)算機(jī)系,于中國(guó)科學(xué)院古脊椎動(dòng)物與古人類研究所取得古生物學(xué)碩士學(xué)位,目前在互聯(lián)網(wǎng)行業(yè)從事機(jī)器學(xué)習(xí)算法相關(guān)工作。
陳震
碩士畢業(yè)于北京大學(xué)?,F(xiàn)任奇虎 360 智能工程部總監(jiān)、負(fù)責(zé)人,帶領(lǐng)團(tuán)隊(duì)建設(shè)集團(tuán)的機(jī)器學(xué)習(xí)計(jì)算調(diào)度平臺(tái)、機(jī)器學(xué)習(xí)建模平臺(tái)、機(jī)器學(xué)習(xí)推理引擎以及推薦平臺(tái)等AI基礎(chǔ)設(shè)施。
9. 跟著這本書造個(gè)大輪子 ??

推 薦 閱 讀
為了鑒別世界名畫,我死磕 CNN 后終于搭建了自己的模型
圖 靈 社 群

