cs231n作業一之實現SVM
阿新 • • 發佈:2019-02-09
這個程式碼不能在python熵執行,是官方給的程式碼,我只是按照我的意思理解了一下,並把自己的理解寫上去,如果想要找能執行的程式碼的同學請忽視,如果你找到了也可以和我分享
import numpy as np from random import shuffle def svm_loss_naive(W, X, y, reg): """ Structured SVM loss function, naive implementation (with loops). Inputs have dimension D, there are C classes, and we operate on minibatches of N examples. Inputs: - W: A numpy array of shape (D, C) containing weights. - X: A numpy array of shape (N, D) containing a minibatch of data. - y: A numpy array of shape (N,) containing training labels; y[i] = c means that X[i] has label c, where 0 <= c < C. - reg: (float) regularization strength Returns a tuple of: - loss as single float - gradient with respect to weights W; an array of same shape as W """ dW = np.zeros(W.shape) # 初始化梯度為零 # compute the loss and the gradient num_classes = W.shape[1] num_train = X.shape[0] loss = 0.0 for i in xrange(num_train): scores = X[i].dot(W)#做點乘 correct_class_score = scores[y[i]]#最後的得分 for j in xrange(num_classes): if j == y[i]: continue margin = scores[j] - correct_class_score + 1 #svm損失函式,Li=max(0,Sj-Syi+1)只要j!=yi if margin > 0: loss += margin#取最大值 dW[:,j] += X[i].T dW[:,y[i]] += -X[i].T # 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#梯度的平均值 # 在損失中增加正規化。 loss += 0.5 * reg * np.sum(W * W) dW += reg * W ############################################################################# # TODO: # # Compute the gradient of the loss function and store it dW.損失函式的梯度 # # Rather that first computing the loss and then computing the derivative, # # it may be simpler to compute the derivative at the same time that the # # loss is being computed. As a result you may need to modify some of the # # code above to compute the gradient. # ############################################################################# return loss, dW 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) #初始化梯度為零 ############################################################################# # TODO: # # Implement a vectorized version of the structured SVM loss, storing the # # result in loss. # ############################################################################# num_train = X.shape[0] num_classes = W.shape[1] scores = X.dot(W)#WX correct_class_scores = scores[range(num_train), list(y)].reshape(-1,1) #(N, 1) margins = np.maximum(0, scores - correct_class_scores +1) margins[range(num_train), list(y)] = 0 loss = np.sum(margins) / num_train + 0.5 * reg * np.sum(W * W) #pass ############################################################################# # 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. # ############################################################################# coeff_mat = np.zeros((num_train, num_classes)) coeff_mat[margins > 0] = 1 coeff_mat[range(num_train), list(y)] = 0 coeff_mat[range(num_train), list(y)] = -np.sum(coeff_mat, axis=1) dW = (X.T).dot(coeff_mat) dW = dW/num_train + reg*W #pass ############################################################################# # END OF YOUR CODE # ############################################################################# return loss, dW