1. 程式人生 > >斯坦福CS231n assignment1:softmax損失函式求導

斯坦福CS231n assignment1:softmax損失函式求導

斯坦福CS231n assignment1:softmax損失函式求導

分類

在前文斯坦福CS231n assignment1:SVM影象分類原理及實現中我們講解了利用SVM模型進行影象分類的方法,本文我們講解影象分類的另一種實現,利用softmax進行影象分類。

softmax和svm模型網路結構很相似,區別在於softmax會對svm的輸出分量進行歸一化處理,使得每一個輸出分量變成一個概率值,所有輸出分量的概率之和為1。
歸一化概率

同時損失函式也發生了變化,svm的損失函式折葉損失(hinge loss)是針對樣本的標記類別之外的其他類別進行損失計算的,也就是說標記類別不計入損失,其他類別計算損失並累加作為某個樣本的損失。而softmax的損失函式交叉熵損失(cross-entropy loss)只跟某個樣本的標記類別相關,根據該標記類別的概率計算損失值,而不考慮標記類別之外的其他類別。
svm和softmax損失函式的計算比較

svm得出的每個輸出節點的得分,比如[98, 33, 15]是無標定的,也就是隻是一個相對的大小,難以進行直觀的解釋。而softmax可以解釋為例項被劃分為某個類別的可能性,或者概率。

下面是softmax的損失函式:

softmax損失函式

也可以等價成:
softmax損失函式等價寫法

加入正則化損失項後,批處理過程中N個樣本的平均損失變成:
加入正則項的損失函式

這裡我們使用L2正則化損失:
L2正則化損失項

在此基礎上我們來推導損失函式L對權重Wij的偏導數,推導過程如下:
softmax交叉熵梯度計算

在這個推導過程中需要注意的是,直接跟標記類對應的輸出節點相連的權重和不跟標記類節點相連的權重的偏導數格式是不一樣的,對應於推導過程中的if/else判別。

對應的程式碼如下:

def softmax_loss_naive(W, X, y, reg):
  """
  :param X: 200 X 3073
  :param Y: 200
  :param W: 3073 X 10
  :return: reg: 正則化損失係數(無法通過拍腦袋設定,需要多試幾個值,然後找個最優的)
  """
  dW = np.zeros(W.shape) # initialize the gradient as zero

  # compute the loss and the gradient
  num_classes = W.shape[1]
  num_train = X.shape[
0] loss = 0.0 for k in xrange(num_train): origin_scors = X[k].dot(W) probabilities = np.zeros(origin_scors.shape) logc = -np.max(origin_scors) total_sum = np.sum(np.exp(origin_scors - logc)) for i in xrange(num_classes): probabilities[i] = np.exp(origin_scors[i] - logc) / total_sum for i in xrange(num_classes): if i == y[k]: dW[:, i] += - X[k] * (1 - probabilities[i]) # dW[:, i]:3073X1 X[k]: 3073 X 1 else: dW[:, i] += X[k] * probabilities[i] loss += -np.log(probabilities[y[k]]) # Right now the loss is a sum over all training examples, but we want it # to be an average instead so we divide by num_train. loss /= num_train dW /= num_train dW += reg*W # regularize the weights # Add regularization to the loss. loss += 0.5 * reg * np.sum(W * W) return loss, dW