【導(dǎo)讀】在深度學(xué)習(xí)任務(wù)中,我們常常會(huì)為模型定義一個(gè)損失函數(shù),損失函數(shù)表征的是預(yù)測值和實(shí)際值之間的差距,再通過一定的優(yōu)化算法減小這個(gè)差距然后絕大多數(shù)情況下,我們的損失函數(shù)十分復(fù)雜,不像我們解數(shù)學(xué)題能得到一個(gè)確定,唯一的解析解。而是通過數(shù)學(xué)的方法去逼近一個(gè)解,也稱數(shù)值解。局部最小值和全局最小值 假設(shè)我們的損失函數(shù)是 import matplotlib.pyplot as plt 我只畫出了區(qū)間(-2, 2)的函數(shù)圖像,通過觀察圖像,我們發(fā)現(xiàn)該函數(shù)有兩個(gè)波谷,分別是局部最小值和全局最小值。 到達(dá)局部最小值的時(shí)候,由損失函數(shù)求得的梯度接近于0,我們很難再跳出這個(gè)局部最小值,進(jìn)而優(yōu)化到全局最小值,即x=1處,這也是損失函數(shù)其中的挑戰(zhàn) 鞍 點(diǎn) 假設(shè)我們的損失函數(shù)為 文章所標(biāo)的點(diǎn),即是鞍點(diǎn)(saddle point),形狀像馬鞍處。 它的特點(diǎn)也是兩邊的梯度趨近于0,但并不是真正的最小值點(diǎn) 在深度學(xué)習(xí)優(yōu)化過程中,這兩種情況很常見,我們需要盡可能地通過數(shù)學(xué)方式去逼近最優(yōu) 梯度下降為什么有效 這里需要用到高數(shù)里面的泰勒展開公式 由于ε是個(gè)極小值,所以我們可以用梯度乘上一個(gè)很小的數(shù),去替代 <section role="presentation" data-formula="f(x-n*f(x)’) = f(x)-n*f(x)" ^2'="" data-formula-type="block-equation">由于梯度的平方是恒大于0的,因此有 < f(x)'="" data-formula-type='block-equation'>看到這里大家應(yīng)該就明白了,其中n代表的是超參數(shù)學(xué)習(xí)率,我們通過讓x減去一個(gè)常數(shù)乘以學(xué)習(xí)率,使得目標(biāo)損失函數(shù)值得到下降 接下來我會(huì)以函數(shù) 作為一個(gè)梯度下降例子 以下是我的畫圖代碼
函數(shù)從x=0.5開始,很順利的優(yōu)化到了全局最小值的地方 那么我們換到x = -1.0,并增加迭代步伐,再次觀察梯度下降情況 我們將迭代步伐調(diào)至20,可見我們卡在局部最小值,無法跳出 那么我們?cè)囋囋龃髮W(xué)習(xí)率,看能不能跳出來 我將eta設(shè)置為1.000542(PS:這個(gè)函數(shù)太刁鉆了,調(diào)了半天學(xué)習(xí)率才達(dá)到想要的結(jié)果) 可以看見再經(jīng)歷過一系列震蕩后,我們的函數(shù)成功到達(dá)了全局最小值點(diǎn),當(dāng)然背后是我找這個(gè)參數(shù)的心酸。 我們?cè)侔褜W(xué)習(xí)率參數(shù)調(diào)大一點(diǎn)點(diǎn),將eta設(shè)置為1.0055 這里我們也可以看得出學(xué)習(xí)率的關(guān)系 當(dāng)學(xué)習(xí)率很小,我們下降較為平滑,但容易卡在局部最小值點(diǎn) 當(dāng)學(xué)習(xí)率很大,我們梯度優(yōu)化過程中會(huì)十分劇烈,可能達(dá)到全局最小值點(diǎn),但也很可能距離優(yōu)化目標(biāo)越來越遠(yuǎn) 隨機(jī)梯度下降SGD 假設(shè)我們有n個(gè)樣本數(shù)據(jù),那么每次進(jìn)行梯度下降,我們需要分別對(duì)每個(gè)數(shù)據(jù)計(jì)算其梯度。 時(shí)間復(fù)雜度為O(n),當(dāng)樣本很多的時(shí)候,這個(gè)計(jì)算開銷是非常大的。 隨機(jī)梯度下降則是在梯度下降每次迭代當(dāng)中,隨機(jī)采取一個(gè)樣本,計(jì)算其梯度,作為整體梯度進(jìn)行下降,我們的計(jì)算開銷也就下降到了O(1) 為了梯度值更穩(wěn)定,我們也可以選擇小批量隨機(jī)梯度下降,以一小批樣本的梯度作為整體的梯度估計(jì) 動(dòng)量法Momentum 我們實(shí)際優(yōu)化的函數(shù)會(huì)十分復(fù)雜,最常見的函數(shù)是多維的情況。當(dāng)函數(shù)在某個(gè)方向上變化十分劇烈,則對(duì)應(yīng)方向上的梯度變化也十分劇烈,為了達(dá)到收斂,需要更多時(shí)間步迭代。 梯度變化劇烈的另外一個(gè)原因是,我們單一地考慮了當(dāng)前的梯度,而忽略了以前的梯度情況。 當(dāng)我們把以前的梯度加入到當(dāng)前梯度計(jì)算中,會(huì)緩解這種問題,加速收斂 動(dòng)量法引入了一個(gè)速度變量,初始化為0,由以下兩個(gè)公式進(jìn)行變量維護(hù) 指數(shù)移動(dòng)平均 這里參考的是mxnet出品的動(dòng)手學(xué)教程 我們假設(shè)有下面公式 繼續(xù)展開得到 令 則 這里直接是變量替換而我們由高數(shù)的常見的極限公式可得 而,則 舉個(gè)例子,取,則根據(jù)前面的極限公式 如果我們把0.37看作是個(gè)很小的數(shù),那我們可以忽略了更高階的系數(shù),比如等等 換句話說,當(dāng),我們只關(guān)注近十個(gè)階數(shù)的系數(shù) 簡單來說,指數(shù)移動(dòng)平均就是計(jì)算近幾個(gè)時(shí)間步的加權(quán)平均,時(shí)間越近,對(duì)應(yīng)的權(quán)重就越大 接下來我們對(duì)動(dòng)量法的速度變量進(jìn)行變形 我們相當(dāng)于是對(duì) 這一項(xiàng)做了移動(dòng)平均。因此動(dòng)量法能綜合考慮一定量時(shí)間步內(nèi)的梯度情況 AdaGrad算法 在前面兩種優(yōu)化算法里,自變量的每一個(gè)元素都是使用同一學(xué)習(xí)率來自我迭代。 而在前面我們對(duì)學(xué)習(xí)率討論中,不同學(xué)習(xí)率所帶來的優(yōu)化效果也不同。 因此我們?cè)谒伎寄芊裉岢鲆粋€(gè)自適應(yīng)學(xué)習(xí)率調(diào)整的優(yōu)化算法 AdaGrad算法維護(hù)一個(gè)狀態(tài)變量 通過以下兩個(gè)公式進(jìn)行迭代更新 我們可以看到狀態(tài)變量S每次都是通過梯度按元素平方進(jìn)行迭代,這樣每個(gè)變量就有自己特定的學(xué)習(xí)率,而且狀態(tài)變量放置在分母下,能逐步調(diào)小學(xué)習(xí)率, 不需要人為進(jìn)行調(diào)整。 缺點(diǎn)就是可能模型還未收斂,學(xué)習(xí)率已經(jīng)過小,很難找到合適的數(shù)值解 RMSProp算法 既然AdaGrad缺點(diǎn)是因?yàn)槠椒胶瘮?shù)是個(gè)遞增函數(shù),一直迭代會(huì)讓學(xué)習(xí)率持續(xù)下降。 那么我們不妨將動(dòng)量法的移動(dòng)平均思想,用于處理狀態(tài)變量s 因此RMSProp算是結(jié)合了Adagrad和Momentum的思想 計(jì)算公式如下 移動(dòng)平均并不是一個(gè)單調(diào)遞增的函數(shù),因此它能更好地調(diào)節(jié)學(xué)習(xí)率 Adam算法 Adam算法則是結(jié)合了RMSProp和Momentum算法 它在RMSProp算法基礎(chǔ)上也對(duì)梯度變量做了指數(shù)加權(quán)移動(dòng)平均 公式如下 這里對(duì)速度變量做的指數(shù)移動(dòng)平均與動(dòng)量法的方法有點(diǎn)區(qū)別 在t較小的時(shí)候,各個(gè)時(shí)間步權(quán)值之和不為1 因此需要做個(gè)偏差修正 然后調(diào)整每個(gè)元素的學(xué)習(xí)率 |
|