2、最近邻分类器
接下来我们来开发一个图像分类器:最近邻分类器。这个分类器在实践中很少用,但是可以让我们对数据驱动的图像分类方法有一个概念性的理解。
图像分类样例数据集:CIFAR-10,这是一个有名的图像分类数据集。包含6万张32X32像素的小图,每张图片都标记为10个分类中的某一个(比如airplane, automobile, bird,等等)。这6万张图片已经分为两组,训练数据5万张,测试数据1万张。下面为每个分类随机展示了10张图片:
左边: CIFAR-10 数据集中的样例数据。右边: 第一列是测试数据,我们每张测试图片给出了最近邻的10张图像
假设我们拿到这5万张CIFAR-10训练图像(每个分类5千张),我们希望去标记剩余的1万张图像。最近邻分类器拿到一张测试图像,会用这张图去与每一张训练图像做比较,用最近距离的训练图片来预测这张图所属的分类。
如何比较两张图片,就是这两组32 x 32 x 3的数据是怎么比较的?一个简单的办法就是一个一个地比较像素点数据,然后将所有的差异求和。将两张图片分别表示为两个向量I1,I2,要比较这两个向量,L1 距离就是一个合理的选择:
其中求和是计算所有的像素的差异的绝对值之和。如下图所示:
用像素差异计算两张图片L1距离的样例(这里只计算了一个颜色通道)。计算对应像素点的差异绝对值,然后求和这些绝对值。如果两张图片完全一致,则和为零。差异越大则这个和就越大。
下面是一个简单的最近邻分类器的实现,使用L1距离
测试代码:
运行这段代码得到的准确率达到38.6%。这比随机猜测好一点(因为有10个类,乱猜也能获得10%的准确度),但是远不及人类的性能(估计在94%左右)或最先进的卷积神经网络,达到约95%。
距离计算:计算向量间距离有很多方法。还有一种是计算L2距离,这种方法计算特征之间差异的平方和,然后再求平方根:
用numpy计算L2距离也很简单,这样即可: distances = np.sqrt(np.sum(np.square(self.Xtr - X[i,:]), axis = 1))
这里用到了平方根函数,在实际的最近邻居应用程序中,可以省去平方根运算,因为平方根是单调函数,算不算对排序没有影响。如果你用这个距离测试上述最近邻居分类器,你将获得35.4%的精度(略低于我们的L1距离结果)。
L1与L2:这两个度量之间的差异有点意思。当涉及两个向量之间的差异时,L2距离比L1距离更不宽容。也就是说,L2距离倾向于放大差异。L1和L2距离(或相当于一对图像之间的差异的L1/L2范数)是p范数中最常用的特殊情况。
下一章 K-最近邻分类器及如何计算超参数
斯坦福大学计算机视图课程,青星大学 翻译整理