CS231N assignment 1 KNN

cs231n 的作業一直寫寫停停,實在是太對不起自己了,其實作業還是挺有意思的
自己用conda create先創建了一個虛擬環境,pytorch36,鏈接到jupyter-notebook的kernel
具體配置jupyter的kernel以後有空再整理

1. knn.ipynb

knn的作業有兩個目的,一個是弄明白numpy的broadcast機制,第二個是嘗試交叉驗證。
from cs231n.classifiers import KNearestNeighbor
表明我們要寫的這個分類器的位置
KNN算法的原理:
1.計算所有測試樣本和訓練樣本之間的l2距離,就是平方和開方 dists = ((num_test, num_train))
2.對於每個測試樣本的距離,挑選出最近的k個,然後統計裏面最多的label,即爲最終的label

命題點1 numpy broadcast

計算距離矩陣用了三種方法,分別是兩次循環,一次循環和沒有循環
兩次循環
就是最簡單的窮舉法,距離矩陣中行和列中的每個元素都計算一遍

    for i in range(num_test):
      for j in range(num_train):
        dists[i,j]=np.sqrt(np.sum((X[i]-self.X_train[j])**2))

一次循環
每次計算一行距離, 這裏test的X[i] 是一個數據,shape是(3072,),X_train 則是一批數據(5000,3072)
兩者的維度不同,怎麼可以相減呢,這就是numpy的broad cast機制。從最後一維對齊3072對3072,然後向前傳播。得到一個(5000,3072)的兩個矩陣計算距離,最後得到(5000,)

    for i in range(num_test):
      dists[i,:] = np.sqrt(np.sum((X[i] - self.X_train)**2,1))

沒有循環
(5000,3072)和(500,3072) 沒法相減,這可怎麼辦呢,那我們只好把平方公式拆開了
具體如下

    dists += np.sum((self.X_train**2),1).reshape(1,num_train)
    dists += np.sum((X**2),1).reshape(num_test,1) #reshape for broadcast
    dists -= 2*np.dot(X,self.X_train.T)
    dists = np.sqrt(dists)

藉助numpy的argsort函數對距離進行排序, 找出最近的k個距離
np.argsort :Returns the indices that would sort an array.

命題點2 k折交叉驗證

分割數據集

X_train_folds = [np.array_split(X_train,num_folds)[i] for i in range(num_folds)]
y_train_folds = [np.array_split(y_train,num_folds)[i] for i in range(num_folds)]

循環k次訓練過程

    for i in range(num_folds): #循環i次
        classifier.train(np.delete(np.array(X_train_folds),i,0).reshape(-1,X_train.shape[1])
                         ,np.delete(np.array(y_train_folds),i,0).reshape(-1)) # 從訓練數據中刪除第i折的數據
        print(i)
        y_pred=classifier.predict(X_train_folds[i],k)  
        acc=np.equal(y_pred,y_train_folds[i]).sum()/y_train_folds[i].shape[0]      
        acc_list.append(acc)

參考

cs231n 主頁
別人的代碼參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章