官术网_书友最值得收藏!

2.3 梯度下降法

上面的內(nèi)容中,我們已經(jīng)構(gòu)造了兩種代價函數(shù),并且這兩種函數(shù)都是凸函數(shù),也就是都存在最小值。只要求出代價函數(shù)取最小值時的參數(shù),我們的任務(wù)也就完成了。那函數(shù)的極值又怎么求呢?非常簡單,當函數(shù)切線的斜率為0,也就是代價函數(shù)的導數(shù)為0時,也就是函數(shù)取得極值時(若自變量多于一個,導數(shù)也稱為梯度)。但這并不好求,有時因為計算量太大,有時甚至根本找不到直接求解函數(shù)極值的公式,因此我們選擇愚笨一些的方法“走一步,算一步”。

話說徒弟小飛與楊師傅已經(jīng)抓到了小白兔,休息一會兒,就準備下山了,然天氣大變,周圍突然起了很濃的霧。此時小飛大叫,“師傅不好,有妖氣!”哐當一下,小飛又被師傅一記長拳,“劣徒,休要胡鬧,天氣突變,恐有大雨,還未收衣,還不隨為師下山?!庇谑菐熗蕉司图贝掖业叵律搅?。但霧太濃密,早已分不清去路。師徒倆只能環(huán)顧四周,摸索一條下山最陡的路,然后走一段距離,再環(huán)顧四周,再往最陡的方向前進,到了傍晚,師徒倆終于回到了家中。如圖2-2所示,我們根據(jù)當前數(shù)據(jù),求出“下山”最快的方向(梯度),然后往梯度方向走一段距離,再重復相同步驟的迭代方法,就稱為梯度下降法(Gradient Descent)[8]。

圖2-2 梯度下降示意圖

梯度下降法,主要考慮兩個問題:一是方向(梯度),二是步長(學習率α)。方向決定是否走在正確的道路上,而步長決定了要走多久才能到達目的地(錯誤率最低處)。對于第一個問題,主要集中在如何才能精準地找到最小值的方向。但很遺憾,我們并沒上帝視角,因此我們只能找到當前的最佳梯度,但當前的梯度不一定是回家的路,我們卻只能前行;對于第二個問題,主要集中在如何確定合理的步長,如果步子太小,則需要很長的時間才能到達目的地,如果步子過大,可能導致在目的地周圍來回震蕩。

  • 方向(梯度)

我們首先來看梯度,求梯度其實就是求多元函數(shù)相應(yīng)變量的偏導數(shù),若參數(shù)為一個,也就是數(shù)據(jù)為一維數(shù)據(jù),那么其實就是在求復合函數(shù)的導數(shù),如果代價函數(shù)為均方誤差函數(shù)(為了計算簡潔,在代價函數(shù)中乘以0.5),如式(2.13)所示。

我們的學習器為線性回歸,并且數(shù)據(jù)為二維:f(x;w)=w1x1+w2x2,那么第一個參數(shù)w1的梯度就為式(2.14)(注意求導時的負號)。

同樣地,w2的梯度就為式(2.15)。

我們所謂的沿著梯度方向上走一步,其實就是去修改

注意:本書是去減梯度,但有些資料中為加梯度,那是在梯度中藏著負號。也可以理解為正確的修改方向是負梯度方向。

雖然上述的推導比較煩瑣,如果你能耐心看完,會發(fā)現(xiàn)其實非常簡單,然后再看看算法2.1,你會發(fā)現(xiàn)我們的關(guān)鍵算法,其實用一行代碼就可以完成。因為簡單的一行代碼,我們講了一個故事,推導了一系列的公式,雖然有些煩瑣,但這些代價都是值得的。

  • 步長(學習率α)

我們剛剛推導完了梯度,學會了如何找“下山的方向”,現(xiàn)在我們就來聊聊“下山的速度”。假如小飛是超人,一個奇怪的超人,他的步子可以任意長,但他有一個缺點,那就是比較“耿直”,只會沿著要走的方向直行。山谷那站著他喜歡的人小魚,他要去見她。他離最低處4.5m,步長為1m,當他走到第5步時就出現(xiàn)了問題,那就是他多走了0.5m,接下來他會怎么做呢?根據(jù)上面的梯度求法,小飛知道現(xiàn)在的下山方向在他的后面,那他就往后再走1米,但接下來他就尷尬了,他就像一個可愛的鐘擺一樣,不停地在小魚周圍來回震蕩,不管小飛走多久,他與小魚始終相差著0.5m,此時耿直的小飛眼角都濕潤了。你愿意幫幫他嗎?請記住,我們從上帝視角知道小飛離小魚的距離,但旁觀者清,當局者迷,小飛是不知道距離的。

聰明的你可能有很多好的想法,而我就只能想出兩個。首先就是提示小飛,“小伙子,欲速則不達,慢一點吧!”,于是小飛就減小了步長,一次走0.4m,那小飛離小魚最近的距離也就縮短到0.1m。而嘗到甜頭的小飛就把自己的步長縮小到了0.04m,那他最終離最低點也就更近了。但這里就出現(xiàn)了一個問題,減小步長確實會離成功更近,但時間的代價,也會讓小飛心碎。

考慮到剛才的情況,我又有了一個不錯的想法。開始時就勇敢地大步往前邁,走到一定步數(shù)后就縮小步長。在實際的應(yīng)用中,步長(學習率α)的選擇是一個很有技巧性的活,具體情況還要具體分析??傮w情況就是α過大,代價函數(shù)就會在最低值附近較大震蕩,而α較小代價函數(shù)的震蕩也會較小,但到達震蕩區(qū)間的時間也會變長,這也是一個魚與熊掌的問題。

2.3.1 批量梯度下降法

批量梯度下降(Batch Gradient Descent,BGD)[9]又稱最速梯度下降,使用“批量”一詞可能會產(chǎn)生歧義,“批量”一詞應(yīng)該是“一批一批處理”的意思,如管道和緩沖器一般,但這里的“批量”其實指的是“全部一起處理”的意思。我們要處理什么呢?我們要處理的其實是數(shù)據(jù),前文中說到我們要找“下降最快的方向”,因此就進行了求導,但其實我們只是找到了下降的方向,還沒找到下降最快的方向。如算法2.2所示,才是下降最快的方向,不知道你喜不喜歡玩“大家來找茬”游戲,我們現(xiàn)在就找找算法2.1與算法2.2的茬吧!

可以發(fā)現(xiàn),我們把算法2.1中的m換成了算法2.2中的N,那N是什么呢?N表示的是數(shù)據(jù)個數(shù),我們計算一次梯度時,需要計算完所有數(shù)據(jù)中的誤差梯度,然后累加之后再取平均值,這就是我們要找的最速下降梯度,也就是我們上文提到的一個信息“環(huán)顧四周”。

事物具有兩面性,最速梯度下降也具有,優(yōu)點是準確,我們找到了最正確的方向;缺點就是慢,每計算一次梯度都要遍歷所有數(shù)據(jù),考慮到如今的大數(shù)據(jù)時代,這就成了巨大的困難。

2.3.2 隨機梯度下降法

隨機梯度下降(Stochastic Gradient Descent,SGD)[10]是批量梯度下降的一個極端版本,如算法2.3所示,是隨機梯度下降的算法描述。

算法優(yōu)點很明顯,那就是快,只要見到一條數(shù)據(jù),就計算其梯度,然后調(diào)整參數(shù)w。也許你會說缺點也很明顯,那就是不可靠。但其真的“不可靠”嗎?

我們先來聊聊SGD算法的優(yōu)點。使用SGD算法,最大的好處就是我們不需要考慮數(shù)據(jù)集的尺寸,我們看見一條數(shù)據(jù)就修改一次參數(shù)。很自然地,我們的學習器就可以邊學習邊工作,也就是現(xiàn)在流行的在線學習(Online learning)[11]模式,更為重要的是社會是在發(fā)展變化的,同時數(shù)據(jù)也在不停地更新,就像3年前流行的穿衣風格,3年后就可能徹底變了,而我們使用3年前最流行的穿衣風格數(shù)據(jù)來預(yù)測當前的穿衣風格,這就落伍了。

我們現(xiàn)在來談?wù)凷GD算法的“不可靠”,誠然,隨機梯度下降使用的梯度是帶有噪聲的梯度,我們的下降方向也總是曲折的,但在這種曲折中,我們還是跌跌撞撞地游到了最小值附近,然后就在最小值周圍震蕩。雖然我們沒有得到最優(yōu)解,但我們至少得到了一個不錯的解。并且在深度學習中,我們恰恰會避開最優(yōu)解,而選擇一個還不錯的解,這其中有兩個重要的原因。

其一就是我們的數(shù)據(jù)本身就不可靠,數(shù)據(jù)是帶有噪聲的,產(chǎn)生數(shù)據(jù)噪聲的原因有很多,有人為造成的,也有天然的,噪聲是不可避免的。為了解決這一問題,一個簡單而又重要的想法呼之欲出,就是我們在噪聲中學習。之前我們提到降噪任務(wù)就是在數(shù)據(jù)中加入噪聲學習的一種學習方式,而隨機梯度下降也可以認為是在梯度中加入噪聲學習,這樣訓練出來的學習器就可能擁有更強的抗噪能力。

其二就是我們不要學得“太好”,這可能有點難以理解。在深度學習中,由于我們模型能力很強大,因此很容易就在已知數(shù)據(jù)中學得很“完美”,但在未知數(shù)據(jù)中就會表現(xiàn)得水土不服。深度學習中一個重要的方法就是使用早停(Early Stopping)[12],也就是學到一定程度就終止了學習,這種方式?jīng)]有在已知數(shù)據(jù)中表現(xiàn)得“完美”,反而在未知數(shù)據(jù)中表現(xiàn)得還不錯。而隨機梯度下降也沒有在數(shù)據(jù)中學得“完美”,而在未知數(shù)據(jù)中,往往表現(xiàn)還不錯。

當然如果噪聲太大,我們也無法學習。取批量梯度下降與隨機梯度下降的一個折中,如最早的算法2.1所示,我們稱之為最小批量梯度下降(Mini-Batch Gradient Descent)[9]。假如全部數(shù)據(jù)有一百條,那我們可以隨機選擇10條數(shù)據(jù)求出其梯度誤差,然后累加之后再取平均值。但如何選擇最小批量的大小,也是需要在實際應(yīng)用中根據(jù)實際情況進行選擇的。

主站蜘蛛池模板: 万州区| 本溪| 唐山市| 定日县| 屏边| 宜兰市| 阿巴嘎旗| 锡林郭勒盟| 枣庄市| 龙口市| 搜索| 诸暨市| 清流县| 河西区| 富蕴县| 彭州市| 淄博市| 静安区| 新晃| 永安市| 班玛县| 常德市| 邯郸县| 龙山县| 潞城市| 奉新县| 承德市| 深圳市| 曲沃县| 萨嘎县| 深州市| 获嘉县| 巴南区| 尖扎县| 成安县| 怀集县| 潼关县| 孝义市| 临汾市| 北票市| 任丘市|