svm-loss 關於權重矩陣W的導數(cs231n Assignment 1)
先給出相應習題的代碼,各位可以自行領會一下:
def svm_loss_vectorized(W, X, y, reg):
"""
Structured SVM loss function, vectorized implementation.
Inputs and outputs are the same as svm_loss_naive.
"""
loss = 0.0
dW = np.zeros(W.shape) # initialize the gradient as zero
scores = X.dot(W)
num_train = X.shape[0]
num_type = W.shape[1]
print(num_type)
#############################################################################
# TODO: #
# Implement a vectorized version of the structured SVM loss, storing the #
# result in loss. #
#############################################################################
correct_scores = scores[range(num_train), y].reshape(-1, 1)
pre_loss = scores + 1 - correct_scores
loss = (np.sum(np.maximum(pre_loss, 0)) - num_train) / num_train + reg * np.sum(W * W)
#############################################################################
# END OF YOUR CODE #
#############################################################################
#############################################################################
# TODO: #
# Implement a vectorized version of the gradient for the structured SVM #
# loss, storing the result in dW. #
# #
# Hint: Instead of computing the gradient from scratch, it may be easier #
# to reuse some of the intermediate values that you used to compute the #
# loss. #
#############################################################################
mask = np.ones(scores.shape)
cnt = pre_loss > 0
mask[range(num_train), y] = 1 - np.sum(cnt, axis = 1)
dW = X.T.dot(mask * (pre_loss > 0)) / num_train + 2 * reg * W
#############################################################################
# END OF YOUR CODE #
#############################################################################
return loss, dW
本題是cs231n Assignment 1中關於svm-loss向量化方法的一個思路,並不是嚴格的數學證明。
首先給出SVM-loss的表達式
設輸入矩陣爲
其中
設
關於svm-loss函數此處不再贅述,詳細請參加CS231n的課程內容
在CS231n 的Assignment 1中要求向量化svm-loss函數對於權重矩陣W的導數, 即
這裏我們將
且對於該
max函數不方便處理,所以我們考慮消去max,由於
展開
下面我們就可以比較方便的求導了,考慮
對於
可以觀察到等式右邊的行向量實際上是
於是我們得到了一個
事實上
剩下的問題就是如何計算
觀察到L矩陣的每一項都有1,我們初始化mask矩陣爲np.ones([D, C])
接下來就是矩陣中每個entry中導數部分的計算了
首先,我們可以利用broadcast計算出矩陣
correct_scores = scores[range(num_train), y].reshape(-1, 1)
pre_loss = scores + 1 - correct_scores
pre_lost > 0就可以作爲bool矩陣表示條件
下面計算每一行的l值,實際上每一行的l的意義就是每一行中pre_lost>0矩陣中爲True的元素個數,利用np.sum函數對pre_lost>0的每行進行加和就可得到。
mask矩陣與dW計算代碼爲:(別忘了L2 Regularization部分的導數)
mask = np.ones(scores.shape)
cnt = pre_loss > 0
mask[range(num_train), y] = 1 - np.sum(cnt, axis = 1)
dW = X.T.dot(mask * (pre_loss > 0)) / num_train + 2 * reg * W
大晚上敲完這篇筆記或許漏洞百出,請各位讀者見諒,改日再仔細檢查一下,如有錯誤懇請指正。