cs231n_assignment1_KNN(2016版)

准备工作

  网上已经有很多关于cs231n作业的讲解和code,所以这里的大多东西都是借鉴他人的成果,但对于个人,一步步的去实现程序比只看代码更能提升能力。本文将会关注KNN分类器在编程实现中的种种问题。

 在这篇知乎专栏可以查看cs231n课程的所有笔记资料(中文版)https://zhuanlan.zhihu.com/p/21930884,找到assignment1,下载相应的代码和数据集,我使用的是windows系统,IDE:Pycharm,根据作业建议安装了anaconda。pip安装相应的第三方库。

  assignment1中的.ipynb文件能很好的引导你完成作业,同时.ipynb交互式编程也方便重复调试,pip install jupyter后,pycharm就能运行.ipynb文件。


KNN_Classifier

  找到knn.ipynb, jupyter 将每段代码分为一个cell,这样有利于单独调试函数。一路run下来,本次作业重点是实现KNN算法,不关注诸如CIFAR10数据集的读入、图形的绘制等问题。

  使用两层循环来计算x_test与x_train的距离是容易的,注意求和函数是np.sum


Compute the distance between each test point in X and each training point
in self.X_train using a nested loop over both the training data and the 
test data.

Inputs:
- X: A numpy array of shape (num_test, D) containing test data.

Returns:
- dists: A numpy array of shape (num_test, num_train) where dists[i, j]
  is the Euclidean distance between the ith test point and the jth training
  point.
"""
num_test = X.shape[0]
num_train = self.X_train.shape[0]
dists = np.zeros((num_test, num_train))
for i in xrange(num_test):
  for j in xrange(num_train):
    #####################################################################
    # TODO:                                                             #
    # Compute the l2 distance between the ith test point and the jth    #
    # training point, and store the result in dists[i, j]. You should   #
    # not use a loop over dimension.                                    #
    #####################################################################
    
    dists[i][j] = np.sqrt(np.sum((X[i] - self.X_train[j]) ** 2))
    #####################################################################
    #                      # END OF YOUR CODE                            #
    ##################################################################

  predict_labels,分为两步,第一使用包含距离的矩阵找到k个近邻,再标识出k个紧邻的label;第二,将K个label中出现次数最多的标记为当前x_test的label。

  第一步,使用np.argsort()函数对每行距离排序并返回索引值,取前K个值,根据索引值找到对应的lable。

  第二步,使用np.bincount()和np.argmax()函数,其中

#  bincount(x, weights=None, minlength=0)
#  Count number of occurrences of each value in array of non-negative ints. 按顺序返回count number
#a=[1,2,3,3,3,4,5,6]
#np.bincount(a)
# array([0, 1, 1, 3, 1, 1, 1], dtype=int64)

#argmax(a, axis=None, out=None)
#Returns the indices of the maximum values along an axis.
   
one_loop的编写使用到numpy中broadcast的性质,向量[i,:]的写法,np.sum(axis)

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

     
   no_loop的编写主要将距离公式中的平方换成      (a2-2ab+b2)的形式,同样使用到broadcast性质,reshape也可用np.sum(keepdims=Ture)代替

dists += np.sum(X ** 2 ,axis=1).reshape(num_test,1)
dists += np.sum(self.X_train ** 2 ,axis=1)
dists -= 2 * np.dot(X,self.X_train.T)
dists = np.sqrt(dists)
  KNN核心代码就此完成,两层循环,一层循环,无循环都是使用numpy的矩阵操作,使用循环利于理解图像距离的计算过程,无循环则大大提升计算速度。

  PS:作业中使用交叉检验来验证KNN识别率,其中使用到     numpy.array_split(X,n)方法,其将长度为L的数组X分为n个子数组,包括L%n个长度为(L//n)+1和剩余的长度为L//n的数组

  



  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值