卷積神經網絡 + 機器視覺: L3_Loss Functions and Optimization (斯坦福CS231n)

完整的視頻課堂鏈接如下:

完整的視頻課堂投影片連接:

前一課堂筆記連結:

 

開始利用 Linear Classifier 的時候需要做的幾件事:

  1. 定義一個 Loss Function 用來量化一個訓練集中“不滿意的得分”的水平,簡單說就是好與不好(0與1)該以哪裏作爲臨界點。
  2. 需要一個方法用來找出 Loss Function 裏面的參數,能夠讓整體 Loss Function 得出來的值達到最小化。
     

    -- 第一步,把一張圖片的全部 pixels 拉直成爲一個只有一行的矩陣,並且我們命名爲數據集 Xi
    -- 第二步,接着用權重矩陣與被拉長成一條的矩陣做 dot product得出每個 pixel 的重要性評比
    -- 第三步,加上一個修正量目的是爲了更好的讓分類器能夠分辨哪些零散的數據是屬於哪一個區域的,提升劃線區分兩種不同類別的東西的操作性。

但是這以運算過程中包含了 dot 與 add 兩個計算,不方便我們在程序代碼中去操作,因此我們會在被拉長的那一條矩陣最下面一列加一個“1”,並把修正項的矩陣融合到權重的矩陣中,這麼一來就可以直接用一個 dot 把所有事情都做了,操作上簡單。

 

Loss Function 的重要性

這個 Function 是一個我們主要用來評判線性分選器中經過權重 W 的評分後預測出來的值有多差的一個手段。下面介紹的第一個方法稱爲 Multiclass Support Vector Machine Loss,又簡稱 SVM Loss,定義爲整個 dataset 加起來的損失的平均,公式如下:

其中參數裏面,
    x 是一張圖片被拉直後做成的原始數據輸入於此,是預測位置數據的依據;
    y 是被線性分選器(linear classifier)預測出來的預測值。
這邊的目標就是找到一個最合適的 W 權重值,使得整個 loss function 可以達到最小值。

一般使用的公式模型如下:

順帶附上 wiki 的介紹網址: https://en.wikipedia.org/wiki/Hinge_loss

 

Hinge Loss

意思可以想象成一個合格指標,只有當分類器在各個種類的得分過程中,正確的一項高過其他不正確的項至少一個 hinge loss 大小的時候,我們才把這個分類器得出來的判斷結果歸納爲正確。如圖上的 hinge loss 就是 1 。下面一個舉例計算 Loss Function 可以更直觀理解:

  貓的圖片 汽車的圖片 青蛙的圖片
貓的得分 3.2 1.3 2.2
汽車的得分 5.1 4.9 2.5
青蛙的得分 -1.7 2.0

-3.1

可以看到這個分類器 classifier 是有問題的,貓的圖片對應到的跑分竟然是汽車比較高,青蛙則錯得更離譜了,只有汽車是好的。如果把公式套用到這個例子裏面,算法如下:
    1. Loss Function for cat: max(0, 5.1-3.2+1) + max(0, -1.7-3.2+1) = 2.9
    2. Loss Function for car: max(0, 1.3-4.9+1) + max(0, 2.0-4.9+1) = 0
    3. Loss Function for frog: max(0, 2.2-(-3.1)+1) + max(0, 2.5-(-3.1)+1) = 12.9
    4. Entire Loss: (2.9 + 0 + 12.9)/3 = 5.27
** 補充:max() 的功能是比較 () 裏面的數字,哪一個最大就選擇哪一個作爲答案。

上述例子可以很明顯看出合格指標 Hinge Loss 起到的作用,如果它越大,則對 classifier 要求的正確與不正確之間的差距也要越大才能夠到達及格水平,讓最後在 max() 裏面得出的項是比 0 小的,達到沒有 Loss 的境地。

 

This triangle delta is some fixed margin indicating that the score of the correct labeled object should be higher at least THIS amount of value than the rests of the error classes so that there would be no loss. If we further stretch out this formula to be an illustrative line, it goes like this:

進一步我們如果用 python 代碼去表示這個方程式的算法,可以寫成:

>>> import numpy as np
>>> def Li_vectorized(x, y, W):
        scores = W.dot(x)
        margins = np.maximum(0, scores - scores[y] + delta)
        margins[y] = 0
        loss_i = np.sum(margins)
        retrun loss_i

從公式可以得出,Loss Function 最大值就是 0 ,而最小值可以是 -∞。

Special case 1:
如果遇到一開始的 W 很小,導致得出來的權重分數接近的話,那 Loss 的值就是 總類數 -1(在 delta = 1 的情況下)。可以視爲 很小的數 + delta = delta,並且自己的 Syi 項不會用來自己剪去自己,故答案 = 總類數 - 1。

 

Special case 2:

 

如果把 max() 做了平方,得出來的結果就會是個不同權重的 Loss 值,一次方與二次方是個不同的方法,需要依照自己所面臨的情況去調整。

但是有一點很重要的觀念需要切記,即便 Loss 的值達到了最優 0,也不意味着這就是最好的情況,因爲那是根據現有的數據做分類,我們創造這個 classifier 目的是爲了檢測未知的數據,看它在未知的領域的表現,現有的數據只是我們的一個預測未知的依據,很多時候達到最優 0 反而意味着過擬合,並不是一件好事。

 

Regularization

 

前面說到了過擬合,這就是用來處理普遍會在機器學習出現的過擬合問題的,它的用意就是讓 W 在選擇的時候,能夠根據實際情況挑選一個比較簡單的參數去套用。因此一個完整的 Loss Function 應該包含兩個項,並在 Regularization 項前面乘上 λ (a hyperparameter)。

Although linear classifier looks good when we gain the perfect Weight value, this W is still not the unique answer. We can simply multiply its value originally found as the perfect one to fit the dataset to gain the other one. Therefore, this Regularization term helps to set a preference for a certain set of weights W over others to remove this ambiguity.

Re 有很多方法,這邊就只介紹 L2 Regularization (Weight Decay)。公式如下:

整個方程式只基於 W 去給參數。加上原有的項之後,整個完整的 MSVM Loss Function 成了這個樣子:

 

我們可以藉由懲罰大的權重來提升整體的 generalization 效果,小的 W 權重可以有相對更小的 Re 項,使得整個結果更難過擬合。

 

 

The other classifier: Softmax classifier
This is similar to the output treatment by SVM. But Softmax's output is a bit more intuitive and has a probabilistic interpretation inside the formula. The loss function looks like this:

我們可以拿一個隨意實數值的向量,把它塞進這個 Softmax function 的流程中做運算,最後得出一個按照原本數字大小比例分佈的,所有新的數值都介於 0~1 的新向量。

我們把算出來的所有權重分數作爲 exponential 的指數方差項,讓得出來的結果不論如何都是“正整數”,接着對加總過後的總和標準化(normalize)得出一個像是機率區間分佈的結果。我們希望通過這個方法激勵例如在貓的那個評分裏有權重佔比的數值,使之更加凸顯其特徵,最後做到拉開其他不正確分類積分的差距。

相對上一個方法而言,Softmax 前面要加一個 ”-“ 原因是 Loss Function 是用來評比預測值有多 “差” 而不是多好,下面的例子就可以理解詞話的含義:

計算方法如下:
    1. cat:exp(3.2) = 24.5 ; 24.5/(24.5+164.0+0.18) = 0.13 ; -log(0.13) = 0.89
    2. car: exp(5.1) = 164.0 ; 164.0/(24.5+164.0+0.18) = 0.87 ; -log(0.87) = 0.06
    3. frog: exp(-1.7) = 0.18 ; 0.18/(24.5+164.0+0.18) = 0 ; ...

這個方法的極值加上 ”-“ 後,也是 maximum = 0;minimum = -∞。
具體更多細節補充可以查詢下面網址:
https://blog.csdn.net/u010976453/article/details/78488279

 

Comparison of these two methods above

o SVM Loss: 更趨近於讓原本數據之間的差異保留原汁原味,甚至我們可以通過一些手段把原本就差很大的間距提升到更大。換言之,這個方法只能夠基於數據本身的差異上 ”加油添醋“ ,跟現實世界的貧富差距有異曲同工之妙。

o Softmax Loss:得出來的結果有是有一個區間限制的,只能在 0~1 之間,不論原本彼此差別多麼的大,最終都要把差距按照公式定義的比例壓縮到這個區間裏,因此這個方法強調的是如何讓有差距的數據往 0 或者 1 的兩極方向跑,藉由讓數據集分化去 0 或者 1 的一端,達到最終目的。

 

Optimization 

這裏開始介紹在現實情況中,我們使用何種方法去找到 Loss Function 中 W 權重的最佳值。

Strategy #1. Random search, a very bad idea though... here are the lines of code:

>>> bestloss = float('inf')        # python assigns the highest possible float value
>>> for num in xrange(1000):
        W = np.random.randn(10, 3073) * 0.0001        # to generate random parameters
        loss = L(X_train, Y_train, W)        # get the loss over the entire training set
        if loss < bestloss:
            bestloss = loss
            bestW = W
        print('in attempt $d the loss was %f, best %f' %(num, loss, bestloss)) 

一般而言,這個方法是在最一開始就被捨棄的,無頭蒼蠅,純靠運氣,無用。

Strategy #2. Follow the slope

對該 Loss Function 做微分,找出對應的切線方程式,梯度 Gradient 就是該方程對應的向量。代碼如下:

 

>>> while True:        # in a real graph, we use for loop to run the model typically
        weights_grad = evaluate_gradient(loss_fun, data, weights)
        weights += -step_size * weights_grad        # perform parameter update
# step_size is also a hyperparameter used to define how fast the loop will get closed to the target.

以前微積分課教的 lim 那套雖然說原理和算法上都是對的,但是對於計算機要處理那麼多比資料的情況下,外加可能需要被微分的數學公式極爲複雜,這個方式是非常慢且不合實際情況的,(不過它是一個很好用來測試最終結果是否是最小值的方法,這也是上帝幫他開起的另一扇窗吧),因此我們一般會使用 Backpropagation,這個方法細節後面筆記介紹。

我們需要把一個方程式微分求梯度,但同時面對效率提升同時要維持功能的壓力下,需要分門擊破真個數據集的運算,不能同時擠在一起,因此解法是:Stochastic Gradient Descent (SGD)。


In every iteration, we sample some small sets of training samples called minibatch to compute and estimate the full sum and the true gradient. The code goes like this:

 

>>> while True:
        data_batch = sample_training_data(data, 256)
        # sample 256 exampels
        weights_grad = evaluate_gradient(loss_fun, data_batch, weights)
        weights += -step_size * weights_grad        # perfrom parameter update


The other earlier example approaches to recognize the image:
- Histogram of Oriented Gradients (HoG): Divide image into 8*8 pixel regions and quantize edge of the regions direction into 9 bins.
- Color Histogram
- Bag of words, the inspiration from nature language processing. the logic here is to count the difference of the characteristics in different images as a paragraph. but there are not vocabulary to describe the image understood by a computer.

 

Image features vs ConvNets
Get an image >>> feature extraction >>> 10 numbers giving scores for classes >>> training >>> convolutional network application >>> output.

The extracted features from the images would be the fixed block that remains unchanged during the training. The only thing changed is the parameters applied in the linear classifier set to fit the minimum loss.

When we talk about CNN, it is quite similar to the earlier approach. But CNN learn the features directly from the data instead of making visual words first.

 

下節鏈接:卷積神經網絡 + 機器視覺: L4_反向傳播_神經網絡內部構造 (斯坦福課堂)

發佈了43 篇原創文章 · 獲贊 33 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章