svm训练完保存权重_assignment1-SVM
理論知識
這次的分類器要比之前的KNN更加得靈活,效果也會更好。這種方法主要有兩部分組成:一個是評分函數(shù)(score function),它是原始圖像數(shù)據(jù)到類別分值的映射。另一個是損失函數(shù)(loss function),它是用來量化預(yù)測分類標(biāo)簽的得分與真實(shí)標(biāo)簽之間一致性的。該方法可轉(zhuǎn)化為一個最優(yōu)化問題,在最優(yōu)化過程中,將通過更新評分函數(shù)的參數(shù)來最小化損失函數(shù)值。
評分函數(shù)可以表示為:
對于
,可以看下面的圖片:當(dāng)然更好的方法是把W和b合并:
的選取也有很多,這里看做對 不做處理。評分函數(shù)在正確的分類的位置應(yīng)當(dāng)?shù)玫阶罡叩脑u分(score)。使用損失函數(shù)(Loss Function)(有時也叫代價函數(shù)Cost Function或目標(biāo)函數(shù)Objective)來衡量我們對結(jié)果的不滿意程度。直觀地講,當(dāng)評分函數(shù)輸出結(jié)果與真實(shí)結(jié)果之間差異越大,損失函數(shù)輸出越大,反之越小。
損失函數(shù)的形式很多,這里使用的是SVM損失函數(shù)。
對于第j個類別的得分為
,針對第i個數(shù)據(jù)的多分類SVM的損失函數(shù)定義如下:SVM的損失函數(shù)想要正確分類類別
的分?jǐn)?shù)比不正確類別分?jǐn)?shù)高,而且至少要高。如果不滿足這點(diǎn),就開始計(jì)算損失值。那么根據(jù)之前的評分函數(shù),最終的損失函數(shù)為:
被稱為折葉損失(hinge loss)正則化(Regularization):課程中是這么解釋的,由于使所有樣本都能正確分類的
并不唯一,可能有很多相似的W都能夠正確地分類所有數(shù)據(jù),比如對于每個數(shù)據(jù),損失值都為0,那么對于 時,任何 都可以使損失值為0。那么哪個 最好呢?正則化的想法就是向某些特定的權(quán)重W添加一些偏好,對其他權(quán)重則不添加,以此來消除這種模糊性。常用的正則化懲罰是L2范數(shù):
可以看出,對于比較大的權(quán)重,它可以使其損失函數(shù)更大,從而抑制大數(shù)值的權(quán)重。
我的理解是:在訓(xùn)練完后發(fā)現(xiàn)了過擬合,那么此時雖然訓(xùn)練集的損失很小了,但是還不是最好的W,所以要調(diào)整W,W還有偏好的含義,越大表示對某個特征反應(yīng)越激烈,而較大的W在預(yù)測中往往有著決定性的作用,所以要降低這些權(quán)重,對大數(shù)值進(jìn)行懲罰,來讓分類器把所有維度上的特征都利用起來,從而提升其泛化能力。
最后的loss如下:
不想再輸公式了。。。算法實(shí)現(xiàn)
整個線性分類器的設(shè)計(jì)過程總結(jié)如下:
算法框架如下:
class LinearClassifier(object):def __init__(self):self.W = Nonedef train(self, X, y, learning_rate=1e-3, reg=1e-5, num_iters=100,batch_size=200, verbose=False):passreturn loss_historydef predict(self, X):passreturn y_preddef loss(self, X_batch, y_batch, reg):pass class LinearSVM(LinearClassifier):""" A subclass that uses the Multiclass SVM loss function """def loss(self, X_batch, y_batch, reg):return svm_loss_vectorized(self.W, X_batch, y_batch, reg)因?yàn)椴煌瑩p失函數(shù)的train和predict的代碼是相同的,所以作業(yè)中使用了繼承來復(fù)用這些代碼,以后只需要寫loss的代碼即可。
train代碼實(shí)現(xiàn):
def train(self, X, y, learning_rate=1e-3, reg=1e-5, num_iters=100,batch_size=200, verbose=False):num_train, dim = X.shapenum_classes = np.max(y) + 1 # 這里用 0...K-1 來表示不同的標(biāo)簽#權(quán)重初始化,使用小隨機(jī)數(shù)if self.W is None:# lazily initialize Wself.W = 0.001 * np.random.randn(dim, num_classes)#使用GD進(jìn)行W的優(yōu)化loss_history = []for it in range(num_iters):X_batch = Noney_batch = Nonenum_train = X.shape[0]batch_indices = np.random.choice(num_train, batch_size)X_batch = X[batch_indices]y_batch = y[batch_indices]loss, grad = self.loss(X_batch, y_batch, reg)loss_history.append(loss)self.W -=learning_rate*gradif verbose and it % 100 == 0:#用于觀察loss的情況print('iteration %d / %d: loss %f' % (it, num_iters, loss))return loss_history這里說明下batch_size,epoch的區(qū)別。
當(dāng)一個完整的數(shù)據(jù)集通過了分類器一次并且完成了一次梯度更新,這個過程稱為一個epoch。然而,當(dāng)一個 epoch 對于計(jì)算機(jī)而言太龐大的時候,就需要把它分成多個小塊。分成的塊數(shù)就是batch的數(shù)量,每一個batch的大小就為batchsize。現(xiàn)在變成了每一個batch進(jìn)行一次梯度更新。batch_size和梯度下降也有一定關(guān)系:
批量梯度下降(BGD)。batch_size=訓(xùn)練集的大小
隨機(jī)梯度下降(SGB)。batch_size= 1
小批量梯度下降(MBGD)。1 <batch_size<訓(xùn)練集的大小
predict的代碼實(shí)現(xiàn):
def predict(self, X):y_pred = np.zeros(X.shape[0])y_pred = np.argmax(X.dot(self.W),axis=1)return y_predsvm_loss_vectorized的實(shí)現(xiàn):
def svm_loss_vectorized(W, X, y, reg):loss = 0.0dW = np.zeros(W.shape) # initialize the gradient as zeroscores = X.dot(W) # N by Cnum_train = X.shape[0]num_classes = W.shape[1]#計(jì)算loss#numpy的這種技巧要記牢啊scores_correct = scores[np.arange(num_train), y] #1 by Nscores_correct = np.reshape(scores_correct, (num_train, 1)) # N by 1margins = scores - scores_correct + 1.0 # N by Cmargins[np.arange(num_train), y] = 0.0 margins[margins <= 0] = 0.0loss += np.sum(margins) / num_trainloss += 0.5 * reg * np.sum(W * W)#計(jì)算梯度margins[margins > 0] = 1.0 # 示性函數(shù)的意義row_sum = np.sum(margins, axis=1) # 1 by Nmargins[np.arange(num_train), y] = -row_sum dW += np.dot(X.T, margins)/num_train + reg * W # D by Creturn loss, dW(關(guān)于loss和梯度計(jì)算的實(shí)現(xiàn)想專門總結(jié)下)
訓(xùn)練集和驗(yàn)證集的正確率為:
調(diào)優(yōu)
這次直接使用驗(yàn)證集來進(jìn)行調(diào)整學(xué)習(xí)率和正則化系數(shù),具體代碼如下:
learning_rates = [1e-7,5e-5] regularization_strengths = [2.5e4,5e4] #對于每一個超參數(shù)集合,用訓(xùn)練集訓(xùn)練一個SVM,計(jì)算訓(xùn)練集和驗(yàn)證集的準(zhǔn)確率,并存放在 #result字典中,存放最好的驗(yàn)證集準(zhǔn)確率在best_val中,最好的模型放在best_svm中 #result中是(learning_rate, regularization_strength):(training_accuracy, validation_accuracy) results = {} best_val = -1 best_svm = None for lr in learning_rates:for rs in regularization_strengths:svm = LinearSVM()loss_hist = svm.train(X_train, y_train, learning_rate=lr, reg=rs,num_iters=500, verbose=False)#num_iters設(shè)為500,調(diào)高查找速度y_train_pred = svm.predict(X_train)train_accuracy = np.mean(y_train == y_train_pred)y_val_pred = svm.predict(X_val)validation_accuracy = np.mean(y_val == y_val_pred)results[(lr,rs)] = (train_accuracy,validation_accuracy)if best_val < validation_accuracy:best_svm = svmbest_val = validation_accuracy # Print out results. for lr, reg in sorted(results):train_accuracy, val_accuracy = results[(lr, reg)]print('lr %e reg %e train accuracy: %f val accuracy: %f' % (lr, reg, train_accuracy, val_accuracy)) print('best validation accuracy achieved during cross-validation: %f' % best_val)正確率與超參數(shù)的關(guān)系如下:
在原有的數(shù)量上又增加了一些取值左上方的顏色為深紅色,表明準(zhǔn)確率最高。學(xué)習(xí)率為1e-7 ,正則化系數(shù)為 5e4,驗(yàn)證集上的準(zhǔn)確率為38%左右。
之后要注意的是在對測試集進(jìn)行預(yù)測之前,要把num_iters調(diào)到較大的值,這里是1500,來更好地優(yōu)化W。最后測試集的準(zhǔn)確率為37%左右。
作業(yè)中還把權(quán)重矩陣中各個類別的權(quán)重繪圖,結(jié)果如下:
可以發(fā)現(xiàn),SVM分類器是在進(jìn)行著模板匹配的工作。
一些問題:
1.多類SVM損失函數(shù)的最大/最小值是多少?
最小值:0 最大值:無窮大
2.如果初始化時w和b很小,損失L會是多少?
設(shè)標(biāo)簽數(shù)為n,單個樣本的L為n-1。這可以驗(yàn)證編碼是否正確
3.考慮所有類別(包括j=yi),損失Li會有什么變化?
會比原來多1
4.在求總損失L計(jì)算時,如果用求和代替平均?
沒有什么影響,可以調(diào)學(xué)習(xí)率
5.如果使用
會使損失值變很大,對最終的效果有影響。
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的svm训练完保存权重_assignment1-SVM的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 五行塔怎么吃第五个_中医美容——“五行美
- 下一篇: 不挂载 组件渲染_让你的 React 组