CS231N—KNN assignment1

KNN前导知识

KNN(K-最近邻分类器,K-Nearest Neighbor)是一种较为简单的经典分类算法。

算法主要思路

对于输入的每一张测试图像,与分类器中储存的每一张训练图像分别计算一次距离,这个距离可以是L1 distance(曼哈顿距离)或者是L2 distance(欧式距离)等。

假设分类器中储存了 j 张训练图像,则对于每一张测试图像,总共会产生 j 个距离(对应每一张训练图像)。将这 j 个距离从小到大排序,并取最小的前 K 个距离,认为这 K 张训练图像与输入的测试图像最相似。然后对这 K 张图像的所属类别进行计数(可能有两张是狗,三张是猫),取出现次数最多的类别作为这张测试图像的类别(即出现三次的猫)。

L1 distance(曼哈顿距离)

L 1 − d i s t a n c e = ∣ x 1 − x 1 ∣ + ∣ y 1 − y 1 ∣ L1-distance=\left | x_{1} - x_{1} \right | +\left | y_{1} - y_{1} \right | L1distance=x1x1+y1y1

L2 distance(欧氏距离)

L 2 − d i s t a n c e = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 L2-distance=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2} L2distance=(x1x2)2+(y1y2)2

K值的选定

K值过小容易导致模型过拟合,而K值过大可能导致模型的近似误差增大。因此可以通过尝试多组K值来选定最适合当前问题的K值。

代码实现

compute_distances_no_loops()

该函数最关键的一步是对于欧式距离计算的拆分与简化,拆分步骤如下所示:
d i s t a n c e ( t e s t [ i ] , t r a i n [ j ] ) = ∑ k ( t e s t [ i ] [ k ] − t r a i n [ j ] [ k ] ) 2 distance(test[i],train[j]) = \sqrt{\sum_{k}^{} (test[i][k]-train[j][k])^{2} } distance(test[i],train[j])=k(test[i][k]train[j][k])2
= ∑ k t e s t [ i ] [ k ] 2 + ∑ k t r a i n [ j ] [ k ] 2 − 2 × t e s t [ i ] [ k ] × t r a i n [ j ] [ k ] =\sqrt{\sum_{k}^{}test[i][k]^{2}+\sum_{k}^{}train[j][k]^{2}-2\times test[i][k]\times train[j][k]} =ktest[i][k]2+ktrain[j][k]22×test[i][k]×train[j][k]
其中,test[i]表示测试集中的第i张图像,test[i][k]表示测试集中第i张图像的第k个像素点(在之前已经将所有像素点伸展为一行)。
我们再将test和train看为一个整体,则可以进一步简化公式为:
d i s t a n c e ( t e s t , t r a i n ) = ( ∑ k t e s t [ : , k ] ) 2 + ( ∑ k t r a i n [ : , k ] ) 2 − 2 × t e s t × t r a i n distance(test,train)=\sqrt{(\sum_{k}^{}test[:,k])^{2}+(\sum_{k}^{}train[:,k])^{2}-2\times test\times train} distance(test,train)=(ktest[:,k])2+(ktrain[:,k])22×test×train
可能你会迷惑两个不同大小的矩阵怎么实现相加,这就是Python的强大之处,后部分的代码会详细讲解,因此实现代码如下所示:

test_square = np.expand_dims(np.square(X).sum(axis = 1), axis = 1)
train_square = np.expand_dims(np.square(self.X_train).sum(axis = 1), axis = 0)
dists = np.sqrt(test + train - 2 * test.dot(train.T))

np.sum()的操作会把test和train分别变为长度为500和长度为5000的列表,而接下去的np.expand_dims()操作又分别将他们变为500×1和1×5000的列向量和行向量。在Python中,将这两个向量相加的操作是将列向量扩充到500×5000,将行向量也扩充到500×5000,再进行相加。此时就实现了所有distance的同时计算(可以自己动手画个向量扩充相加一下试试)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值