前言
最近開始學習cs231n的課程,想從基礎上再梳理一下視覺相關的知識點,課程中有些概念的解釋還是非常巧妙的,將自己有些領悟的地方記錄下來,方面以後回顧。
Loss Functions
SVM Loss
對於一個線性模型,計算出來的值就是某張圖片對於每個類別的分數。
如上圖的計算一樣,假設我們現在有了一組W,如何判斷這個W的表現如何呢?
因此引入了loss函數,用這個loss函數計算出來的值來評估這組W計算出來的結果與我們期待的結果之間的差距。我們期待的情況當然是這張圖片真實label位置計算出來的score要大於其他位置的score,如果符合這個要求,loss就爲0,否則就會有loss值產生以表示跟我們期待的情況有差距。
給定樣本,從1到N,N是總共樣本個數,我們會對每一個樣本求loss,然後彙總得到總共的loss
按照上面提到的思路,我們希望圖片真實label的score要高於其他位置score,這裏爲了提高robustness,我們增加一個margin值,讓真實label是score大於其他位置score+margin,假定margin爲1,那麼loss可以如下表示,叫做SVM loss
表示正確label的得分,表示其他位置的得分,如果比+1還要大,那麼就沒有loss產生,否則有loss。
上圖表示SVM loss也叫做Hinge loss,橫軸表示,縱軸表示loss大小,可見如果>+1,loss爲0,否則loss可以上升到無線大。所以SVM loss的最小值爲0,最大值爲無線大。
對上圖的例子進行計算,最後L=(2.9+0+12.9)/3=5.27
regularization
那麼現在有一個問題,對於汽車的L爲0,那是否只有唯一一個W使L=0呢?當然不是2W也會讓L=0
比如如果car的score都翻倍,最後計算出來的L肯定還是0,所以我們要對L加一個正則項。
現在L由兩部分組成,第一個式子就是前面提到過的loss公式,這裏叫做data loss,第二個式子叫做regularization
一般用L1和L2正則化兩種比較多。
對於上面提到的W和2W的情況,如果loss加上了,那麼很明顯W會更優。
另外增加了還可以降低過擬合(overfitting)的情況。
如果我們只追求W對訓練數據的擬合,就可能會導致W不能更好的範化,不能很好的適應val或者test數據叫做過擬合。
上圖中圓形表示訓練數據,方形表示測試數據,我們希望我們的預測函數是綠色的線而不是藍色的線,藍色的線是過擬合的情況,曲線波動很大,所以很多位置的斜率都會比較大,表示W的值相對比較大,當我們加上regularization的約束後W的值會相對小一些,這樣綠色線條的loss會比藍色線條的loss更好而更優。
那麼L1 regularization和L2 regularization有什麼差別呢?
例子1:
假設,,
用L2 regularization來計算,對應的loss更大,對應的loss更小,所以更優
就是說L2主要是讓w參數更加均衡,能夠均衡的使用每個特徵信息
例子2:
假設,,
用L1 regularization來計算對應loss更小
所以L1會更加突出某個特徵信息
至於是L1還是L2的方式更好,需要根據實際情況來看。
Softmax Loss
softmax loss生成的是正確標籤的佔所有求和的比重,所以它與SVM loss不同的是,softmax loss希望正確label的score越大越好,遠遠大於錯誤的score,這樣才能讓softmax loss比較小。而SVM loss則只需要正確label的score比錯誤的大一個margin值就好了,條件控制上不如softmax嚴格。
總結
Optimization
我們知道了如何衡量一個W的值的好壞,那如何才能找到最好或者比較好的W值呢?
假設我們在綿延不覺的山丘中漫步,山的高度就是loss的大小,腳下的每一步就是W的值,我們如何才能找到山丘中的最低點呢?
我們用自己的腳來感覺山丘的坡度,然後朝着下降的方向行走是可行的方法。
對數據而言,我們就是需要求出W中每個值的斜率,然後都朝着斜率爲0的方向來更新W中的每個值。
斜率就是導數
對一組矩陣W,我們可以根據上面的斜率公式依次求出裏面每個w的導數得到dw,這種方法可行,但是會很慢。
事實上loss函數可以根據W求導得到求導函數,然後將W的值帶入得到dw,這樣會更快。
代碼實現如上,先求出dw,然後用dw更新W,step_size就是每一個步伐的大小,也就是learning rate。
但是有個問題,我們求Loss的時候需要求出每個樣本的loss然後求和,計算出來的導數函數也是每個L_i對W計算導數然後求和,如果樣本非常多,比如ImageNet有1,500,000以上的圖片,那麼需要1,500,000個計算式子相加才能得到weights_grad的值,這樣計算會非常慢。
所以引入minibatch,從總樣本中取出部分進行Gradient Descent計算