CS231N assignment 1 KNN

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013608336/article/details/82856184

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 主页
别人的代码参考

猜你喜欢

转载自blog.csdn.net/u013608336/article/details/82856184