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

你即将要完成的几个任务是:

  1. 读取图片文件、展示图片、并做部分采样。采样的原因主要是为了节省训练的时间,因为我们知道KNN的搜索复杂度为O(N),何况图片也属于高维的数据,这也会增加搜索效率。
  2. 使用KNN算法识别图片。在这里,我们需要使用K折交叉验证来最适合的超参数。
  3. 使用PCA技术先给图片做降维,然后在使用KNN来识别图片。 另外,使用PCA把图片降维到2维度空间里,这时候相当于我们得到了每一个图片在(x,y)轴上的坐标。之后把采样过的一些图片在二维空间里根据每个坐标点来展示一下。
  4. 给每一个图片抽取两个经典的特征,color historgramHOG, 抽取的过程已经给你写好。抽取完之后再通过KNN来训练。
  5. 基于第四步,换成神经网络模型去识别。虽然还没有讲到神经网络,但根据提前给定的参数设置并结合sklearn的文档,完全可以去实现一个神经网络模型。

1. 文件的读取、可视化、以及采样

在这部分我们需要读取图片文件,并展示部分图片便于观察,以及做少量的采样。

  1. 文件的读取: 读取部分的代码已经提供,你只需要调用一下即可以读取图片数据。
  2. 可视化: 选择其中的一些样本做可视化,也就是展示图片的内容以及它的标签。
  3. 采样:统计一下各类出现的个数以及采样部分样本作为后续的模型的训练。
# 文件的读取,直接通过给定的`load_CIFAR10`模块读取数据。
from load_data import load_CIFAR10
import numpy as np
import matplotlib.pyplot as pltcifar10_dir = 'cifar-10-batches-py'  # 清空变量,防止重复导入多次。
try:del X_train, y_traindel X_test, y_testprint('清除之前导入过的变量...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个类别。classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
num_classes = len(classes)  # 样本种类的个数
samples_per_class = 5       # 每一个类随机选择5个样本# plt.subplot函数以及 plt.imshow函数用来展示图片for y,cls in enumerate(classes):idxs = np.flatnonzero(y_train==y)idxs = np.random.choice(idxs,samples_per_class,replace=False)for i,idx in enumerate(idxs):plt_idx = i * num_classes + y + 1plt.subplot(samples_per_class,num_classes,plt_idx)plt.imshow(X_train[idx].astype('uint8'))plt.axis('off')if i == 0:plt.title(cls)
plt.show()

number_of_each_class=[]
for y,cls in enumerate(classes):idxs = np.flatnonzero(y_train==y)number_of_each_class.append(len(idxs))
plt.plot(classes,number_of_each_class)
plt.show()# 随机采样训练样本5000个和测试样本500个。训练样本从训练集里采样,测试样本从测试集里采样。
num_training = 5000
num_test = 500random_train = np.random.randint(50000,size=5000)
random_test = np.random.randint(10000,size=500)X_train = X_train[random_train]
y_train = y_train[random_train]X_test = X_test[random_test]
y_test = y_test[random_test]print (X_train.shape, y_train.shape, X_test.shape, y_test.shape)

2. 使用KNN算法识别图片。

这部分主要的工作是通过K折交叉验证来训练KNN,以及选择最合适的K值和p值。具体KNN的描述请看官方文档: https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html

KNN有几个关键的参数:

K: 指定选择多少个neighbors。 这个值越大,我们知道KNN的决策边界就会越平滑,而且越不容易过拟合, 但不保证准确率会很高。
p: 不同距离的指定,看以下的说明。

KNN依赖于两个样本的距离计算,这里简单介绍一下一个概念叫做Minkowski Distance,是一个种通用的距离计算方法。假如我们有两个点,分别由两个向量来表达x=(x1,x2,...,xd) 和 y=(y1,y2,...,yd) ,这时候根据Minkowski Distance的定义可以得到以下的结果:

从上述的距离来看其实不难发现p=1 时其实就是绝对值的距离,p=2 时就是欧式距离。所以欧式距离其实是Minkowski Distance的一个特例而已。所以这里的p 值是可以调节的比如p=1,2,3,4,... 。

# 首先我们 Reshape一下图片。图片是的每一个图片变成一个向量的形式。也就是把原来大小为(32, 32, 3)的图片直接转换成一个长度为32*32*3=3072的向量。
# 这样就直接可以作为模型的输入。 X_train_1和y_train_1是用来解决第一个问题的处理后的数据。
X_train1 = np.reshape(X_train, (X_train.shape[0], -1))
X_test1 = np.reshape(X_test, (X_test.shape[0], -1))
print(X_train1.shape, X_test1.shape) # 确保维度正确# 训练数据: (X_train1, y_train), 测试数据:(X_test1, y_test)
params_k = [1,3,5,7]  # 可以选择的K值
params_p = [1,2] # 可以选择的P值# 构建模型
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
param_grid = {"n_neighbors":params_k,"p":params_p}
model = GridSearchCV(estimator=KNeighborsClassifier(),param_grid=param_grid,cv=5)
model.fit(X_train1,y_train)
# 输出最好的K和p值
print(model.best_params_)# 输出在测试集上的准确率
predict_model = model.best_estimator_
y_pre = predict_model.predict(X_test1)
correct = np.count_nonzero((y_pre==y_test)==True)
print("Predict precision is: ",correct/len(y_test))

3. 抽取图片特征,再用KNN算法来识别图片

一种解决图像识别问题中各种环境不一致的方案是抽取对这些环境因素不敏感的特征,这就是所谓的特征工程。 在这里,我们即将会提取两种类型的特征,分别是color histogramHOG特征,并把它们拼接在一起作为最终的特征向量。 至于这些特征的概念请参考第三章的内容,或者网络上的一些解释。我们已经提供了抽取特征的工具,只需要调用就可以使用了。 所以你需要做的任务是:

  1. 调用特征提取工具给每一个图片提取特征。 如果想深入了解,可以查看其代码
  2. 使用K折交叉验证去学出最好的模型(同上)
from features import *num_color_bins = 10 # 设定color histogram的 bin大小# 分别设置接下来需要调用的两个特征抽取器,分别是hog_feature, color_histogram_hsv
feature_fns = [hog_feature, lambda img: color_histogram_hsv(img, nbin=num_color_bins)]# 抽取特征,分别对特征数据和测试数据,把结果存放在X_train2和X_test2
X_train2 = extract_features(X_train, feature_fns, verbose=True)
#X_val_feats = extract_features(X_val, feature_fns)
X_test2 = extract_features(X_test, feature_fns)# 打印转换后的数据大小。
print (X_train2.shape, X_test2.shape)# 对于X_train2, X_test2做归一化from sklearn import preprocessing
from sklearn.preprocessing import StandardScalerx_normalizer = StandardScaler()
X_train2 = x_normalizer.fit_transform(X_train2)
X_test2 = x_normalizer.transform(X_test2)# 通过K折交叉验证构造最好的KNN模型,并输出最好的模型参数,以及测试集上的准确率。
# 训练数据: (X_train2, y_train), 测试数据:(X_test2, y_test)
params_k = [1,3,5,7]  # 可以选择的K值
params_p = [1,2] # 可以选择的P值
param_grid = {"n_neighbors":params_k,"p":params_p}
# 构建模型
model = GridSearchCV(estimator=KNeighborsClassifier(),param_grid=param_grid,cv=5)
model.fit(X_train2,y_train)
# 输出最好的K和p值
print(model.best_params_)# 输出在测试集上的准确率
predict_model = model.best_estimator_
y_pre = predict_model.predict(X_test2)
correct = np.count_nonzero((y_pre==y_test)==True)
print("Predict precision is: ",correct/len(y_test))

你应该会看到效果的提升,没错! 因为提取出来的特征会比原始的像素特征更加Robust。 除了上面所讲到的2种类型特征,也可以尝试其他图形识别的特征。

4. 使用PCA对图片做降维,并做可视化

PCA是一种常用的降维工具,可以把高维度的特征映射到任意低维的空间,所以这个方法也经常用来做数据的可视化。具体PCA相关的教程可以参考sklearn官方文档,https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html, 他有一个主要的参数需要设计,就是n_components, 指的是降维之后的维度。比如设置为2,就代表降维到2维的空间。现阶段,能看懂官方文档,以及指导如何使用就可以了。 需要完成以下任务:

  1. 通过PCA把数据降维,然后再通过KNN来分类
  2. 把降维之后的数据可视化
params_components = [10, 20, 50, 100]
params_k = [1,3,5,7]  # 可以选择的K值
params_p = [1,2] # 可以选择的P值
param_grid = {"n_neighbors":params_k,"p":params_p}from sklearn.decomposition import PCA#首先使用PCA对数据做降维,之后再用KNN做交叉验证。 每一个PCA的维度都需要做一次KNN的交叉验证过程。
#       输入为原始的像素特征。 训练数据:X_train,  y_train  测试数据: X_test, y_test。
data = []
for component in params_components:pca = PCA(n_components=component)X_train3 = pca.fit_transform(X_train2)#用原始像素特征会不会太久?这里换用X_train2X_test3 = pca.transform(X_test2)model = GridSearchCV(estimator=KNeighborsClassifier(),param_grid=param_grid,cv=5)model.fit(X_train3,y_train)predict_model = model.best_estimator_y_pre = predict_model.predict(X_test3)correct = np.count_nonzero((y_pre==y_test)==True)data.append([correct/len(y_test),component,model.best_params_['n_neighbors'],model.best_params_['p']])data = np.array(data)
D = data[np.argmax(data[:,0])][1]
K = data[np.argmax(data[:,0])][2]
p = data[np.argmax(data[:,0])][3]
Precision = data[np.argmax(data[:,0])][0]# 输出最好的 维度、K和p值
print("Best dimension:%.1f Best K:%.1f Best p:%.1f"%(D,K,p))# 输出在测试集上的准确率
print("Best precision:%6.3f"%Precision)

把数据映射到2维的空间,然后展示。 从X_train中随机选择50个图片做展示, 请使用subplots. 具体来讲的话:

  1. 首先把随机提取训练数据中的50个样本。
  2. 对这50个样本做数据的降维,使用PCA降维到2维的空间,这时候每一个图片变成了2维的向量
  3. 这2维的向量我们可以看作是图片的坐标

根据图片的坐标,把每个图片展示在相应的位置,需要使用imshow来展示图片。

并观察以下是否能看出想个相邻图片之间有一些共性?

random_50 = np.random.randint(5000,size=50)
X_train4 = X_train2[random_50]
second_pca= PCA(n_components=2)
second_pca.fit_transform(X_train4)
plt.subplot(111)
#plt.plot(X_train4[0],X_train4[1])
plt.imshow(X_train4)
plt.show()

5 使用神经网络识别图片

在这里,我们将尝试使用神经网络来识别图片。我们将会搭建包含一层隐含层的神经网络(多层就意味着是深度神经网络)。这里使用的数据为特征提取之后的数据(HOG, color histogram)。

创建神经网络模型(叫做multilayer perceptron), 并制定模型的参数。 具体神经网络的使用参考: https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPClassifier.html#sklearn.neural_network.MLPClassifier 在这里我们需要调整的参数为:

  1. hidden_layer_sizes: 隐含层神经元的个数,这个值越大模型越容易过拟合,但这个值越小模型的准确率就不高
  2. activation: 'logistic': 这是激活函数,可以让模型拥有非线性。有几个常见的选项个如'logistic', 'relu'等。我们在这里使用'logistic'为激活函数
    # 利用sklearn来实现神经网络模型,并使用交叉验证来选出最好的参数hidden_layer_size
    #  训练数据:(X_train2, y_train)  测试数据: (X_test2, y_test), 直接使用上面已经构建好的特征。
    from sklearn.neural_network import MLPClassifier
    import warningswarnings.filterwarnings("ignore")
    params_hidden_layer_sizes = [10,20,30,40,50]
    activation = 'logistic'
    params_grid={"hidden_layer_sizes":params_hidden_layer_sizes}
    model = GridSearchCV(estimator=MLPClassifier(activation = activation),param_grid=params_grid,cv=5)
    model.fit(X_train2,y_train)# 输出最好的K和p值
    print(model.best_params_)# 输出在测试集上的准确率predict_model = model.best_estimator_
    y_pre = predict_model.predict(X_test2)
    correct = np.count_nonzero((y_pre==y_test)==True)
    print("Predict precision is: ",correct/len(y_test))

基于KNN算法的图像识别相关推荐

  1. python 数学公式识别_Python实现基于KNN算法的笔迹识别功能详解

    本文实例讲述了Python实现基于KNN算法的笔迹识别功能.分享给大家供大家参考,具体如下: 需要用到: Numpy库 Pandas库 手写识别数据 点击此处本站下载. 数据说明: 数据共有785列, ...

  2. python模拟手写笔迹_Python实现基于KNN算法的笔迹识别功能详解

    本文实例讲述了Python实现基于KNN算法的笔迹识别功能.分享给大家供大家参考,具体如下: 需要用到: Numpy库 Pandas库 手写识别数据 点击此处本站下载. 数据说明: 数据共有785列, ...

  3. 基于KNN算法的手写体数字识别

    基于KNN算法的手写体数字识别 KNN分类算法是一种经典的分类算法,属于懒惰学习算法的一种. 1.算法原理 工作原理:存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道 ...

  4. 【Python】基于kNN算法的手写识别系统的实现与分类器测试

    基于kNN算法的手写识别系统 1.      数据准备 使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件. 方法如下,使用画图工具,打开网格线,调整像素为32 ...

  5. 机器学习:基于Knn算法的用户属性判断方案设计

    本文作者通过Knn算法进行了一次用户判断预测的流程,文章为作者根据自身经验所做出的总结,希望通过此文能够加深你对Knn算法的认识. knn算法简介 K最近邻(k-Nearest Neighbor,KN ...

  6. python笔迹识别_python_基于KNN算法的笔迹识别

    需要用到: Numpy库 Pandas库 手写识别数据 下载地址 数据说明: 数据共有785列,第一列为label,剩下的784列数据存储的是灰度图像(0~255)的像素值 28*28=784 KNN ...

  7. 基于KNN算法的少量数据分类实验

    一.实验目的 利用knn分类算法来对汽车碰撞声以及汽车鸣笛声进行识别,本次实验使用的声学特征是37维mfcc特征,其中包括前12维倒谱系数.12维一阶差分系数.12维二阶差分系数以及1维短时信号能量谱 ...

  8. 基于KNN算法的颜色识别

    KNN实现魔方颜色识别 1.颜色识别 该程序利用KNN实现魔方颜色识别,特征采用RGB的颜色直方图,它可以区分白.黑.红.绿.蓝.橙色.黄色和紫色,如果你想分类更多颜色或者提高分类准确率,可以通过调整 ...

  9. 基于KNN算法——手写海伦约会(学习)

    import numpy as np import pandas as pd import operator from matplotlib.font_manager import FontPrope ...

最新文章

  1. 完成CitrixVDI架构了解及部署测试
  2. 自定义PHP错误报告处理方式
  3. APUE(第九章)进程关系
  4. 硅谷人眼中的2018年十大前沿科技预测
  5. python调用math函数log_Python中求对数方法总结
  6. Java基础:IO流之File类
  7. Luogu_2774 方格取数问题
  8. 20190718考试70分记
  9. Collection中Set集合在应用中常见的方法和注意点
  10. Java 中 List 分片的 5 种方法!
  11. [转载]如何决定要使用多少点来做FFT?(转载)
  12. 恶意广告活动利用 WebKit 0day 实施欺诈
  13. 网络工程师Day2---实验2-1:HDLC和PPP配置
  14. Python黑魔法 --- 异步IO( asyncio) 协程
  15. libxml2 not found
  16. OpenRefine数据清洗实战
  17. UVA 473 Raucous Rockers
  18. 如何通过压缩视频软件,减少大小且画质无损技巧
  19. 了解原型设计工具:墨刀
  20. supervisor> restart bili:create_bili_index bili:create_bili_index: ERROR (not running) bili:create_b

热门文章

  1. STM32入门100步 第2期 STM32家族大起底
  2. LocalDate的常用方法(值得收藏的好文)
  3. HBase介绍、搭建、环境、安装部署
  4. PAT 团体程序设计天梯赛-练习集 题解(凑零钱,堆栈,社交集群)
  5. 华为mate 30rs保时捷安装鸿蒙系统,华为Mate30 RS保时捷版本发布:加入高档机身工艺,标配5G功能...
  6. lemon语法分析生成器的使用以及源代码分析
  7. 深耕中国、投资中国、服务中国,斯凯奇斥资30亿元建设中国物流中心 | 美通社头条...
  8. [18调剂]中国科学院上海高等研究院 航空通信实验室接受调剂
  9. C语言:十进制转换成十六进制字符串和数组
  10. Photoshop CC 2017 One-on-One: Mastery Photoshop CC 2017系列进阶教程之成为大师 Lynda课程中文字幕