knn人脸识别判断_基于OpenCV和Keras实现人脸识别系列——七、通过K折交叉验证选取最佳的KNN模型实现人脸分类...

本文介绍了基于OpenCV和Keras的人脸识别项目,利用KNN算法进行人脸分类。通过K折交叉验证选择最佳的KNN模型,实现了99%的准确率。文章详述了KNN算法思想、数据预处理中的L2_normalization以及shuffle操作对模型性能的影响,强调了数据平衡度和归一化的关键作用。
摘要由CSDN通过智能技术生成

基于OpenCV和Keras的人脸识别系列手记:

项目完整代码参见Github仓库。

项目完整代码参见Github仓库。

本篇手记是上面这一系列的第七篇。

在系列的上一篇手记里,我完成了将图片转化为128维特征向量的工作,这篇要用这些128维特征向量的数据来训练一个KNN模型。

KNN算法的基本思想

先来看看KNN算法的基本思想,KNN是K nearest neighbor的缩写,中文名称是k-近邻算法。一开始学习这个算法,我是通过斯坦福的计算机视觉课程cs231n,里面有一节专门介绍了KNN算法并且还有配套的编程作业,学过以后我觉得KNN算法就是对需要预测的数据,将其与所有训练数据比较,得到训练数据中k个距离(通常是欧氏距离)预测数据最近的样本,统计其分类,最后将k个样本中占最多数的分类作为对预测数据的分类预测。KNN算法中,k值是一个需要调整的超参数。

如果说上面的通用描述还比较抽象,不好理解,我来把它引申到这个人脸识别项目里:假如现在摄像头实时探测到一张人脸,先计算这张人脸图像和我之前准备的两千多张人脸图像128维特征向量的欧氏距离,就会得到两千多个欧氏距离,假设k取7,在这两千多个欧氏距离里取7个最小的,如果其中有四个以上欧氏距离所对应的分类标签都是“我”,那么就预测这张探测到的人脸就是我。

可以看到,KNN算法的思想很简单,也确实是所有机器学习算法里最简单的之一,不过,我在实际使用的时候发现还是有许多细节需要注意。下面就来讲解我是如何实现用KNN算法识别人脸的。

scikit-learn

在这个项目里,我是用scikit-learn这个基于Python的机器学习库来实现KNN算法的,scikit-learn覆盖了数据集的加载、预处理,模型的建立、训练、预测和持久化以及性能评估等机器学习的完整流程,利用scikit-learn能很方便地实现KNN、SVM等机器学习常用算法。

Holdout验证与K折交叉验证

Facenet+KNN方案整体的思路其实和利用人脸数据训练一个简单的神经网络模型里类似,只是训练数据由人脸图片变成了经过Facenet提取的128维人脸特征,最终的预测模型由CNN变成了KNN,然后值得一提的一个不同就是我在这里使用了K折交叉验证。

继续抽象的理论之前还是先上一些代码,首先是建立一个KNN模型的类,用来建立、训练、测试和持久化KNN模型:

class Knn_Model:

# 初始化构造方法

def __init__(self):

self.model = None

在系列前一篇手记的最后我提到了,在准备训练数据的时候我没有像之前用简单CNN的方案中那样,将准备好的训练数据随机按70%/30%的比例划分为训练集和测试集,这种一部分数据集用于训练,一部分数据集用于测试的方式叫做Holdout验证,由于训练数据和测试数据并没有交叉使用,这种验证方式并不能算是交叉验证。一开始训练KNN模型的时候我是沿用了Holdout验证,将Facenet提取的128维人脸特征七比三随机划分为训练集和测试集:

X_train, X_test, y_train, y_test = train_test_split(X_embedding, labels, test_size = 0.3, random_state = random.randint(0, 100))

上面train_test_split方法的random_state参数的值是一个0到100之间的随机整数,因此每次运行程序时数据的划分都不一样,我在实际运行程序的时候发现,有的时候KNN模型的测试准确率能达到90%+,有的时候只有80%+。虽然最后实际运行人脸识别程序的时候效果差不多,但是在训练一个模型的时候,我肯定希望准确率越高越好,因此,我改用了K折交叉验证:

K次交叉验证,将训练集分割成K个子样本,一个单独的子样本被保留作为验证模型的数据,其他K-1个样本用来训练。交叉验证重复K次,每个子样本验证一次,平均K次的结果或者使用其它结合方式,最终得到一个单一估测。这个方法的优势在于,同时重复运用随机产生的子样本进行训练和验证,每次的结果验证一次,10次交叉验证是最常用的。

在K折交叉验证里,由于训练数据和测试数据交叉使用,最终的结果会更稳定、准确,受数据划分的影响也大大减小。

下面在Knn_Model类里定义一个cross_val_and_build_model方法用来实现K折交叉验证并选择最佳的模型(超参数k):

def cross_val_and_build_model(self, dataset):

k_range = range(1,31)

# k_range = range(1,60)

k_scores = []

print("k vs accuracy:")

for k in k_range:

knn &#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值