Higher-level representations, image features Optimization, stochastic gradient descent
導語:
在上一個部分我們介紹了在圖像識別領域的兩個重要部分:score function 和 loss function, SVM的公式如下:
$L = \frac{1}{N} \sum_i \sum_{j\neq y_i} \left[ \max(0, f(x_i; W)j - f(x_i; W){y_i} + 1) \right] + \alpha R(W)$
記下來我們來介紹最后一個部分,優(yōu)化。優(yōu)化是發(fā)現(xiàn)最優(yōu)的W來最小化損失函數(shù)沿彭。
Hinge Loss簡介:Hinge Loss是一種目標函數(shù)(或者說損失函數(shù))的名稱,有的時候又叫做max-margin objective右核。其最著名的應用是作為SVM的目標函數(shù)。
其二分類情況下,公式如下: $\begin{equation}
l(y)=max(0, 1-t\cdot y)
\end{equation}$
其中瘩欺,y是預測值(-1到1之間)蜘腌,t為目標值(±1)沫屡。
其含義為,y的值在-1到1之間就可以了撮珠,并不鼓勵|y|>1沮脖,即并不鼓勵分類器過度自信,讓某個可以正確分類的樣本距離分割線的距離超過1并不會有任何獎勵。從而使得分類器可以更專注整體的分類誤差勺届。
變種: 實際應用中驶俊,一方面很多時候我們的y的值域并不是[-1,1],比如我們可能更希望y更接近于一個概率涮因,即其值域最好是[0,1]废睦。另一方面,很多時候我們希望訓練的是兩個樣本之間的相似關系养泡,而非樣本的整體分類嗜湃,所以很多時候我們會用下面的公式:
$\begin{equation}
l(y,y')=max(0, m-y+y')
\end{equation}$
其中,y是正樣本的得分澜掩,y’是負樣本的得分购披,m是margin(自己選一個數(shù))
即我們希望正樣本分數(shù)越高越好,負樣本分數(shù)越低越好肩榕,但二者得分之差最多到m就足夠了刚陡,差距增大并不會有任何獎勵。
可視化:
通常損失函數(shù)都是高維空間的株汉,使得他們很難可視化筐乳。然而,我們?nèi)匀豢梢缘玫揭恍┲庇^感受通過將高維空間用切片的方式觀察乔妈,比如我們可以產(chǎn)生一個隨機的權重矩陣蝙云,然后沿著一條射線來記錄損失函數(shù)的變化。
除此之外路召,您可能從其碗形外觀中猜出勃刨,SVM成本函數(shù)是凸函數(shù)的一個例子有大量的文獻專門用于有效地最小化這些類型的函數(shù),您還可以選擇斯坦福大學關于主題(凸優(yōu)化)股淡。一旦我們將我們的分數(shù)函數(shù)ff擴展到神經(jīng)網(wǎng)絡身隐,我們的目標函數(shù)將變得非凸,并且上述可視化不會具有碗而是復雜而顛簸的地形唯灵。
不可微分的損失函數(shù)贾铝。作為技術說明,您還可以看到損失函數(shù)中的扭結(由于最大運算)在技術上使損失函數(shù)不可微分埠帕,因為在這些扭結中忌傻,漸變沒有定義。然而搞监,子梯度仍然存在并且通常被使用水孩。在這個類中,可以使用術語“梯度”和“漸變”琐驴。
最優(yōu)化
重申一下俘种,損失函數(shù)可以讓我們量化任何特定的權重集W的質(zhì)量秤标。優(yōu)化的目的是找到最小化損失函數(shù)的W。我們現(xiàn)在將激勵和緩慢地開發(fā)一種優(yōu)化損失功能的方法宙刘。對于你以前的經(jīng)驗來看這個課程的人苍姜,這部分可能看起來很奇怪,因為我們將使用的工作示例(SVM損失)是一個凸起的問題悬包,但請記住衙猪,我們的目標是最終優(yōu)化神經(jīng)網(wǎng)絡,在那里我們不容易使用凸版優(yōu)化文獻中開發(fā)的任何工具布近。
策略一 最差的解決方案是隨機搜索
由于很容易檢驗W的好壞垫释,所以第一個解決方案就是隨機的搜索。代碼如下:
# assume X_train is the data where each column is an example (e.g. 3073 x 50,000)
# assume Y_train are the labels (e.g. 1D array of 50,000)
# assume the function L evaluates the loss function
bestloss = float("inf") # Python assigns the highest possible float value
for num in xrange(1000):
W = np.random.randn(10, 3073) * 0.0001 # generate random parameters
loss = L(X_train, Y_train, W) # get the loss over the entire training set
if loss < bestloss: # keep track of the best solution
bestloss = loss
bestW = W
print 'in attempt %d the loss was %f, best %f' % (num, loss, bestloss)
核心思想:迭代細化撑瞧。當然棵譬,事實證明,我們可以做得更好预伺。核心思想是找到最好的權重集W是一個非常困難或甚至不可能的問題(特別是一旦W包含整個復雜神經(jīng)網(wǎng)絡的權重)订咸,但是將一組特定的權重W精細化為稍好一些的問題是顯著的不那么困難換句話說,我們的方法是從隨機的W開始酬诀,然后迭代地改進它脏嚷,使它每次稍微好一些。
策略二 隨機局部搜索
你可能會想到的第一個策略是嘗試在隨機方向上延伸一只腳瞒御,然后只有在下坡的時候才采取一個步驟然眼。具體來說,我們將從隨機W開始葵腹,對其產(chǎn)生隨機擾動δW,如果擾動的W +δW的損耗較低屿岂,則將進行更新践宴。此過程的代碼如下:
W = np.random.randn(10, 3073) * 0.001 # generate random starting W
bestloss = float("inf")
for i in xrange(1000):
step_size = 0.0001
Wtry = W + np.random.randn(10, 3073) * step_size
loss = L(Xtr_cols, Ytr, Wtry)
if loss < bestloss:
W = Wtry
bestloss = loss
print 'iter %d loss is %f' % (i, bestloss)
策略三 根據(jù)梯度
在上一節(jié)中,我們嘗試在權重空間中找到一個方向爷怀,這將改善我們的權重向量(并給我們較低的損失)阻肩。事實證明,沒有必要隨機搜索一個好的方向:我們可以計算出我們應該改變我們的權重向量的最佳方向运授,該權重向量在數(shù)學上保證是最陡峭下降的方向(至少在極限中為步長為零)烤惊。這個方向與損失函數(shù)的梯度有關。在我們的徒步比喻中吁朦,這種做法大致對應于感覺到我們腳下的山坡柒室,并且沿著最陡峭的方向。
在一維函數(shù)中逗宜,斜率是您可能感興趣的任何點的函數(shù)的瞬時變化率雄右。梯度是不采用單個數(shù)字而是數(shù)字向量的函數(shù)的斜率的推廣空骚。此外,梯度只是輸入空間中每個維度的斜率向量(通常稱為導數(shù))擂仍。 1-D函數(shù)的導數(shù)與其輸入的數(shù)學表達式是:
$\frac{df(x)}{dx} = \lim_{h\ \to 0} \frac{f(x + h) - f(x)}{h}$
當函數(shù)有多維向量而不是一個數(shù)字的時候我們做偏微分囤屹,梯度就是在不同方向上的偏微分。
梯度計算
有兩種計算梯度的方法逢渔,一種是比較慢的雖然是近似但是簡單的和一種快的 但是可能有錯誤肋坚。
第一種:
def eval_numerical_gradient(f, x):
"""
a naive implementation of numerical gradient of f at x
- f should be a function that takes a single argument
- x is the point (numpy array) to evaluate the gradient at
"""
fx = f(x) # evaluate function value at original point
grad = np.zeros(x.shape)
h = 0.00001
# iterate over all indexes in x
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
# evaluate function at x+h
ix = it.multi_index
old_value = x[ix]
x[ix] = old_value + h # increment by h
fxh = f(x) # evalute f(x + h)
x[ix] = old_value # restore to previous value (very important!)
# compute the partial derivative
grad[ix] = (fxh - fx) / h # the slope
it.iternext() # step to next dimension
return grad
但是這種梯度的定義中h的極限趨近于0,但是實際上他使用一個足夠小的值就足夠了肃廓,理想情況智厌,你會想用最小的步長以不會引起計算問題。除此之外亿昏,實際上計算數(shù)字梯度使用中心極限定理是更好的峦剔。$ [f(x+h) - f(x-h)] / 2 h $
loss_original = CIFAR10_loss_fun(W) # the original loss
print 'original loss: %f' % (loss_original, )
# lets see the effect of multiple step sizes
for step_size_log in [-10, -9, -8, -7, -6, -5,-4,-3,-2,-1]:
step_size = 10 ** step_size_log
W_new = W - step_size * df # new position in the weight space
loss_new = CIFAR10_loss_fun(W_new)
print 'for step size %f new loss: %f' % (step_size, loss_new)
我們應該逆向更新梯度方向,并且梯度告訴了我們增加最陡峭的方向但是沒有告訴我們應該向哪個方向前進角钩。選擇合適的步長也就是學習速率將會成為參數(shù)設定中的重要因素吝沫。
另外就是效率問題,你可能已經(jīng)注意到數(shù)字梯度有一個復雜的線性參數(shù)關系递礼。參數(shù)越多惨险,這種策略可能會越差。
計算gradient analytically
鑒于上面的分析脊髓,又有另一種非常普遍的計算題都的方法叫做gradient check辫愉,如果使用SVM的例子,我們可以拿到相應于w的梯度:
$\nabla_{w_{y_i}} L_i = - \left( \sum_{j\neq y_i} \mathbb{1}(w_j^Tx_i - w_{y_i}^Tx_i + \Delta > 0) \right) x_i $
這里1是一個示性函數(shù)将硝,就是里面的是真的那么就取1恭朗,假的取0,所以梯度下降算法依疼,小批量梯度下降痰腮。在大規(guī)模應用(如ILSVRC挑戰(zhàn))中,培訓數(shù)據(jù)可以有數(shù)百萬個例子律罢。因此膀值,為了僅執(zhí)行單個參數(shù)更新,計算整個訓練集中的全損失函數(shù)似乎是浪費的误辑。解決這一挑戰(zhàn)的一個非常常見的方法是計算訓練數(shù)據(jù)批次之間的梯度沧踏。例如,在目前最先進的ConvNets中巾钉,典型的批次包含來自整個120萬個培訓集的256個示例翘狱。此批次然后用于執(zhí)行參數(shù)更新:
# Vanilla Gradient Descent
while True:
weights_grad = evaluate_gradient(loss_fun, data, weights)
weights += - step_size * weights_grad # perform parameter update
原因很好的是訓練數(shù)據(jù)中的例子是相關的。為了看到這一點砰苍,考慮到極端情況盒蟆,ILSVRC中的所有120萬圖像實際上由僅有1000個獨特圖像的精確重復(每個類別一個踏烙,或者每個圖像的1200個相同的副本)組成。然后很明顯历等,我們將為所有1200個相同的副本計算的梯度將全部相同讨惩,當我們平均所有120萬圖像中的數(shù)據(jù)丟失時,我們將獲得完全相同的損失寒屯,就像我們只評估一小部分當然荐捻,實際上,數(shù)據(jù)集不會包含重復的圖像寡夹,小批量的漸變是完整目標的梯度的很好的近似值处面。因此,通過評估小型批量梯度來執(zhí)行更頻繁的參數(shù)更新菩掏,實踐中可以實現(xiàn)更快的收斂魂角。
極端情況是迷你批次僅包含一個示例的設置。該過程稱為隨機梯度下降(SGD)(或有時在線梯度下降)智绸。這是相對較少見的野揪,因為在實踐中由于矢量化的代碼優(yōu)化,對于100個示例瞧栗,對于100個示例的梯度來說斯稳,計算上可以更有效地評估梯度,而不是一個示例100次的梯度迹恐。即使SGD技術上是指一次使用一個例子來評估漸變挣惰,即使在提到微型批量梯度下降(即提及“Minibatch Gradient Descent”的MGD或BGD for “批量梯度下降”很少見),通常假設使用小批量殴边。小批量的大小是超參數(shù)憎茂,但是交叉驗證它不是很常見。它通炒赴叮基于內(nèi)存約束(如果有的話)竖幔,或者設置為一些值,例如能耻。 32,64或128.在實踐中,我們使用2的冪亡驰,因為當它們的輸入的大小為2的冪時晓猛,許多向量化的操作實現(xiàn)工作更快。