cs231n線性分類器作業 svm代碼 softmax


CS231n之線性分類器

斯坦福CS231n項目實戰(二):線性支持向量機SVM

CS231n 2016 通關 第三章-SVM與Softmax

 cs231n:assignment1——Q3: Implement a Softmax classifier

cs231n線性分類器作業:(Assignment 1 ):

二 訓練一個SVM:

steps:

  • 完成一個完全向量化的SVM損失函數
  • 完成一個用解析法向量化求解梯度的函數
  • 再用數值法計算梯度,驗證解析法求得結果
  • 使用驗證集調優學習率與正則化強度
  • 用SGD(隨機梯度下降)方法進行最優化
  • 將最終學習到的權重可視化

1.SVM

支持向量機(Support Vector Machine, SVM)的目標是希望正確類別樣本的分數( W^TX )比錯誤類別的分數越大越好。兩者之間的最小距離(margin)我們用 \Delta 來表示,一般令 \Delta =1。

對於單個樣本,SVM的Loss function可表示為:

L_i=\sum_{j\neq y_i}max(0,s_j-s_{y_i}+\Delta)

 

s_j=W_j^Tx_is_{y_i}=W_{y_i}^Tx_i 帶入上式:

L_i=\sum_{j\neq y_i}max(0,W_j^Tx_i-W_{y_i}^Tx_i+\Delta)

 

其中, (x_i,y_i) 表示正確類別, s_{y_i} 表示正確類別的分數score, s_j 表示錯誤類別的分數score。從 L_i 表達式來看, s_j 不僅要比 s_{y_i} 小,而且距離至少是 \Delta ,才能保證 L_i=0 。若 s_j>s_{y_i}+\Delta ,則 L_i>0 。也就是說SVM希望 s_js_{y_i} 至少相差一個Δ的距離。

該Loss function我們稱之為Hinge Loss

 

此處使用多分類的hinge loss, Δ=1:   

假如一個三分類的輸出分數為:[10, 20, -10],正確的類別是第0類 (yi=0),則該樣本的Loss function為:

L_i=max(0, 20-10+1)+max(0, -10-10+1)=11

 

值得一提的是,還可以對hinge loss進行平方處理,也稱為L2-SVM。其Loss function為:

L_i=\sum_{j\neq y_i}max(0,W_j^Tx_i-W_{y_i}^Tx_i+\Delta)^2

這種平方處理的目的是增大對正類別與負類別之間距離的懲罰。

依照scores帶入hinge loss:

依次計算,得到最終值,並求和再平均:

svm 的loss function中bug:

     簡要說明:當loss 為0,則對w進行縮放,結果依舊是0,如何解決?如下圖所示:

 

加入正則項:

 

加入正則,對w進行約束,常用的正則有L1 L2

L1趨於選取稀疏的參數,L2趨於選取數值較小且離散的參數。

 

  問題1:如果在求loss時,允許j=y_i

      此時L會比之前未包含的L大1

  問題2:如果對1個樣本做loss時使用對loss做平均,而不是求和,會怎樣?

      相當於sum乘以常系數

  問題4:上述求得的hinge loss的最大值與最小值:

    最小值為0,最大值可以無限大。

  問題5:通常在初始化f(x,w)中的參數w時,w值范圍較小,此時得到的scores接近於0,那么這時候的loss是?

    此時正確score與錯誤score的差接近於0,對於3classes,loss的結果是2。

 

2.softmax

 

使用似然估計作為loss,本來是似然估計越大越好,但通常loss使用越小時更直觀,所以乘以-1

單一樣本:

  

單一樣本數值表示:

\displaystyle Li=-log(\frac{e^{f_{y_i}}}{\sum_je^{f_j}})

具體例子:

3、SVM與Softmax比較:

  模型不同,loss function不同》》

  loss function:

問題8:如果改變對輸入數據做改變,即f(x,w)后的值發生變化,此時兩個模型的loss分別會怎樣變化?(如下例所示)

當改變的值不大時,對svm結果可能沒影響,此時改變的點沒有超過邊界;但當改變較大時,會使得loss變化,此時表示數據點已經跨越了最大邊界范圍。

但是對softmax而言,無論大小的改變,結果都會相應變化。

4、參數計算

  對兩種模型loss 求和取平均並加入正則項。

方案1:隨機選擇w,計算得到相應的loss,選取產生的loss較小的w。

方案2:數值計算法梯度下降 

一維求導:

  多維時,分別對分量求導。具體步驟如下所示: h為定值

     

  上述計算了2個分量的偏導。按照此方法求其余分量偏導。代碼結構如下圖:

  顯然,這種方式計算比較繁瑣,參數更新比較慢。

方案三:解析法梯度下降

方案二使用逐一對w進行微量變化,並求導數的方式步驟繁瑣,並且產生了很多不必要的步驟。

方案三是直接對w分量求偏導的方式:

     

  對於SVM:

  對於softmax:

softmax梯度推導

(1)概率

  (2)似然函數

  (3)對似然函數關於θq求導

      似然函數展開:

      求導:

 SVM代碼 返回loss和dw 給出兩種寫法 :

(1)循環的寫法:

def loss_naive(self, X, y, reg):
        """
        Structured SVM loss function, naive implementation (with loops).
        Inputs:
        - X: A numpy array of shape (num_train, D) contain the training data
          consisting of num_train samples each of dimension D
        - y: A numpy array of shape (num_train,) contain the training labels,
          where y[i] is the label of X[i]
        - reg: float, regularization strength
        Return:
        - loss: the loss value between predict value and ground truth
        - dW: gradient of W
        """

        # Initialize loss and dW
        loss = 0.0
        dW = np.zeros(self.W.shape)

        # Compute the loss and dW
        num_train = X.shape[0]
        num_classes = self.W.shape[1] 
        for i in range(num_train):
            scores = np.dot(X[i], self.W)
            for j in range(num_classes):
                if j == y[i]:
                    margin = 0
                else:
                    margin = scores[j] - scores[y[i]] + 1    # delta = 1
                    if margin > 0:
                        loss += margin
                        dW[:,j] += X[i].T
                        dW[:,y[i]] += -X[i].T
        # Divided by num_train
        loss /= num_train
        dW /= num_train

        # Add regularization
        loss += 0.5 * reg * np.sum(self.W * self.W)
        dW += reg * self.W

        return loss, dW

(2)矩陣操作;

def loss_vectorized(self, X, y, reg):
        """
        Structured SVM loss function, naive implementation (with loops).
        Inputs:
        - X: A numpy array of shape (num_train, D) contain the training data
          consisting of num_train samples each of dimension D
        - y: A numpy array of shape (num_train,) contain the training labels,
          where y[i] is the label of X[i]
        - reg: (float) regularization strength
        Outputs:
        - loss: the loss value between predict value and ground truth
        - dW: gradient of W
        """

         # Initialize loss and dW
        loss = 0.0
        dW = np.zeros(self.W.shape)

        # Compute the loss
        num_train = X.shape[0]
        scores = np.dot(X, self.W)
        correct_score = scores[range(num_train), list(y)].reshape(-1, 1)    # delta = -1
        margin = np.maximum(0, scores - correct_score + 1)
        margin[range(num_train), list(y)] = 0
        loss = np.sum(margin) / num_train + 0.5 * reg * np.sum(self.W * self.W)

        # Compute the dW 
        num_classes = self.W.shape[1]
        mask = np.zeros((num_train, num_classes))
        mask[margin > 0] = 1
        mask[range(num_train), list(y)] = 0
        mask[range(num_train), list(y)] = -np.sum(mask, axis=1)
        dW = np.dot(X.T, mask)
        dW = dW / num_train + reg * self.W

        return loss, dW

 dw是Li中j不等於yi時hingeloss大於0的個數的和乘對應的xi的負數,就是下面的式子

每一列是一個樣本經過參數矩陣計算得到的對不同類別的score,Li計算每個樣本得分與真實標簽的hinge loss

 每個score都是由下面的矩陣計算得到,xi是一個樣本,w和b是參數矩陣,f(xi;W,b)是樣本對每一類的score:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM