搭建基于K近邻的图像识别系统

本文介绍了基于K近邻(KNN)的图像识别系统搭建,探讨了图像识别背景知识,包括图像读取、表示和降维。通过PCA进行特征降维,改善KNN算法在高维数据上的性能。此外,还讨论了KNN的超参数选择,如K值和距离度量。最后,对比了KNN与神经网络在图像识别中的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 图像识别背景知识

1.1 图像识别任务描述

图像识别的应用场景特别多,比如人脸识别、物体识别、监控视频里的异常检测、无人驾驶等,其核心技术都来自于图像识别。
目前对于图像识别任务,最有效的方法是使用深度学习,比如卷积神经网络。但实际上,我们也可以通过其他简单的算法如KNN来识别图片,只不过比起卷积神经网络效果会差一些。
图像本身是一个非结构化的数据,而且非结构化数据本身是不能直接用来做模型输入的。

1.2 图像的读取以及表示

那什么是非结构化数据呢? 简单来讲,文本、图片、声音、视频这些都属于非结构化数据,需要做进一步的处理。相反, 结构化的数据指的是存放在数据库里的年龄,身高等这种信息。
对于图像来说,此过程相对简单。一般可以通过Python自带的库来读取图片,并把图片数据存放在矩阵(Matrix)或者张量(Tensor)里。
图片是由像素来构成的,比如256×256或者128×128。两个值分别代表长宽上的像素。这个值越大图片就会越清晰。另外,对于彩色的图片,一个像素点一般由三维数组来构成,分别代表的是R,G,B三种颜色。除了RGB,其实还有其他常用的色彩空间。如果使用RGB来表示每一个像素点,一个大小为128×128像素的图片实际大小为128×128×3,是一个三维张量的形式。

import matplotlib.pyplot as plt

# 读取图片的数据,存放到img
img = plt.imread("/home/anaconda/data/RGZNXLY/ch3/sample.jpg")
print(img.shape)
plt.imshow(img)
(347, 335, 3)

在这里插入图片描述

1.3 降维及图片的特征

图像识别工作中需要考虑的点:

  • 从不同视角拍摄同一个物体
  • 主要的物体被部分覆盖
  • 图片的亮度
  • 同一个物体可以有不同的形状

问题:假如我们直接读取图片里的数据,然后再通过KNN算法来识别图片,那这种方案是否能考虑到上面提到的几点呢?
很显然是不可以的。
KNN模型的核心是计算距离。假设我们把图片转换成数据,之后无非就是计算两个矩阵/张量之间的距离罢了,这很明显不会考虑到以上几个问题,这也是为什么KNN这种方式得出来的效果并不是特别好的主要原因。
常用的图片特征:

  • 颜色特征(最常用的是颜色直方图(color histogram))
  • SIFT特征(一个局部的特征,它会试图去寻找图片中的拐点这类的关键点,然后再通过一系列的处理最终得到一个SIFT向量)
  • HOG(通过计算和统计图像局部区域的梯度方向直方图来构建特征)

由于HOG是在图像的局部方格单元上操作,所以它对图像几何的和光学的形变都能保持很好的不变性。
对于一个中小型图片,它的大小一般大于256×256×3。如果把它转换成向量,其实维度的大小已经几十万了。这会导致消耗非常大的计算资源,所以一般情况下我们都会尝试对图片做一些降维操作。其实特征提取过程我们自然地可以理解为是降维过程。

除了特征提取之外,我们还有一种常用的降维工具叫做PCA(Principal Component Analysis), 它是一种无监督的学习方法,可以把高维的向量映射到低维的空间里。它的核心思路是对数据做线性的变换,然后在空间里选择信息量最大的Top K维度作为新的特征值。

二 搭建基于Knn的图像识别系统

在这个项目里, 需要完成一个图像识别的任务,主要使用的模型是KNN算法。使用的数据集是cifar-10,是图像识别领域最为经典的数据集之一。具体的数据可以从以下的链接下载: http://www.cs.toronto.edu/~kriz/cifar.html, 下载之后把是数据集解压在当前的工程的根目录下。

该项目主要做了如下几个方面的工作:

  • 读取图片文件、展示图片、并做部分采样。采样的原因主要是为了节省训练的时间,因为我们知道KNN的搜索复杂度为O(N),何况图片也属于高维的数据,这也会增加搜索效率。
  • 使用KNN算法识别图片。在这里,需要使用K折交叉验证来选择最适合的超参数。
  • 使用PCA技术先给图片做降维,然后在使用KNN来识别图片。 另外,使用PCA把图片降维到2维度空间里,这时候相当于我们得到了每一个图片在(x,y)轴上的坐标。之后把采样过的一些图片在二维空间里根据每个坐标点来展示一下。
  • 给每一个图片抽取两个经典的特征,color historgram和HOG, 抽取完之后再通过KNN来训练。
  • 基于第四步,换成神经网络模型去识别。

在机器学习的上下文中,超参数是在开始学习过程之前设置的参数。
超参数的一些示例:

  • 树的数量或树的深度
  • 矩阵分解中潜在因素的数量
  • 学习率(多种模式)
  • 深层神经网络隐藏层数
  • k均值聚类中的簇数
2.1 文件的读取、可视化、以及采样
# 文件的读取,我们直接通过给定的`load_CIFAR10`模块读取数据。 
from load_data import load_CIFAR10   # load_data为用于读取数据的脚本文件,不必要担心如何写读取的过程。
import numpy as np
import matplotlib.pyplot as plt

cifar10_dir = 'cifar-10-batches-py'  # 定义文件夹的路径

# 清空变量,防止重复导入多次。 
try:
   del X_train, y_train
   del X_test, y_test
   print('清除之前导入过的变量...Done!')
except:
   pass

# 读取文件,并把数据保存到训练集和测试集合。  
X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)
# 先来查看一下每个变量的大小,确保没有任何错误!X_train和X_test的大小应该为 N*W*H*3
# N: 样本个数, W: 样本宽度 H: 样本高度, 3: RGB颜色。 y_train和y_test为图片的标签。
print ("训练数据和测试数据:", X_train.shape, y_train.shape, X_test.shape, y_test.shape)
print ("标签的种类: ", np.unique(y_train)) # 查看标签的个数以及标签种类,预计10个类别。
训练数据和测试数据: (50000, 32, 32, 3) (50000,) (10000, 32, 32, 3) (10000,)
标签的种类:  [0 1 2 3 4 5 6 7 8 9]

从训练数据抽取50个样本(每一个类别中随机抽取5个样本),并做可视化

classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
num_classes = len(classes)  # 样本种类的个数
samples_per_class = 5       # 每一个类随机选择5个样本

plt.figure(figsize=(10,6))

for col in range(num_classes):
    # 随机抽取第col类的5个样本
    i_class_samples = X_train[np.random.choice(np.argwhere(y_train == col).ravel(),samples_per_class,replace=False)] # 不放回采样
    # 循环绘制第col类的这5个样本图片
    for row in range(samples_per_class):
        # 定位当前画板的对应位置子图
        plt.subplot(samples_per_class, num_classes, (num_classes * row + col + 1))
        # 在当前位置子图上绘制对应的样本图片
        plt.imshow(i_class_samples[row]/255)
        # 给各个类别的第一个图片加上标题
        if row == 0:
            plt.title(classes[col])
        plt.axis("off") # 不显示坐标轴
plt.savefig('./图片1')

在这里插入图片描述
检查样本是否均衡

# 统计并展示每一个类别出现的次数
from collections import Counter

# 使用Counter统计各个类别下标出现次数
count_result = Counter(y_train)
# 对统计结果按类别下标排序,并拆分为横坐标与纵坐标序列
count_plot_result = list(zip(*sorted(count_result.items())))
count_plot_result
[(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
 (5000, 5000, 5000,<
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值