深度学习与计算机视觉(三)最优化与梯度下降
三、最優(yōu)化與梯度下降
上一節(jié)深度學(xué)習(xí)與計(jì)算機(jī)視覺(jué)系列(3)_線性SVM與SoftMax分類器中提到兩個(gè)對(duì)圖像識(shí)別至關(guān)重要的概念:
其中對(duì)于線性SVM,我們有:
1. 得分函數(shù)
2. 損失函數(shù)
L=1N∑i∑j≠yi[max(0,f(xi;W)j?f(xi;W)yi+1)]+αR(W)L=1N∑i∑j≠yi[max(0,f(xi;W)j?f(xi;W)yi+1)]+αR(W)
在取到合適的參數(shù)W的情況下,我們根據(jù)原始像素計(jì)算得到的預(yù)測(cè)結(jié)果和實(shí)際結(jié)果吻合度非常高,這時(shí)候損失函數(shù)得到的值就很小。
這節(jié)我們就講講,怎么得到這個(gè)合適的參數(shù)W,使得損失函數(shù)取值最小化。也就是最優(yōu)化的過(guò)程。
3.1 損失函數(shù)可視化
計(jì)算機(jī)視覺(jué)中看到的損失函數(shù),通常都是定義在非常高維空間里的,無(wú)法直接看到其形狀和變化情況,但是可以將高維投射到一個(gè)向量或者一個(gè)面上,從而直觀的看到其變化。
舉個(gè)例子說(shuō),我們可以對(duì)一個(gè)權(quán)重矩陣W(例如CIFAR-10中是30730個(gè)參數(shù)),可以找到W維度空間中的一條直線,然后沿著這條線,計(jì)算一下?lián)p失函數(shù)值的變化情況。具體一點(diǎn)說(shuō),就是我們找到一個(gè)向量W1W1 (維度要和W一樣,這樣W1W1 才能表示W(wǎng)的維度空間的一個(gè)方向),然后我們給不同的a值,計(jì)算L(W+aW1)L(W+aW1),這樣,如果a取得足夠密,其實(shí)我們就能夠在一定程度上描繪出損失函數(shù)沿著這個(gè)方向的變化了。
同樣,如果我們給兩個(gè)方向W1W1 和W2W2 ,那么我們可以確定一個(gè)平面,我們?cè)偃〔煌档腶和b,計(jì)算L(W+aW1+bW2)L(W+aW1+bW2) 的值,那么我們就可以大致繪出在這個(gè)平面上,損失函數(shù)的變化情況了。
根據(jù)上面的方法,我們畫出了下面3個(gè)圖。最上面的圖是調(diào)整a的不同取值,繪出的損失函數(shù)變化曲線(越高值越大);中間和最后一個(gè)圖是調(diào)整a與b的取值,繪出的損失函數(shù)變化圖(藍(lán)色表示損失小,紅色表示損失大),中間是在一個(gè)圖片樣本上計(jì)算的損失結(jié)果,最下圖為100張圖片上計(jì)算的損失結(jié)果的一個(gè)平均。顯然沿著直線方向得到的曲線底端為最小的損失值點(diǎn),而曲面呈現(xiàn)的碗狀圖形碗底為損失函數(shù)取值最小處。
我們從數(shù)學(xué)的角度,來(lái)嘗試解釋一下,上面的凹曲線是怎么出來(lái)的。對(duì)于第i個(gè)樣本,我們知道它的損失函數(shù)值為:
Li=∑j≠yi[max(0,wTjxi?wTyixi+1)Li=∑j≠yi[max(0,wjTxi?wyiTxi+1)
所有的樣本上的損失函數(shù)值是其損失函數(shù)的平均值(max(0,?)max(0,?),所以最小值是0),為了更好的理解,我們假設(shè)訓(xùn)練集里邊有3個(gè)樣本,都是1維的,同時(shí)總共有3個(gè)類別,所以SVM損失表示如下(暫不考慮正則化):
樣本中的例子都是一維的,所以xixi和wjwj都是實(shí)數(shù),拿w0w0舉例,損失函數(shù)里,大于0的值其實(shí)都和w0w0是線性關(guān)系的,而最小值為0。因此,我們可以想象成,三條折線『合體』得到的最終曲線,如下圖所示:
從之前碗狀結(jié)構(gòu)的示意圖,你可能會(huì)猜到SVM損失函數(shù)是一個(gè)凸函數(shù),而對(duì)于凸函數(shù)的最小值求解方法有很多種。但之后當(dāng)我們把損失函數(shù)f擴(kuò)充到神經(jīng)網(wǎng)絡(luò)之后,損失函數(shù)將變成一個(gè)非凸函數(shù),而如果依舊可視化的話,我們看到的將不再是一個(gè)碗狀結(jié)構(gòu),而是凹凸不平的曲面。
3.2 最優(yōu)化
所謂的最優(yōu)化其實(shí)就是指的找到能夠讓損失函數(shù)最小的參數(shù)W,下面介紹如何一步步的實(shí)現(xiàn)最優(yōu)化問(wèn)題。
3.2.1 策略1:隨機(jī)搜尋(不太實(shí)用)
最原始的方法,當(dāng)我們手上有參數(shù)W后,可以計(jì)算損失函數(shù),評(píng)估參數(shù)合適程度,所以最簡(jiǎn)單的方法就是盡量多的去試參數(shù),然后選擇讓損失函數(shù)最小的,作為最后的W:
# 假設(shè) X_train 是訓(xùn)練集 (例如. 3073 x 50,000) # 假設(shè) Y_train 是類別結(jié)果 (例如. 1D array of 50,000)bestloss = float("inf") # 初始化一個(gè)最大的float值 for num in xrange(1000): W = np.random.randn(10, 3073) * 0.0001 # 隨機(jī)生成一組參數(shù)loss = L(X_train, Y_train, W) # 計(jì)算損失函數(shù)if loss < bestloss: # 比對(duì)已搜尋中最好的結(jié)果bestloss = lossbestW = Wprint 'in attempt %d the loss was %f, best %f' % (num, loss, bestloss)# prints: # in attempt 0 the loss was 9.401632, best 9.401632 # in attempt 1 the loss was 8.959668, best 8.959668 # in attempt 2 the loss was 9.044034, best 8.959668 # in attempt 3 the loss was 9.278948, best 8.959668 # in attempt 4 the loss was 8.857370, best 8.857370 # in attempt 5 the loss was 8.943151, best 8.857370 # in attempt 6 the loss was 8.605604, best 8.605604 # ... (trunctated: continues for 1000 lines)一通隨機(jī)試驗(yàn)和搜尋之后,我們會(huì)拿到試驗(yàn)結(jié)果中最好的參數(shù)W ,然后在測(cè)試集上看看效果:
# 假定 X_test 為 [3073 x 10000], Y_test 為 [10000 x 1] scores = Wbest.dot(Xte_cols) # 10 x 10000, 計(jì)算類別得分 # 找到最高得分作為結(jié)果 Yte_predict = np.argmax(scores, axis = 0) # 計(jì)算準(zhǔn)確度 np.mean(Yte_predict == Yte) # 返回 0.1555隨機(jī)搜尋得到的參數(shù)W,在測(cè)試集上的準(zhǔn)確率為15.5%,總共10各類別,我們不做任何預(yù)測(cè)只是隨機(jī)猜的結(jié)果應(yīng)該是10%,好像稍高一點(diǎn),但是…大家也看到了…這個(gè)準(zhǔn)確率…實(shí)在是沒(méi)辦法在實(shí)際應(yīng)用中使用。
3.2.2 隨機(jī)局部搜索
上一個(gè)策略完全就是盲搜,要想找到全局最優(yōu)的那個(gè)結(jié)果基本是不可能的。它最大的缺點(diǎn),就在于下一次搜索完全是隨機(jī)進(jìn)行的,沒(méi)有一個(gè)指引方向。那我們多想想,就能想出一個(gè)在上個(gè)策略的基礎(chǔ)上,優(yōu)化的版本,叫做『隨機(jī)局部搜索』。
這個(gè)策略的意思是,我們不每次都隨機(jī)產(chǎn)生一個(gè)參數(shù)矩陣W 了,而是在現(xiàn)有的參數(shù)W 基礎(chǔ)上,搜尋一下周邊臨近的參數(shù),有沒(méi)有比現(xiàn)在參數(shù)更好的W ,然后我們用新的W替換現(xiàn)在的W,接著在周圍繼續(xù)小范圍搜尋。這個(gè)過(guò)程呢,可以想象成,我們?cè)谝蛔缴?#xff0c;現(xiàn)在要下山,然后我們每次都伸腳探一探周邊,找一個(gè)比現(xiàn)在的位置下降一些的位置,然后邁一步,接著在新的位置上做同樣的操作,一步步直至下山。
從代碼實(shí)現(xiàn)的角度看,以上的過(guò)程,實(shí)際上就是對(duì)于一個(gè)當(dāng)前W,我們每次實(shí)驗(yàn)和添加δW′,然后看看損失函數(shù)是否比當(dāng)前要低,如果是,就替換掉當(dāng)前W,代碼如下:
W = np.random.randn(10, 3073) * 0.001 # 初始化權(quán)重矩陣W bestloss = float("inf") for i in xrange(1000):step_size = 0.0001Wtry = W + np.random.randn(10, 3073) * step_sizeloss = L(Xtr_cols, Ytr, Wtry)if loss < bestloss:W = Wtrybestloss = lossprint 'iter %d loss is %f' % (i, bestloss)我們做了這么個(gè)小小的修正之后,我們?cè)倌脛偛乓粯拥臏y(cè)試集來(lái)測(cè)一下效果,結(jié)果發(fā)現(xiàn)準(zhǔn)確率提升至21.4%,雖然離實(shí)際應(yīng)用差很遠(yuǎn),但只是比剛才要進(jìn)步一點(diǎn)點(diǎn)了。
但是還是有個(gè)問(wèn)題,我們每次測(cè)試周邊點(diǎn)的損失函數(shù),是一件非常耗時(shí)的事情。我們有沒(méi)有辦法能夠直接找到我們應(yīng)該迭代的方向呢?
3.2.3 順著梯度下滑
剛才的策略,我們說(shuō)了,最大的缺點(diǎn)是非常耗時(shí),且計(jì)算量也很大。我們一直在做的事情,就是在當(dāng)前的位置基礎(chǔ)上,想找到一個(gè)最合適的下降方向。我們依舊回到我們假設(shè)的那個(gè)情境,如果我們?cè)谏巾?#xff0c;要以最快的方式下山,我們會(huì)怎么做?我們可能會(huì)環(huán)顧四周,然后找到最陡的方向,邁一小步,然后再找當(dāng)前位置最陡的下山方向,再邁一小步…
而這里提到的最陡的方向,其實(shí)對(duì)應(yīng)的就是數(shù)學(xué)里『梯度』的概念,也就是說(shuō),其實(shí)我們無(wú)需『伸腳試探』周邊的陡峭程度,而是可以通過(guò)計(jì)算損失函數(shù)的梯度,直接取得這個(gè)方向。
我們知道在1個(gè)變量的函數(shù)里,某點(diǎn)的斜率/導(dǎo)數(shù)代表其變化率最大的方向。而對(duì)于多元的情況,梯度是上面情況的一個(gè)擴(kuò)展,只不過(guò)這時(shí)候的變量不再是一個(gè),而是多個(gè),同時(shí)我們計(jì)算得到的『梯度方向』也是一個(gè)多維的向量。大家都知道數(shù)學(xué)上計(jì)算1維/元函數(shù)『梯度/導(dǎo)數(shù)』的表達(dá)式如下:
df(x)dx=limh→0f(x+h)?f(x)hdf(x)dx=limh→0f(x+h)?f(x)h
對(duì)于多元的情況,這個(gè)時(shí)候我們需要求的東西擴(kuò)展成每個(gè)方向的『偏導(dǎo)數(shù)』,然后把它們合在一塊組成我們的梯度向量。
我們用幾張圖來(lái)說(shuō)明這個(gè)過(guò)程:
3.2.4 計(jì)算梯度
有兩種計(jì)算梯度的方法:
慢一些但是簡(jiǎn)單一些的數(shù)值梯度/numerical gradient
速度快但是更容易出錯(cuò)的解析梯度/analytic gradient
1、數(shù)值梯度
根據(jù)上面提到的導(dǎo)數(shù)求解公式,我們可以得到數(shù)值梯度計(jì)算法。下面是一段簡(jiǎn)單的代碼,對(duì)于一個(gè)給定的函數(shù)f和一個(gè)向量x,求解這個(gè)點(diǎn)上的梯度:
def eval_numerical_gradient(f, x):""" 一個(gè)最基本的計(jì)算x點(diǎn)上f的梯度的算法 - f 為參數(shù)為x的函數(shù)- x 是一個(gè)numpy的vector""" fx = f(x) # 計(jì)算原始點(diǎn)上函數(shù)值grad = np.zeros(x.shape)h = 0.00001# 對(duì)x的每個(gè)維度都計(jì)算一遍it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])while not it.finished:# 計(jì)算x+h處的函數(shù)值ix = it.multi_indexold_value = x[ix]x[ix] = old_value + h # 加hfxh = f(x) # 計(jì)算f(x + h)x[ix] = old_value # 存儲(chǔ)之前的函數(shù)值# 計(jì)算偏導(dǎo)數(shù)grad[ix] = (fxh - fx) / h # 斜率it.iternext() # 開始下一個(gè)維度上的偏導(dǎo)計(jì)算return grad代碼的方法很簡(jiǎn)單,對(duì)每個(gè)維度,都在原始值上加上一個(gè)很小的h,然后計(jì)算這個(gè)維度/方向上的偏導(dǎo),最后組在一起得到梯度grad。
1)實(shí)際計(jì)算的問(wèn)題:
我們仔細(xì)看看導(dǎo)數(shù)求解的公式,會(huì)發(fā)現(xiàn)數(shù)學(xué)定義上h是要趨于0的,但實(shí)際我們計(jì)算的時(shí)候我們只要取一個(gè)足夠小的數(shù)(比如1e-5)作為h就行了,所以我們要精準(zhǔn)計(jì)算偏導(dǎo)的話,要盡量取到不會(huì)帶來(lái)數(shù)值計(jì)算問(wèn)題,同時(shí)又能很小的h。另外,其實(shí)實(shí)際計(jì)算中,我們用另外一個(gè)公式用得更多[f(x+h)?f(x?h)]/2h[f(x+h)?f(x?h)]/2h
下面我們用上面的公式在CIFAR-10數(shù)據(jù)集上,試一試吧:
def CIFAR10_loss_fun(W):return L(X_train, Y_train, W)W = np.random.rand(10, 3073) * 0.001 # 隨機(jī)權(quán)重向量 df = eval_numerical_gradient(CIFAR10_loss_fun, W) # 計(jì)算梯度計(jì)算到的梯度(準(zhǔn)確地說(shuō),梯度的方向是函數(shù)增大方向,負(fù)梯度才是下降方向)告訴我們,我們應(yīng)該『下山』的方向是啥,接著我們就沿著它小步邁進(jìn):
loss_original = CIFAR10_loss_fun(W) # 原始點(diǎn)上的損失 print 'original loss: %f' % (loss_original, )# 多大步伐邁進(jìn)好呢?我們選一些步長(zhǎng)試試 for step_size_log in [-10, -9, -8, -7, -6, -5,-4,-3,-2,-1]:step_size = 10 ** step_size_logW_new = W - step_size * df # 新的權(quán)重loss_new = CIFAR10_loss_fun(W_new)print 'for step size %f new loss: %f' % (step_size, loss_new)# 輸出: # original loss: 2.200718 # for step size 1.000000e-10 new loss: 2.200652 # for step size 1.000000e-09 new loss: 2.200057 # for step size 1.000000e-08 new loss: 2.194116 # for step size 1.000000e-07 new loss: 2.135493 # for step size 1.000000e-06 new loss: 1.647802 # for step size 1.000000e-05 new loss: 2.844355 # for step size 1.000000e-04 new loss: 25.558142 # for step size 1.000000e-03 new loss: 254.086573 # for step size 1.000000e-02 new loss: 2539.370888 # for step size 1.000000e-01 new loss: 25392.2140362)關(guān)于迭代的細(xì)節(jié):
如果大家仔細(xì)看上述代碼的話,會(huì)發(fā)現(xiàn)我們step_size設(shè)的都是負(fù)的,確實(shí)我們每次update權(quán)重W的時(shí)候,是用原來(lái)的W減掉梯度方向的一個(gè)較小的值,這樣損失函數(shù)才能減小。
3)關(guān)于迭代的步長(zhǎng):
我們計(jì)算得到梯度之后,就確定了幅度變化最快(負(fù)梯度是下降方向)的方向,但是它并沒(méi)有告訴我們,我朝著這個(gè)方向,應(yīng)該邁進(jìn)多遠(yuǎn)啊。之后的章節(jié)會(huì)提到,選擇正確的迭代步長(zhǎng)(有時(shí)候我們也把它叫做學(xué)習(xí)速率)是訓(xùn)練過(guò)程中最重要(也是最讓人頭疼)的一個(gè)待設(shè)定參數(shù)。就像我想以最快的速度下山,我們能感知到最陡的方向,卻不知道應(yīng)該邁多大的步子。如果我們小步邁進(jìn),那確實(shí)每一步都能比上一步下降一些,但是速度太慢了親!!但是如果我們以非常非常大的步伐邁進(jìn)(假如腿巨長(zhǎng) -_-||),那你猜怎么著,你一不小心可能就邁過(guò)山腳邁到另一座山山腰上了…
下圖是對(duì)以上情況的一個(gè)描述和解釋:
圖上紅色的值很大,藍(lán)色的值很小,我們想逐步下降至藍(lán)色中心。如果邁進(jìn)的步伐太小,收斂和行進(jìn)的速度就會(huì)很慢,如果邁進(jìn)的步伐太大,可能直接越過(guò)去了。
4)效率問(wèn)題:
如果你再回過(guò)頭去看看上面計(jì)算數(shù)值梯度的程序,你會(huì)發(fā)現(xiàn),這個(gè)計(jì)算方法的復(fù)雜度,基本是和我們的參數(shù)個(gè)數(shù)成線性關(guān)系的。這意味著什么呢?在我們的CIFAR-10例子中,我們總共有30730個(gè)參數(shù),因此我們單次迭代總共就需要計(jì)算30731次損失函數(shù)。這個(gè)問(wèn)題在之后會(huì)提到的神經(jīng)網(wǎng)絡(luò)中更為嚴(yán)重,很可能兩層神經(jīng)元之間就有百萬(wàn)級(jí)別的參數(shù)權(quán)重,所以,計(jì)算機(jī)算起來(lái)都很耗時(shí)…
2、解析法計(jì)算梯度
數(shù)值梯度發(fā)非常容易實(shí)現(xiàn),但是從公式里面我們就看得出來(lái),梯度實(shí)際上是一個(gè)近似(畢竟你沒(méi)辦法把h取到非常小),同時(shí)這也是一個(gè)計(jì)算非常耗時(shí)的算法。第二種計(jì)算梯度的方法是解析法,它可以讓我們直接得到梯度的一個(gè)公式(代入就可以計(jì)算,非常快),但是呢,不像數(shù)值梯度法,這種方法更容易出現(xiàn)錯(cuò)誤。so,聰明的同學(xué)們,就想了一個(gè)辦法,我們可以先計(jì)算解析梯度和數(shù)值梯度,然后比對(duì)結(jié)果和校正,在確定我們解析梯度實(shí)現(xiàn)正確之后,我們就可以大膽地進(jìn)行解析法計(jì)算了(這個(gè)過(guò)程叫做梯度檢查 / 檢測(cè))
我們拿一個(gè)樣本點(diǎn)的SVM損失函數(shù)舉例:
我們可以求它對(duì)每個(gè)權(quán)重的偏導(dǎo)數(shù),比如說(shuō),我們求它對(duì)wyiwyi的偏導(dǎo),我們得到:
其中1 是一個(gè)bool函數(shù),在括號(hào)內(nèi)的條件為真的時(shí)候取值為1,否則為0。看起來(lái)似乎很嚇人,但實(shí)際上要寫代碼完成的話,你只需要計(jì)算不滿足指定SVM最小距離的類(對(duì)損失函數(shù)有貢獻(xiàn)的類)的個(gè)數(shù),然后用這個(gè)值會(huì)對(duì)數(shù)據(jù)向量xixi做縮放即可得到梯度。但是要注意只是WW中對(duì)應(yīng)正確的類別的列的梯度。對(duì)于其他的j≠yij≠yi的情況,梯度為:
一旦得到梯度的表達(dá)式,那計(jì)算梯度和調(diào)整權(quán)重就變得非常直接和簡(jiǎn)單。熟練掌握如何在loss expression下計(jì)算梯度是非常重要的一個(gè)技巧,貫穿整個(gè)神經(jīng)網(wǎng)絡(luò)的訓(xùn)練實(shí)現(xiàn)過(guò)程。
3.3 梯度下降
在我們有辦法計(jì)算得到梯度之后,使用梯度去更新已有權(quán)重參數(shù)的過(guò)程叫做『梯度下降』,偽代碼其實(shí)就是如下的樣子:
while True:weights_grad = evaluate_gradient(loss_fun, data, weights)weights += - step_size * weights_grad # 梯度下降更新參數(shù)這個(gè)簡(jiǎn)單的循環(huán)實(shí)質(zhì)上就是很多神經(jīng)網(wǎng)絡(luò)庫(kù)的核心。當(dāng)然,我們也有其他的方式去實(shí)現(xiàn)最優(yōu)化(比如說(shuō)L-BFGS),但是梯度下降確實(shí)是當(dāng)前使用最廣泛,也相對(duì)最穩(wěn)定的神經(jīng)網(wǎng)絡(luò)損失函數(shù)最優(yōu)化方法。
3.3.1 Mini-batch gradient descent
在大型的應(yīng)用當(dāng)中(比如ILSVRC),訓(xùn)練數(shù)據(jù)可能是百萬(wàn)千萬(wàn)級(jí)別的。因此,對(duì)整個(gè)訓(xùn)練數(shù)據(jù)集的樣本都算一遍損失函數(shù),以完成參數(shù)迭代是一件非常耗時(shí)的事情,一個(gè)我們通常會(huì)用到的替代方法是,采樣出一個(gè)子集在其上計(jì)算梯度。現(xiàn)在比較前沿的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)基本都是這么做的,例如ConvNets是每256張作為一個(gè)batch去完成參數(shù)的更新。參數(shù)更新的代碼如下:
while True:data_batch = sample_training_data(data, 256) # 抽樣256個(gè)樣本作為一個(gè)batchweights_grad = evaluate_gradient(loss_fun, data_batch, weights)weights += - step_size * weights_grad # 參數(shù)更新之所以這么做,是因?yàn)橛?xùn)練數(shù)據(jù)之間是關(guān)聯(lián)的,我們簡(jiǎn)化一下這個(gè)問(wèn)題,如果ILSVRC中的120w張圖像,如果只是1000種不同的圖像復(fù)制1200次而來(lái)的,那么其實(shí)我們?cè)谶@1000張圖像上算得的損失函數(shù)和120w的平均其實(shí)是一致的。
當(dāng)然,在實(shí)際場(chǎng)景中,很少會(huì)遇到這種多次重復(fù)的情況,但是原數(shù)據(jù)的一個(gè)子集上的梯度,其實(shí)也是對(duì)整體數(shù)據(jù)上梯度的一個(gè)很好的近似,因此在mini-batch上計(jì)算和更新參數(shù),會(huì)有更快的收斂速度。
隨機(jī)梯度下降:如果mini-batch中只有一張圖像,那么這個(gè)過(guò)程就變成隨機(jī)梯度下降(Stochastic Gradient Descent ,SGD),這個(gè)其實(shí)在實(shí)際應(yīng)用中倒也沒(méi)那么常見(jiàn),原因是向量化之后,一次計(jì)算100張圖片,其實(shí)比計(jì)算一張圖片100次,要快得多。所以即使從定義上來(lái)說(shuō),SGD表示我們用一張圖片上的梯度近似全局梯度,但是很多時(shí)候人們提到SGD的時(shí)候,其實(shí)他們指的是mini-batch梯度下降,也就是說(shuō),我們把一個(gè)batch當(dāng)做1份了。額,還要稍微提一句的是,有些同學(xué)可能會(huì)問(wèn),這個(gè)batch size本身不是一個(gè)需要實(shí)驗(yàn)的參數(shù)嗎,取多大的batch size好啊?但實(shí)際應(yīng)用中,我們倒很少會(huì)用cross-validation去選擇這個(gè)參數(shù)。這么說(shuō)吧,我們一般是基于我們內(nèi)存限制去取這個(gè)值的,比如設(shè)成100左右。
3.4 總結(jié)
- 把損失函數(shù)在各參數(shù)上的取值,想象成我們所在山峰的高度。那么我們要最小化損失函數(shù),實(shí)際上就是『要想辦法下山』。
- 我們采取的下山策略是,一次邁一小步,只要每次都往下走了,那么最后就會(huì)到山底。
- 梯度對(duì)應(yīng)函數(shù)變化最快的方向,負(fù)梯度的方向就是我們下山,環(huán)顧四周之后,發(fā)現(xiàn)最陡的下山路方向。
- 我們的步長(zhǎng)(也叫學(xué)習(xí)率),會(huì)影響我們的收斂速度(下山速度),如果步伐特別特別大,甚至可能躍過(guò)最低點(diǎn),跑到另外一個(gè)高值位置了。
- 我們用mini-batch的方式,用一小部分的樣本子集,計(jì)算和更新參數(shù),減少計(jì)算量,加快收斂速度
總結(jié)
以上是生活随笔為你收集整理的深度学习与计算机视觉(三)最优化与梯度下降的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 银行查流水需要带些什么证明
- 下一篇: 刷卡机手续费收取标准