除了得到最小的W之外,如何節省這個探索最優W的過程,也是很重要的一點。假如把這個過程比作從山上的頂點開始下山,把圖中必定游玩的經典比作最優權重,那么節省的過程,就是找到下山的最短路徑的過程。而在下山的過程中,我們通常會根據腳傳來的感覺去判斷地面凹凸不平的情況,從而選擇地勢更矮的部分去下山,我們所走的每一步都是往更低的方向走,且由于每次我們都是選擇往最矮的方向走,可以節省很多不必要的力氣。
像這種一步一步去判斷當前最優的方法,就是我們常說的梯度下降法,而每次選擇更低的方向就好比我們在每個x點上,將前后的值作差,并令這個步長接近于0,求得的斜率就是我們每一步要選擇的梯度。不過與一維函數不同的是,由于輸入的x可能是向量的形式,所以求得的梯度一般都是由偏導數組成的向量,也就能看到在當前向量下的各個方向的最優斜率,從而讓模型明確該如何優化。
一般在計算機中,用有限差分法從傳統的意義上,通過逼近極限來計算梯度,如下圖:
對于每一步的梯度,對計算方向上的數據加0.0001,然后計算改變前后的損失值差除以0.0001來作為這個偏導數。但這個方法相當于要對向量的每一項都進行計算,如果我們在實際應用時,用到的卷積網絡很大,向量W可能不只有10個類別,那么要一步步去迭代計算每一項會讓我們的函數計算變得非常的緩慢。我們一般采用的方式是直接對梯度的公式進行微分運算,這就相當于我們只需要計算一個公式表達式,剩下的直接帶入值即可。不過這并不是說有限差分法不好,用它來計算可以保證結果的準確性(因為其是從定義出發),所以我們會用它來進行調試,在模型訓練前選取一些數據分別用微分法和有限差分法計算去對比,從而確認代碼的方向無誤,我們把前者叫解析梯度,后者叫做數值梯度。
所以在實際使用中,步驟通常是先隨機分配權重,去計算當前的損失值、梯度以及梯度相反的方向(從梯度計算公式出發,x是向量時,方向導數是梯度和向量的點積,公式里是取夾角的cos值,也就能知道夾角為0度時其取最大值1,所以梯度的方向是增加函數值的方向),從而確定要怎么更新權重,再重復這一步驟知道損失為0。但在計算梯度時的步長是我們人為設定的(又叫學習率),是每經過多少就要更新權重。為了謹慎,我想很多人都會習慣性往小的參數設置,但并不是說設置一個很小的步長,就一定能獲得最優解,因為這很可能會因為步長過小,導致在很小的一段數據里,模型被后續大的梯度誤導以為已經求得了最優的權重,類似于在山上到達了一個較小的山谷,但由于四周看不到更矮的地方,就以為自己到了山腳。
不過如果數據集比較大,盡管我們用了很好的優化算法和函數表達,由于梯度下降是計算梯度和,那么每次梯度下降,其實都是相當于做了N次計算,而損失和也需要做N次運算,會使計算過程變得非常緩慢,所以一般我們會取數據集的一小部分取計算梯度來估算整個數據集的梯度,這叫做隨機梯度下降,所取得數據集叫minibatch,一般是2的n次冪。
不過在現在的普遍處理中,我們在進行線性分類時,一般都會先進行特征處理,即先對圖片的像素做處理,提取出某類特征的數字作為輸入,而不是直接把像素轉換為向量輸入進去。因為線性分類的本質是可以看做在平面圖中用直線作為決策邊界去劃分不同類別,但如果圖片的兩個類別在平面圖中是以圓的形式存在,直線是無法區分的,而轉換成特征的形式其實就是把他們變成在平面圖上按照類直線排列的形式,這樣有助于模型區分。
學習來自于斯坦福教程:Stanford University CS231n: Deep Learning for Computer Vision