閱讀525 返回首頁    go 技術社區[雲棲]


山重水複疑無路,最快下降問梯度(深度學習入門係列之七)

更多深度文章,請關注:https://yq.aliyun.com/cloud


係列文章:

一入侯門“深”似海,深度學習深幾許(深度學習入門係列之一)
人工“碳”索意猶盡,智能“矽”來未可知(深度學習入門係列之二)
神經網絡不勝語,M-P模型似可尋(深度學習入門係列之三)
“機器學習”三重門,“中庸之道”趨若人(深度學習入門係列之四)
Hello World感知機,懂你我心才安息 (深度學習入門係列之五)
損失函數減肥用,神經網絡調權重(深度學習入門係列之六)


一年多前,吳軍博士寫了一本暢銷書《智能時代》[1]。書裏提到,在人工智能領域,有一個流派叫“鳥飛派”,亦稱之為“模仿派”。說的是,當人們要學習飛翔的時候,最先想到的是模仿鳥一樣去飛翔。
很多年前,印度詩人泰戈爾出了本《飛鳥集》,裏麵有個名句:“天空沒有留下翅膀的痕跡,但我已經飛過”。有人對此解讀為,“人世間,很多事情雖然做過了,卻不為人所知,但那又如何?重要的是,我已做過,並從中獲得了許多。”
兩千多年前,司馬遷在《史記•滑稽列傳》寫到:“此鳥不飛則已,一飛衝天;不鳴則已,一鳴驚人。”。說的是當年楚莊王在“勢不眷我”時,選擇了“蟄伏”。蟄伏,隻是一個儲勢過程,遲早有一天,蓄勢待發,“發”則達天。
這三者的情感交集,讓我聯想到出了本章的主人公傑弗裏•辛頓(Geoffrey Hinton)教授,在學術界裏,他就是這樣的一個“勵誌”人物!
1986年,辛頓教授和他的小夥伴們重新設計了BP算法,以“人工神經網絡”模仿大腦工作機理,“吻”醒了沉睡多年的“人工智能”公主,一時風光無限。
但“好花不常開,好景不常在”。當風光不再時,辛頓和他的研究方向,逐漸被世人所淡忘。
這被“淡忘”的冷板凳一坐,就是30年。
但在這30年裏,辛頓又如“飛鳥”一般,即使“飛過無痕”,也從不放棄。從哪裏跌到,就從哪裏爬起。實在不行,即使換個馬甲,也要重過一生。
玉汝於成,功不唐捐。
終於,在2006年,辛頓等人提出了“深度信念網(Deep Belief Nets,DBN)”(這實際上就是多層神經網絡的馬甲)[2]。這個“深度信念網”後期被稱為“深度學習”。終於,辛頓再次閃耀於人工智能世界,隨後被封為“深度學習教父”。
但細心的讀者可發現,即使辛頓等人提出了“深度信念網”,在隨後的小10年裏,這個概念亦是不溫不火地發展著(如圖1所示)。直到後期(2012年以後),隨著大數據和大計算(GPU、雲計算等)的興起,深度學習才開始大行其道,一時間甚囂塵上。

473387ba332c29a061579c612ecdcabd36b2d99a
圖7-1 深度學習的穀歌趨勢圖

回顧起傑弗裏•辛頓過往40多年的學術生涯,可謂是顧跌宕起伏,但最終修得正果。但倘若細細說起,這“牛逼”,還得從1986年吹起。

7.1 1986年的那篇神作

1986年10月,傑弗裏•辛頓還在卡內基梅隆大學任職。他和在加州大學聖迭戈分校的認知心理學家大衛·魯梅爾哈特(David Rumelhart)等人,在著名學術期刊《自然》上聯合發表題為:“通過反向傳播算法的學習表征(Learning Representations by Back-propagating errors)”的論文[3]。該文首次係統簡潔地闡述反向傳播算法(BP)在神經網絡模型上的應用,該算法把網絡權值糾錯的運算量,從原來的與神經元數目的平方成正比,下降到隻和神經元數目本身成正比。
與此同時,當時的大背景是,在八十年代末,Intel x86係列的微處理器和內存技術的發展,讓計算機的運行速度和數據訪存速度也比二十年前高了幾個數量級。這一下(運算量下降)一上(計算速度上升),加之多層神經網絡可通過設置隱含層 (hidden layer),極大增強了數據特征的表征能力,從而輕易解決感知機無法實現的異或門 (XOR gate)難題,這些“天時地利人和”的大好環境,極大緩解了當年明斯基對神經網絡的責難。
於是,人工神經網絡的研究,漸漸得以複蘇。

26fbe65f390940904aca829eb23e43377a97fca6
圖7-2 1986年傑弗裏•辛頓的那篇神作

值得一提的是,在文獻[3]中,傑弗裏•辛頓並不是第一作者,魯梅爾哈特才是,而辛頓僅僅“屈居”第二(如圖7-2所示)。但為什麼我們提起BP算法時,總是說起辛頓呢?其實原因也很簡單,主要有二:第一、魯梅爾哈特畢竟並非計算機科學領域之內的人士,我們計算機科學家,總不能找一個腦科學家去“拜碼頭”吧;第二、辛頓是這篇論文的通信作者,通常而言,通信作者才是論文思路的核心提供者,這樣一來,即使作者排名第二,也沒有埋沒掉辛頓教授的貢獻。
同在1986年,魯梅爾哈特也和自己的小夥伴們合作發表了一篇題為“並行分布式處理:來自認知微結構的探索”的論文[4]。僅僅從論文題目的前半部分來看,我們很可能誤解這是一個有關“高性能計算”的文章,但從標題的後半部分可以得知,這是魯梅爾哈特等人對人類大腦研究的最新認知。魯梅爾哈特對大腦工作機理的深入觀察,極大地啟發了辛頓。辛頓靈光一現,覺得可以把這個想法遷移到“人工神經網絡”當中。於是,就有了他們神來一筆的合作。
我們知道,1986年,辛頓和魯梅爾哈特能在大名鼎鼎的《自然》期刊上發表論文,自然不是泛泛而談,它一定是解決了什麼大問題。下麵我們就聊聊這個話題。

7.2 多層感知機網絡遇到的大問題

由於曆史的慣性,在第六講中提到的多層前饋網絡,有時也被稱為多層感知機(Multilayer Perceptron,MLP)。但這個提法導致概念多少有些混淆。這是因為,在多層前饋網絡中,神經元的內部構造已悄然發生變化,即激活函數從簡單粗暴的“階躍函數”變成了比較平滑的擠壓函數Sigmoid(如圖7-3所示)。
激活函數為什麼要換成Sigmoid呢?其實原因並不複雜,這是因為感知機的激活函數是階躍函數,不利於函數求導,進而求損失函數的極小值。我們知道,當分類對象是線性可分,且學習率(learning rate)η足夠小時,由感知機還不堪勝任,由其構建的網絡,還可以訓練達到收斂。但分類對象不是線性可分時,感知機就有點“黔驢技窮”了。因此,通常感知機並不能推廣到一般前饋網絡中。

695665b6fab2907e89e0f5ea550082b212818350
圖 7-3 變更激活函數的前饋多層神經網絡

按照我們前麵章節的說法,所謂的機器學習,簡單來說,就是找到一個好用的函數(function),從而較好地實現某個特定的功能(function)。一言蔽之,函數就是功能。而對於某個特定的前饋神經網絡,給定網絡參數(連接權值與閾值),其實就是定義了一個具備數據采集(輸入層)、加工處理(隱含層),然後輸出結果(輸出層)的函數。
如果僅僅給定一個網絡結構,其實它定義的是一個函數集合。因為不同的網絡參數(連接權值與閾值),實現的功能“大相徑庭”。功能不同,自然函數也是不同的!
針對前饋神經網絡,我們需要實現的目的很簡單,就是想讓損失函數達到最小值,因為隻有這樣,實際輸出和預期輸出的差值才最小。那麼,如何從眾多網絡參數(神經元之間的鏈接權值和閾值)中選擇最佳的參數呢?
最簡單粗暴的方法,當然就是枚舉所有可能值了!

1d55debae62787470e13eaa4765e83e32924e177
圖7-4 暴力調參不可取

但這中暴力策略,對稍微複雜一點的網絡就不可取了!例如,用於語音識別的神經網絡,假設網絡結構有7層,每一層有1000個神經元,那麼僅一層之間的全連接權值,就達到1000×1000=106個,一旦層次多了,那權值數量就海了去了!(如圖7-4所示)。故此,這種暴力調參找最優參數,既不優雅,也不高效,故實不可取!

7.3到底什麼是梯度?

為了克服多層感知機存在的問題,人們設計了一種名為delta()法則(delta rule)的啟發式方法,該方法可以讓目標收斂到最佳解的近似值[5]。
delta法則的核心思想在於,使用梯度下降(gradient descent)的方法找極值。具體說來,就是在假設空間中搜索可能的權值向量,並以“最佳”的姿態,來擬合訓練集合中的樣本。那麼,何謂最佳擬合呢?當然就是讓前文提到的損失函數達到最小值!
我們知道,求某個函數的極值,難免就要用到“導數”等概念。既然我們把這個係列文章定位為入門層次,那不妨就再講細致一點。什麼是導數呢?所謂導數,就是用來分析函數“變化率”的一種度量。針對函數中的某個特定點x0,該點的導數就是x0點的“瞬間斜率”,也即切線斜率,見公式(7.1)。
$$
[f'({x_0}) = \mathop {\lim }\limits_{\Delta x \to 0} \frac{{\Delta y}}{{\Delta x}} = \mathop {\lim }\limits_{\Delta x \to 0} \frac{{f({x_0} + \Delta x) - f({x_0})}}{{\Delta x}}]\tag{7.1}
$$

如果這個斜率越大,就表明其上升趨勢越強勁。當這個斜率為0時,就達到了這個函數的“強弩之末”,即達到了極值點。而前文提到的損失函數,如果要達到損失最小,就難免用到導數“反向指導”如何快速抵達極小值。
在單變量的實值函數中,梯度就可以簡單地理解為隻是導數,或者說對於一個線性函數而言,梯度就是線的斜率。但對於多維變量的函數,它的梯度概念就不那麼容易理解了。下麵我們來談談這個概念。
在向量微積分中,標量場的梯度其實是一個向量場(vector filled)。對於特定函數的某個特定點,它的梯度就表示從該點出發,該函數值增長最為迅勐的方向(direction of greatest increase of a function)[6]。假設一個標量函數f的梯度記為:\(f\)或\(grad f\),這裏的表示向量微分算子。那麼,在一個三維直角坐標係,該函數的梯度就可以表示為公式(7.2):
$$
\nabla f = \left( {\frac{{\partial f}}{{\partial x}},\frac{{\partial f}}{{\partial y}},\frac{{\partial f}}{{\partial z}}} \right)\tag{7.2}
$$
求這個梯度值,難免要用到“偏導”的概念。說到“偏導”,這裏順便“輕拍”一下國內的翻譯。“偏導”的英文本意是“partial derivatives(局部導數)”,書本上常翻譯為“偏導”,可能會把讀者的思路引導“偏”了。
那什麼是“局部導數”呢?對於多維變量函數而言,當求某個變量的導數(相比於全部變量,這裏隻求一個變量,即為“局部”),就是把其它變量視為常量,然後整個函數求其導數。之後,這個過程對每個變量都“臨幸”一遍,放在向量場中,就得到了這個函數的梯度了。舉例來說,對於3變量函數\(f = {x^2} + 3xy + {y^2} + {z^3}\),它的梯度可以這樣求得:
(1) 把y,z視為常量,得x的“局部導數”:
$$
\frac{{\partial f}}{{\partial x}} = 2x + 3y
$$
(2) 然後把x,z視為常量,得y的“局部導數”:
$$
\frac{{\partial f}}{{\partial y}} = 3x + 2y
$$
(3) 最後把x,y視為常量,得z的“局部導數”:
$$
\frac{{\partial f}}{{\partial y}} = 3{z^2}
$$
於是,函數f的梯度可表示為:
$$
[\nabla f = grad(f) = \left( {2x + 3y,3x + 2y,3{z^2}} \right)]
$$
針對某個特定點,如點A(1, 2, 3),帶入對應的值即可得到改點的梯度:

4f75e940f1420ede59209bae2510630c59f0b30c

這時,梯度可理解為,站在向量點A(1, 2, 3),如果想讓函數f的值增長得最快,那麼它的下一個前進的方向,就是朝著向量點B(8,7,27)方向進發(如圖7-3所示)。很顯然,梯度最明顯的應用,就是快速找到多維變量函數的極(大/小)值。

fa7173766658813327198183bf5e53a187b84847
圖7-5 梯度概念的示意圖

在這裏需要說明的是,我們用“局部導數”的翻譯,僅僅是用來加深大家對“偏導”的理解,並不是想糾正大家已經約定俗成的叫法。所以為了簡單起見,在後文我們還是將“局部導數”稱唿為“偏導”。

7.4 到底什麼是梯度下降?

上麵我們提到了梯度的概念,下麵我們說說在求損失函數極小值過程中,常常提到的“梯度遞減”的概念。
我們先給出一個形象的案例。爬過山的人,可能會有這樣的體會,爬坡愈平緩(相當於斜率較小),抵達山峰(函數峰值)的過程就越緩慢,而如果不考慮爬山的重力阻力(對於計算機而言不存在這樣的阻力),山坡越陡峭(相當於斜率越大),順著這樣的山坡爬山,就越能快速抵達山峰(對於函數而言,就是愈加快速收斂到極值點)。

65e84b866c08b4c43ccdc900bb9f7a458acd3d2e
圖7-6 梯度遞減求極小值

如果我們把山峰“乾坤大挪移”,把爬山峰變成找穀底(即求極小值),這時找斜率最陡峭的坡而攀爬山峰的方法,並沒有本質變化,不過是方向相反而已。如果把登山過程中求某點的斜率稱為“梯度(gradient)”,而找穀底的方法,就可以把它稱之為“梯度遞減(gradient descent)”,示意圖如圖7-6所示。
依據“梯度遞減”作為指導,走一步,算一步,一直遵循“最陡峭”的方向,探索著前進,這個過程,是不是有點像鄧公的名句“摸著石頭過河”?
這個“梯度遞減”體現出來的指導意義,就是“機器學習”中的“學習”內涵,即使在大名鼎鼎的“AlphaGo”中,“學習”這是這麼玩的!你是不是有點失望?這機器學習也太不高大上了!
但別忘了,在第一講中,我們就已經講到“學習”的本質,在於性能的提升。利用“梯度遞減”的方法,的確在很大程度上,提升了機器的性能,所以,它就是“學習”!
當然,從圖7-3中,我們也很容易看到“梯度遞減”的問題所在,那就是它很容易收斂到局部最小值。正如攀登高峰,我們會感歎“一山還比一山高”,探尋穀底時,我們也可能發現,“一穀還比一穀低”。但是“隻緣身在此山中”,當前的眼界讓我們像“螞蟻尋路”一樣,很難讓我們有全局觀,因為我們都沒有“上帝視角”。

7.5 重溫神經網絡的損失函數

針對前饋神經網絡的設計,輸入和輸出層設計比較直觀。比如說,假如我們嚐試判斷一張手寫數字圖片上麵是否寫著數字“2”。很自然地,我們可以把圖片像素的灰度值作為網絡的輸入。如果圖片的維度是16×16,那麼我們輸入層神經元就可以設計為256個(也就是說,輸入層是一個包括256個灰度值向量),每個神經元接受的輸入值,就是規格化的灰度值。
而輸出層的設計也很簡單,就是需要包含10神經元,輸出是數字“0~9”的分類概率(也就是說,輸出層是一個包括10個概率值的向量)。擇其大者而判之,如圖7-7所示,如果判定為“2”的概率(比如說80%)遠遠大於其他數字,那麼整個神經網絡的最終判定,就是手寫圖片中的數字是“2”,而非其它數字。

c2cc9974f1c0869eca1298d03e2386257e2e737f
圖7-8 識別手寫數字的神經網絡

相比於神經網絡輸入、輸出層設計的簡單直觀,它的隱含層設計,可就沒有那麼簡單了。說好聽點,它是一門藝術,依賴於“工匠”的打磨。說不好聽點,它就是一個體力活,需要不斷地“試錯”。
但通過不斷地“折騰”,研究人員還真是掌握了一些針對隱層的啟發式設計規則(如下文即將提到的BP算法),以此降低訓練網絡所花的開銷,並盡量提升網絡的性能。
那麼,怎樣才算是提升神經網絡性能呢?這就需要用到前麵我們前麵提到的損失函數了。在第六章我們提到,所謂“損失函數”,就是一個刻畫實際輸出值和期望輸出值之間“落差”的函數。
為了達到理想狀態,我們當然希望這種“落差”最小,也就是說,我們希望快速配置好網絡參數,從而讓這個損失函數達到極小值。這時,神經網絡的性能也就接近最優!
關於求損失函數極小值,台灣大學李弘毅博士給出了一個通俗易懂的例子,下麵我們來說說。對於識別手寫數字的神經網絡,訓練數據都是一些“0,1 2, …, 9”等數字圖像,如圖7-8所示。

圖7-8 識別手寫數字的神經網絡
由於人們手寫數字的風格不同,圖像的殘缺程度不同,輸出的結果有時並不能“十全十美”,於是我們就用損失函數來衡量二者的誤差。前麵我們提到,常用的損失函數是:
(7.3)
機器學習的任務,在很大程度上,找一個模型,擬合(fitting)或者說“適配”給定的訓練數據,然後再用這個模型預測新數據。這個模型的表現形式,具體說來,就是設計一個好用的函數,用以揭示這些訓練樣本隨自變量的變化關係。揭示擬合好壞的程度,就要用到損失函數。“損失”越小,說明擬合的效果就越好。

7f600f55091d803f5cca41d9b59c9cd814a86bc6
圖7-9 用梯度遞減,更新網絡權值

在我們訓練神經網絡時,損失函數說白了,就是有關“權值參數”的函數。為了求損失函數的極小值,就不可避免地需要計算損失函數中每一個權值參數的偏導數,這時前文中提到的“梯度遞減”方法就派上用場了。訓練線性單元的梯度遞減算法示意圖如圖7-9所示,圖中的參數η就是“學習率”,它決定了梯度遞減搜索的步長,這個步長“過猶不及”。如果值太小,則收斂慢,如果值太大,則容易越過極值,導致網絡震蕩,難以收斂。
圖7-9僅僅給出一個權值變量wi的梯度示意圖,而實際上,神經網絡中的參數是非常多的,因此針對損失函數L的權值向量的梯度可以記作:
(7.4)
在這裏,本身就是一個向量,它的多個維度分別由損失函數L對多個權值參數wi求偏導所得。當梯度被解釋為權值空間的一個向量時,它就確定了L對陡峭上升的方向。
如果需要根據圖7-9所示的公式來更新權值,我們需要一個更加實用的辦法,在每一步重複計算。幸運的是,這個過程並不複雜,通過簡易的數學推導,我們可以得到每個權值分量wi更加簡明的計算公式:
(7.5)
其中,xid表示訓練集合第d個樣例的輸入分量xi,yd表示第d樣例的期望輸出值,yd’表示第d樣例的實際輸出值,這二者的差值就是“損失(loss)”,也稱之為誤差(error)。有了公式(7.5)做支撐,圖7-9所示的算法就可行之有“章法”了。
有了前麵的知識鋪墊,我們終於可以在下一章談談誤差反向傳播(Back Propagation,BP)算法了。

7.6 小結

在本章中,我們主要講解了梯度的概念。所謂梯度,就是該函數值增長最為迅勐的方向,然後我們介紹了梯度下降法則。
在下一章中,我們將用最為通俗易懂的圖文並茂的方式,給你詳細解釋反向傳播(BP)算法。BP算法不僅僅是作為經典,留在我們的記憶裏,而且,它還“曆久彌新”活在當下。要知道,深度信念網(也就是深度學習)之所以性能奇佳,不僅僅是因為它有一個“無監督”的逐層預訓練(unsupervised layer-wise training),除此之外,預訓練之後的“微調(fine-tuning)”,還是需要“有監督”BP算法作為支撐。
由此可見,BP算法影響之深,以至於“深度學習”都離不開它!
“世上沒有白走的路,每一步都算數”。希望你能持續關注。

7.7 請你思考

通過本章的學習,請你思考如下問題:
(1)在前饋神經網絡中,隱含層設計多少層、每一層有多少神經元比較合適呢?我們可以設定一種自動確定網絡結構的方法嗎?
(2)神經網絡具有強大的特征表征能力,但“成也蕭何,敗也蕭何”,BP算法常常遭遇“過擬合(overfitting)”,它可能會把噪音當做有效信號,你知道有什麼策略來避免過擬合嗎?

【參考文獻】

[1] 吳軍. 智能時代. 中信出版集團. 2016.8
[2] Hinton G E, Osindero S, Teh Y W. A fast learning algorithm for deep belief nets[J]. Neural computation, 2006, 18(7): 1527-1554.
[3] Williams D, Hinton G. Learning representations by back-propagating errors[J]. Nature, 1986, 323(6088): 533-538.
[4] Rumelhart D E, McClelland J L, PDP Research Group. Parallel Distributed Processing, Volume 1 Explorations in the Microstructure of Cognition: Foundations[J]. 1986.
[5] Tom Mitchell著.曾華軍等譯. 機器學習. 機器工業出版社. 2007.4
[6] Better Explained. Vector Calculus: Understanding the Gradient

文章作者:張玉宏,著有《品味大數據》一書。審校:我是主題曲哥哥。

(未完待續)

最後更新:2017-06-19 08:45:34

  上一篇:go  永久免費OA辦公係統的功能模塊介紹(一)
  下一篇:go  如何打造支撐百萬用戶的分布式代碼托管平台