我們在前一篇提到了在線貝葉斯估計,在這一章中,我們講述在線貝葉斯估計體現(xiàn)出來的重要思想:要精益求精,不要步步為營。
在線貝葉斯估計與在線算法
我們在前一章中第一次提到了 在線貝葉斯估計 的概念:當證據(jù)源源不斷到來時,貝葉斯估計并不是等著所有的所有的證據(jù)來了以后才開始計算基于所有收集到的觀測的后驗概率。而是開始根據(jù)少量的證據(jù)計算一個概率,然后每次拿到每一個新觀測的時候,都用該觀測來調(diào)整之前的估計。
以開水房打水的例子而言,你進入開水房準備打開水,你想知道這個水是否開了,在這個過程中,你實際上是一步一步拿到證據(jù),并且用這些證據(jù)不斷更新你上一步的猜測的:
- 在你還未看到燒開水的機器之前,根據(jù)你過去的經(jīng)驗,你得到一個水開的先驗概率: P0=P(水開)。
- 然后,你會先觀察一下開水器的電源燈是否亮起,根據(jù)這個觀測在 P0 的基礎上提高或者調(diào)低水開的概率,得到 P1= P(水開|電源燈狀態(tài))。
- 其次,你在灌水的初始,會觀察水是否冒熱氣,并根據(jù)這個觀測在 P1 的基礎上來調(diào)整水開的概率:得到 P2= P(水開}|電源燈狀態(tài),熱氣)。
- 最后灌水之后,你會隔著杯子感受這個溫度,并將這個觀測加入到之前的證據(jù)中對P2 做更新,得到 P3= P(水開|電源燈狀態(tài),熱氣,溫度)。
這個例子中,觀測是源源不斷來的。在線貝葉斯估計使得我們不用等拿到所有可能的觀測之后再估計一個最終的后驗概率,而是可以
- 每次來一個觀測,我們都用該觀測,對前一次計算的后驗概率進行更新,得到一個新的后驗概率。
- 并且,在上一步的基礎上更新的后驗概率,和用所有觀測重新計算得到的后驗概率完全一樣。
貝葉斯的在線估計算法的核心,和很多在線算法(on-line algorithms) 相同。在線算法的核心步驟包括以下幾點:
- 在最初時刻,根據(jù)最初的一個或者幾個數(shù)據(jù)得到一個初步結(jié)果。
- 每次來一個數(shù)據(jù),用這個數(shù)據(jù)更新上一次的結(jié)果。
- 這個更新的結(jié)果,和用此時之前的所有數(shù)據(jù)得到的結(jié)果一致。
和在線算法相對的叫做離線算法(off-line algorithm)。離線算法又被稱為batch algorithm。離線算法對于新來的數(shù)據(jù),總是把它加到前面的數(shù)據(jù)重新計算得到結(jié)果。比如說一開始你有100個數(shù)據(jù),你用這一批數(shù)據(jù)得到了一個結(jié)果,當你又有了100個新的數(shù)據(jù)后,你需要把這100個和原來的100數(shù)據(jù)合并起來,用200個數(shù)據(jù)重新計算一下結(jié)果。這就是離線算法。
在線算法和離線算法的最大的不同是不需要重新計算,而是在前一次的計算的結(jié)果上進行調(diào)整:拿到新的100個數(shù)據(jù)之前,用著100個數(shù)據(jù)來更新之前計算的結(jié)果,更新的結(jié)果和用200個數(shù)據(jù)重新計算的結(jié)果一樣。因此在線算法和離線算法最大的差別不在于數(shù)據(jù)是否一個一個來,而在于是需要重新算,還是在原來的基礎上進行更新。
在線算法的例子:求均值
我們用求均值的例子來說明在線算法和離線算法的區(qū)別。假若給你100個數(shù),從x1,x2,...,x100,要求它們的均值很容易:

這種方法是拿到所有的100個x后一起計算的。這就是離線算法。
而在線算法是如何計算的呢?
- 在k=1時刻,我們拿到 x1,此時我們計算一個均值

這個均值,是基于當前的所有數(shù)據(jù)(只有一個x1)計算得到的。
- 在k=2時刻,我們拿到 x2,我們需要在上一時刻的均值的基礎之上,用新的數(shù)據(jù)x2進行調(diào)整,并且使得調(diào)整的結(jié)果和 x_1、x_2這兩個的均值相等。我們很容易找到如下形式:

- 在k=3時刻,我們拿到 x3,此時的均值也可寫成用 x3 來更新上一時刻的均值的形式:

- 以此類推,可以看出在任意k時刻,當我們拿到 xk 時,此時的均值寫成在用 xk 來更新前一時刻(k-1時刻) 的均值的形式:

也就是說,從初始估計

出發(fā),

這個就是求均值的在線算法。
相比離線算法,在線算法有三個巨大的優(yōu)勢:
- 即時反饋:不需要等到所有數(shù)據(jù)來了之后才能知道結(jié)果,任何時刻都會存在一個結(jié)果。并且這個結(jié)果,是基于迄今為止拿到的所有數(shù)據(jù)基礎之上的最優(yōu)結(jié)果。
- 計算量?。簛砹诵碌臄?shù)據(jù)后,不需要重新計算,而只需要在上一步計算的結(jié)果上進行更新即可,大大的節(jié)省了計算量。
- 存儲量?。翰恍枰鎯υ紨?shù)據(jù),每次只需要存儲上一次的結(jié)果即可,大大節(jié)省了存儲空間。
不僅如此,在線貝葉斯,乃至所有的在線算法體現(xiàn)出來的一種思想,就是精益求精:在最開始,我們并不求完美,而是先得到一個結(jié)果;我們在該結(jié)果的基礎之上,不斷的接收新的信息對原來的結(jié)果進行改進,以達到我們所追求的最優(yōu)的目標。
精益求精的例子
精益求精的這種思想,在很多領域都有非常多的體現(xiàn)。舉幾個例子。
例子1: 函數(shù)極值的數(shù)值解法
在我們高中的時候,我們就學會求一個函數(shù)的最大值或者最小值。我記得最常用的方法就是求導法。我們將函數(shù)的表達式求導數(shù),令其為0,建立一個方程。方程的解就是這個函數(shù)的極值。
例如對于函數(shù)

而言,該函數(shù)的導數(shù)為

令導數(shù)為0,即

因此 x=1 就是使得該函數(shù)有極值的自變量的值。這種方法得到的自變量的值,叫做該問題的解析解(analytical solution)。本質(zhì)就是根據(jù)公式嚴格進行一步一步地推導,最后得出最優(yōu)解的表達式。 解析解的一個問題是,很多函數(shù)的導數(shù)形式十分復雜,甚至在很多位置上不存在。因此函數(shù)極值的數(shù)值解法應運而生。
與解析解相對的,就是數(shù)值解(numerical solution)。數(shù)值解的核心思想就是精益求精。我們用下圖來解釋。圖中的藍色曲線,就是這個函數(shù)y的表達式。我們想找到這個函數(shù)最大值對應的x的位置(紅點處)。

找到數(shù)值解具體有以下幾步:
- 第一步(k=1):隨便猜一個x值。你沒看錯,就是隨便猜。假設我猜的位置為 x1,顯示在圖中。顯然這么隨便猜一個值,幾乎不可能是最優(yōu)解。不是最優(yōu)解沒關系,當我們猜到
x1 這個位置以后,我們計算一下在 x1 這個位置附近,該函數(shù)是上升的還是下降的。這個可以用函數(shù)的梯度來得到。本例子中 x1 的附近該函數(shù)是上升的。這個意味著,我們?nèi)绻龃?br> x1,我們就可以得到一個更大的y。 - 第二步(k=2): 于是,我們在 x1 的基礎上增加一點,假設達到 x2 的位置。同樣,我們看一下該函數(shù)在 x2 的附近是上升還是下降。這個例子中仍然是上升。我們還應該繼續(xù)增加 x。
- 第三步(k=3):,因此我們在 x2 的基礎上,再次增加一點,達到 x3。按照上述的方法判斷依然應該增加。
- 第四步(k=4):,我們在 x3的基礎上,再次增加一點,達到 x4,則這時候,我們發(fā)現(xiàn)函數(shù)在 x4 的周圍是下降的,這意味著我們應該往回退一點。
- 不斷重復上面的步驟,經(jīng)過多次,可能逼近最優(yōu)的紅點位置。
我們可以發(fā)現(xiàn),找到數(shù)值解的思路是并不試圖一次就找到函數(shù)最優(yōu)值的位置,而是用逐步迭代的方法不斷逼近最優(yōu)值。這就是精益求精的思想。
而我們剛才的解析解的方法,是根據(jù)公式嚴格推導。這種方法用成語步步為營來描述最為貼切。相比較于精益求精,步步為營有兩個缺點:(1)知道最后一步之前,你永遠不知道答案,哪怕是一個粗略的答案(2)一旦任何一步出了錯誤,最后的結(jié)果都是錯的。
從這一點來說,我們在初高中的最后幾道大題都是步步為營:在你推出最后結(jié)果之前,你不知道你證明對了還是錯了,并且一旦中間任何一步錯了,你都無法得到正確的結(jié)果。
例子2: 項目管理中的敏捷模型
熟悉項目管理的人,都知道項目管理有兩種不同的模型。第一個模型是瀑布模型(Waterfall model)。瀑布模型將一個系統(tǒng)的開發(fā)分成包括需求分析、設計、實現(xiàn)、發(fā)布等多個階段。每個階段都有相應的管理與控制,因此能夠比較有效的確保系統(tǒng)品質(zhì)。瀑布模型顯示在下圖中的上半部分。我們可以看出,瀑布模型中各個階段有相互銜接的固定次序,如同瀑布流水,逐級下落。

然而,用瀑布模型來進行項目的管理有2個重要的缺點:
- 不適應用戶需求的變化。因為用戶需求在最前端,一旦用戶需求發(fā)生變化,則整個開發(fā)過程全部需要從頭再來。
- 只有在項目生命周期的后期才能看到結(jié)果。
與瀑布模型相對的是敏捷模型(Agile Model)。敏捷模型顯示在上圖的下半部分。我們可以看出,在用敏捷模型來開發(fā)項目中,整個開發(fā)工作被組織為一系列短周期的快速迭代。每一次迭代都包括了需求分析、設計、實現(xiàn)與測試工作,并通過客戶的反饋來進行不斷改進,直到達到最后的要求。
和瀑布模型相比,用敏捷模型來進行開發(fā)的突出優(yōu)勢在于
- 敏捷模型的短周期迭代的思想,可以很好的適應用戶需求的變化。
- 能夠最快的得到早期用戶反饋,進而可以在沒有考慮到的情況下進行快速改進
這里說的瀑布模型和敏捷模型,同我們剛才的函數(shù)極值的解析解和數(shù)值解何其相似!瀑布模型和解析解這兩種方法,都是采用了'步步為營'的思路,而敏捷模型和數(shù)值解,就對應著`精益求精'的思路。
例子3:最簡可行產(chǎn)品
很多年前,我和同事一起去和一家私營公司的CEO談項目合作。這個公司是做國內(nèi)做高壓電線自動檢測最好的一個公司。簡單的來說,他們做了一個設備,可以用一根長的桿子捅到高壓電線上掛住,然后實時檢測輸電線路是否正常工作。一天晚飯的時候,這個CEO在和我談到他們開發(fā)的思路的時候,說了這么一段話:
像我們這樣的小公司開發(fā)產(chǎn)品,尤其是科技含量較高的產(chǎn)品,不能想著一步到位。最開始,一定要把一個不完美,但可用的產(chǎn)品搞出來。這樣我們心里就有底了。然后拿到現(xiàn)場去用,工程師在部署后會告訴我們很多設計之初沒想到的問題,用戶會給我們提供更多的要求,我們就在這些基礎上一步一步改進。別看我們現(xiàn)在這個產(chǎn)品功能看著這么漂亮,但是第一代產(chǎn)品剛出來的時候問題非常多。
這么多年,我仍然記得清清楚楚他說的這個就是不完美,但可用的產(chǎn)品的這個概念。后來我才知道,這就是大家所說的`最簡可行產(chǎn)品'(minimum viable product,簡稱 MVP)。MVP的嚴格說法,是指的有部分機能恰好可以讓設計者表達其核心設計概念的產(chǎn)品。設計者可以進行驗證式學習,根據(jù)使用者的回饋,進一步了解使用情形,并且繼續(xù)開發(fā)此產(chǎn)品。
我在香港的胡子科技學院(http://mtache.com/mvp/)的網(wǎng)頁上看到下面一個例子。
一個人想去創(chuàng)業(yè),做一個關于足球的社交平臺,可以讓人在該平臺上組隊 訂場去踢球。
他很快找到了另一個IT拍擋, 一起進行這個項目。他們非常認真,并放棄了一些其他的
工作機會,全心全意投入這項目。
他們這個團隊對該平臺要求非常高。他和開發(fā)團隊慢慢地打磨該產(chǎn)品,開發(fā)一些特別的功
能,例如要在平臺上drag & drop人到球場上組隊。這些功能開發(fā)起來都非常費時,開
發(fā)進度比預期慢。但他們認為這是必須的,因為要確保能夠推出一個`完美'的產(chǎn)品到市
場。
一年后,這個`完美'的產(chǎn)品終于完成,準備要推出市場。然而,當他們把產(chǎn)品推出到市場
后,卻發(fā)現(xiàn):沒有人用!
沒有人用的原因,可能是推廣不足,也可能是市場并沒有這個需求!最后,整個項目不了
了之。
市場的反應往往是難以預料的。尤其是初創(chuàng)企業(yè)。試想想當你投放了大量資源、金錢、時間,請了一隊團隊去開發(fā)一個 APP/平臺,推出到市場后卻發(fā)現(xiàn)沒啥人用,感覺是絕對不好受的。
解決這個'推出市場后沒有人用的問題'最好方法,就是MVP。創(chuàng)業(yè)者與其花大量資源去開發(fā)一個自以為會成功的完美產(chǎn)品,倒不如用最快的方法,建立一個只有最少、最基本功能的'半成品'。先把這個'半成品'推到市場,看看市場的反應。
有很多非常成功的初創(chuàng)企業(yè),也是遵循MVP的精神。Groupon這家市值上億美元的公司,便是MVP的一個很好例子。
創(chuàng)辦人Andrew Mason 在成立Groupon初期,與其花資源去建立一個`完美的團購系統(tǒng)',他只建立了一個簡單的WordPress博客。這個博客定時會放上一些商店優(yōu)惠的文章,而其優(yōu)惠也只是透過人手,一封一封的去電郵給參加者!后來,他發(fā)現(xiàn)這個發(fā)布商店優(yōu)惠文章的博客非常受歡迎,Andrew 因此確定這個主意有市場后,才開始組織團隊去開發(fā)這個團購系統(tǒng)。
上一個例子中的敏捷模型,其實就是先力爭推出一個MVP。推出MVP之后,開發(fā)者可以根據(jù)用戶或者使用者的回饋,進一步了解使用情形,并且持續(xù)不斷的在上一個版本的基礎上,根據(jù)實際情況進行改進。
MVP和剛才說的敏捷模型,實際上還和最近互聯(lián)網(wǎng)行業(yè)推出產(chǎn)品基本的做法小步快跑,快速迭代的思路完全一致。
小步快跑,快速迭代,就是不要想著一次性發(fā)出好的產(chǎn)品,而要通過快速迭代的方式進行更新,保證每一小步都跑得很快。在快速迭代理念支持下的產(chǎn)品研發(fā)是'上線-反饋-修改-上線' 這樣反復更新內(nèi)容的過程。再開始時,要允許不完美,但要通過快速迭代逐漸向完美逼近。每天都能發(fā)現(xiàn)修正一兩個小問題,不到一年產(chǎn)品就打磨出來了。
與之相對的,如果開始總是面面俱到的謀布局,并且在每一步盡善盡美求完美否則不肯往下走,這樣的問題就在于,你開始一旦某一個點沒考慮到或者考慮不周全,那么你只能到最后一步才會發(fā)現(xiàn)問題所在,此時重頭再來的代價和時間成本會過于昂貴。
凱文?凱利在他的暢銷書《失控》里,有過這么一段話:
由此說到機器,有一個違反直覺但卻很明確的規(guī)則:復雜的機器必定是逐步地、而且往往
是間接地完善的。別指望通過一次華麗的組裝就能完成整個功能系統(tǒng)。你必須首先制作一
個可運行的系統(tǒng),作為你真正想完成的系統(tǒng)的工作平臺。...在組裝復雜機械過程中,收益
遞增是通過多次不斷的嘗試才獲得的-也即人們常說的'成長'過程。
例子4: 用精益求精的方法來寫論文
我在香港理工大學期間,聽到過一位我非常敬佩的老師來組里給學生分享過應該如何寫學術(shù)論文。
他告訴我們,寫一篇論文有兩種方案。第一種方案,是遲遲不下筆,要等著把idea想好,仿真做好,實驗完成之后,拿到了所有的素材之后才開始寫。在寫的過程中,按照自然順序一章一章的打磨,寫完一章,再寫下一章。
第二種方案,就是稍微有了一個idea就開始寫,甚至這個idea都不需要很好。寫的過程中,不打磨語法,用最快的時間寫出一個初稿。初稿寫完以后,給周圍的人看,讓他們提意見,這時我們就會知道這個文章的idea有哪些漏洞,如何改進等等。然后不斷的進行多次`快速迭代'式的修改文章。每次修改,都完善idea,仿真、實驗,修改語法,這樣最終把文章打磨完成。
這位老師說,我們一定要用第二種方法來寫文章。
現(xiàn)在看起來,確實應該如此。如果按照第一種方案來寫文章,你可能永遠都寫不出一篇論文。原因在于,(1) 只有當你寫完以后,別人才可能給你意見,一旦你發(fā)現(xiàn)某一個意見可以采納,你可能需要重新做實驗,做仿真,又重頭來過,導致時間耗費的過長。(2) 寫文章的過程中,如果按照一章一章的仔細打磨,你可能發(fā)現(xiàn)你寫到后面的時候,因為需要修改idea或者仿真等,前面的部分很多需要重新寫,這些仔細打磨的部分就全部浪費掉了。
其實,不僅僅是寫科學論文,我覺得這種方式可以用到寫任何文章的方法。Facebook人工智能研究院智能圍棋項目的負責人,也是網(wǎng)上的著名科學段子手田淵棟,在他的知乎專欄中發(fā)表的一篇文章《碎片化時代如何讀寫》中,寫到下面的一段話:
我的經(jīng)驗是先把自己想說的零碎思路寫下來,然后反復看反復組織,才能寫出長文來。在
第一階段寫零碎思路時,往往先有個模糊的提綱(這也是寫作的第一推動力),然后無拘
無束地寫,這樣九成會離題萬里,說些自己潛意識里想說,但卻和初衷完全違背的話來。
但這完全沒有關系,只要咬住一個字“快”,十幾分鐘就有大段稿子。我有時候程序?qū)懙揭?半,突然有個想法想寫下來,那就切到另一個窗口開始打字,等榨干了自己的想法,再回
去寫程序,這樣至少可以保存思考的火種,之后可以繼續(xù)。
這樣寫出來的文章,大多是不忍卒讀兼無人可懂的。這樣就跳到第二階段。視情況一般有
兩種選擇,可以根據(jù)內(nèi)容修改主題,或者受已經(jīng)寫下的片斷啟發(fā),重新寫些與主題相關的
句子。這時候選擇切題的段落,打通全文脈絡是最重要的,能否成文取決于此,如果看到
一個有開頭結(jié)尾的完整故事,那就算局部不通順或者詳略失當,這一篇文章也是板上釘釘
有了。
這種方式,實際上就是先盡可能寫出一個MVP出來,然后再不斷迭代去改進。從這個意義上來講,最初迅速的完成一個MVP,比花很長時間完美的完成一個產(chǎn)品要重要的多,這也是印證了這句格言:
完成比完美更重要 (Done is better than perfect)。
用精益求精的方法的好處
我們在前面幾個例子中,說到了用精益求精的思想來開發(fā)產(chǎn)品、寫文章等的好處。你應該可以理解,用精益求精的思想的好處在于,可以快速后端的用戶(或者開發(fā)者本身)得到反饋,迅速完成迭代升級。
其實,從開發(fā)者是否能完成這個項目而言,用精益求精的思想來做項目,有兩個好處。
第一個好處,是安心! 在前面的'例子3:最簡可行產(chǎn)品'中,那個CEO和我說的一段話中就可以反映這一點:最開始,一定要把一個不完美,但可用的產(chǎn)品搞出來。這樣我們心里就有底了。
心里有底,這就是安心。起碼從方案上來講,這個方案是可行的。開發(fā)者需要做的,就是在這個可行的方案上進行改進而已。即便哪一點改進不成功,退回原來的版本即可,起碼這個版本可以work!相反的,如果用步步為營的方式來做項目,直到你到達最后一步之前,你都不知道這個產(chǎn)品到底能不能工作,壓力山大!一旦不能工作,你可能需要重頭再來。這就是精益求精比步步為營的好處。
第二個好處,就是多次的即時反饋。開發(fā)者用精益求精的方式改進MVP,每次改進成功,實際上都可以獲得完成時的成就感。一旦得到這個成就感,開發(fā)者又可以迫不及待地投入了下一個小目標,進一步改進當前的版本。
我在上課的時候問過我的學生一個問題,為什么一個人上自習學習的時候,堅持1個小時不到可能就得休息,而玩游戲的時候,則可以通宵呢?
原因就在于學習的反饋鏈條很長,而玩游戲可以得到即時反饋。
《游戲改變世界》一書中,揭示了人類會被游戲吸引的深層機理就是:即時反饋。游戲開發(fā)人員深諳此道。你在游戲中的任何操作,都會立馬視覺化、數(shù)據(jù)化地顯示出來。
不要小看每次砍怪物頭上飚出的數(shù)字,不要小看出招的音效,不要小看傷血的紅字和加魔的藍字,它們都給玩家提供了最最直觀的即時反饋。
你清楚的知道,你這次擊殺怪物,一定會漲經(jīng)驗值,并且有幾率會得到一些寶物。其實就是說,及時反饋使得你明確知道,你的每一次操作,都是有回報的,并且回報就在操作完成時!這就是使得我們能通宵玩游戲的原因。
對比現(xiàn)實生活中的學習卻相反。今天你費勁心力背了50個單詞,幾乎完全不能立刻看出你付出努力的成效:之前看不懂英文書還是看不懂,之前聽不懂的英文電臺還是聽不明白。你只有持之以恒的堅持很多年,才會突然有一天發(fā)現(xiàn)你的英語水平漲了。但是這個反饋鏈條未免也太長了吧。
包括英語的很多學科、乃至很多技能的學習的反饋鏈條都很長。例如小提琴和二胡。直到你付出非常長時間的枯燥的練習之后,你拉出的聲音才不至于讓人立刻想把你趕走。自己的努力不能得到即時反饋,就是很多人不能靜心下來學習的主要原因。
忍不住想起了左小祖咒唱的這個《交作業(yè)》的這首歌
憑什么要我交作業(yè)?
交了,又不一定是自己寫的!
寫了,又定不一定考!
考了,又不一定能畢業(yè)!
畢了業(yè),又不一定找到工作!
找到工作,又不一定找得到老婆!
娶了老婆,又不一定會生孩子!
生了孩子,又不一定會用功讀書!
會用功讀書,又不一定考得上!
考得上,又不一定交作業(yè)!
天哪,這個反饋鏈條如此之長,并且回報充滿了如此之多的不確定性,難怪沒有動力交作業(yè)啊。。。。
怎么破?其實核心就在于如何縮短這個反饋鏈條。例如背單詞的時候,你可以引入獎勵機制或者自我成就機制,例如每次完成50個單詞的任務,就給自己一個獎勵,或者在你的完成任務列表上重重的打一個勾!
從另外一個角度而言,我們需要訓練自己的延遲滿足的能力。延遲滿足,就是一種克服當前的困難以獲得長遠利益的能力。 通俗地說,就是堅韌(Grit)。堅韌不拔的忍耐能力,對一個人極其重要。
本章總結(jié)
我們今天的收獲是:
- 在線貝葉斯,乃至所有的在線算法體現(xiàn)出來的一種思想就是精益求精。
- 精益求精的這種思想,在包括函數(shù)極值的數(shù)值解法、項目管理中的敏捷模型、最簡可行產(chǎn)品、以及寫文章中都有體現(xiàn)。
- 精益求精,和每一步力求完美的步步為營相比,具有適應變化能力強、能及時得到外界反饋、讓開發(fā)者安心、以及給開發(fā)者創(chuàng)造即時反饋的諸多優(yōu)點。