参考Python深度学习第5章第2节中的代码示例
目录
一、理解人脸图像特征提取的各种方法(至少包括HoG、Dlib和卷积神经网络特征)
这个网上很多资料,可以自己去找来看。
1、HOG
Histogram of Oriented Gradient descriptors provide a dense overlapping description of image regions,即统计图像局部区域的梯度方向信息来作为该局部图像区域的表征。
HOG有点类似于SIFT特征描述子,区别:
1)HOG没有选取主方向,也没有旋转梯度方向直方图,因而本身不具有旋转不变性(较大的方向变化),其rotate不变性是通过采用不同旋转方向的训练样本来实现的;
2)HOG本身不具有scale不变性,其scale不变性是通过改变检测图像的size来实现的;
3)HOG是在dense采样的图像块中求取的,在计算得到的HOG特征向量中隐含了该块与检测窗口之间的空间位子关系,而SIFT特征向量是在一些独立并离散分布的特征点上提取的(dense SIFT除外)。
2、Dlib人脸特征检测
Dlib人脸特征检测原理是首先要提取特征点,将人脸划分为68个坐标点,获取到这68个特征点的值后,就把获取的特征数据集写入csv,最后计算特征数据集的欧氏距离作对比,每个人的人脸的欧氏距离都不一样,所以可以达到识别人脸的作用。
3、卷积神经网络
卷积网络在本质上是一种输入到输出的映射,它能够学习大量的输入与输出之间的映射关系,而不需要任何输入和输出之间的精确的数学表达式,只要用已知的模式对卷积网络加以训练,网络就具有输入输出对之间的映射能力。
特点
CNN一个非常重要的特点就是头重脚轻(越往输入权值越小,越往输出权值越多),呈现出一个倒三角的形态,这就很好地避免了BP神经网络中反向传播的时候梯度损失得太快。
卷积神经网络CNN主要用来识别位移、缩放及其他形式扭曲不变性的二维图形。由于CNN的特征检测层通过训练数据进行学习,所以在使用CNN时,避免了显式的特征抽取,而隐式地从训练数据中进行学习;再者由于同一特征映射面上的神经元权值相同,所以网络可以并行学习,这也是卷积网络相对于神经元彼此相连网络的一大优势。卷积神经网络以其局部权值共享的特殊结构在语音识别和图像处理方面有着独特的优越性,其布局更接近于实际的生物神经网络,权值共享降低了网络的复杂性,特别是多维输入向量的图像可以直接输入网络这一特点避免了特征提取和分类过程中数据重建的复杂度。
二、掌握笑脸数据集(genki4k)正负样本的划分、模型训练和测试的过程(至少包括SVM、CNN),输出模型训练精度和测试精度(F1-score和ROC)
1、在小数据集上训练ConvNet
我们从零开始在小数据集上训练Convnet。
仅使用很少的数据来训练图像分类模型是一种常见的情况,如果你曾经在专业环境中做过计算机视觉,你可能会在实践中遇到这种情况。
拥有“少量”样本可能意味着从数百到数万张图像。作为一个实际的例子,我们将在包含4000张笑和没笑的图片(2000张笑的,2000没笑的)的数据集中把图像分类为“smile”或“unsmile”。我们将使用2000张图片进行培训,1000张用于验证,最后1000张用于测试。
在这个程序中,我们将回顾解决这个问题的一个基本策略:在我们仅有的少量数据的基础上从头开始训练一个新模型。我们将从天真地在我们的2000个训练样本上训练一个小convnet开始,没有任何规则化,为可以达到的目标设定一个基线。这将使我们的分类准确率达到71%。到那时,我们的主要问题将是过度拟合。然后我们将介绍数据增强技术,这是一种减轻计算机视觉中过度拟合的强大技术。通过利用数据扩充,我们将改进我们的网络,使准确率达到82%。
2、 深度学习与小数据问题的相关性
你有时会听说深度学习只有在有大量数据的时候才有效。这在一定程度上是有道理的:深度学习的一个基本特征是,它能够自己在训练数据中发现有趣的特征,而不需要任何手动特征工程,并且这只能在有大量训练实例可用时才能实现。对于输入样本非常高维的问题尤其如此,比如图像。
然而,构成“大量”样本的是相对的——首先,相对于你试图训练的网络的规模和深度。仅仅用几十个样本来训练一个convnet来解决一个复杂的问题是不可能的,但是如果这个模型很小并且规则性很好,并且任务很简单,那么几百个样本就足够了。因为convnets学习局部的、平移不变的特征,所以它们在感知问题上非常有效。在非常小的图像数据集上从头开始训练convnet仍然会产生合理的结果,尽管相对缺乏数据,不需要任何定制的特征工程。您将在本节中看到这一点。
但更重要的是,深度学习模型本质上是高度可重用的:你可以采取,比如说,在大规模数据集上训练的图像分类或语音到文本的模型,然后在一个明显不同的问题上重用它,只需要很小的改变。具体来说,在计算机视觉的情况下,许多预先训练的模型(通常在ImageNet数据集上训练)现在可以公开下载,并且可以用于从非常少的数据中引导强大的视觉模型。这就是我们下一节要做的。
现在,让我们从掌握数据开始。
3、 数据集下载
数据集就是网上通用的笑脸数据集。
找不到的也可以找我要数据集。
展示几张图片
不出所料,2013年猫狗Kaggle比赛的获胜者是使用convnets的参赛者。最佳输入可以达到95%的准确率。在我们自己的例子中,我们将相当接近这一精度(在下一节),尽管我们将在竞争对手可用数据的不到10%的情况下训练我们的模型。
4、 代码实现上述操作
首先需要下载tensorflow,然后再下载keras,然后就可以执行代码了。
运行tensorflow环境,可以看到我下载的是2.3.1版本的。
然后导包
读取训练集的图片,将训练数据和测试数据放入自己创建的文件夹
# The path to the directory where the original
# dataset was uncompressed
riginal_dataset_dir = 'C:\Users\Administrator\Desktop\genki4k'
# The directory where we will
# store our smaller dataset
base_dir = 'genki4k'
os.mkdir(base_dir)
# Directories for our training,
# validation and test splits
train_dir = os.path.join(base_dir, 'train')
os.mkdir(train_dir)
validation_dir = os.path.join(base_dir, 'validation')
os.mkdir(validation_dir)
test_dir = os.path.join(base_dir, 'test')
os.mkdir(test_dir)
# Directory with our training smile pictures
train_smile_dir = os.path.join(train_dir, 'smile')
os.mkdir(train_smile_dir)
# Directory with our training unsmile pictures
train_unsmile_dir = os.path.join(train_dir, 'unsmile')
#s.mkdir(train_dogs_dir)
# Directory with our validation smile pictures
validation_smile_dir = os.path.join(validation_dir, 'smile')
os.mkdir(validation_smile_dir)
# Directory with our validation unsmile pictures
validation_unsmile_dir = os.path.join(validation_dir, 'unsmile')
os.mkdir(validation_unsmile_dir)
# Directory with our validation smile pictures
test_smile_dir = os.path.join(test_dir, 'smile')
os.mkdir(test_smile_dir)
# Directory with our validation unsmile pictures
test_unsmile_dir = os.path.join(test_dir, 'unsmile')
os.mkdir(test_unsmile_dir)
运行完这个程序会生成一个文件夹,如果再次运行这个程序就会报错,因为已经有这个文件存在。然后我是自己把这些照片放进对应的文件里的,效果是一样的,也可以通过代码进行。
# Copy smile images to train_smile_dir
#fnames = ['smile.{}.jpg'.format(i) for i in range(1000)]
#for fname in fnames:
# src = os.path.join(original_dataset_dir, fname)
# dst = os.path.join(train_smile_dir, fname)
# shutil.copyfile(src, dst)
# Copy next 500 smile images to validation_smile_dir
#fnames = ['smile.{}.jpg'.format(i) for i in range(1000, 1500)]
#for fname in fnames:
# src = os.path.join(original_dataset_dir, fname)
# dst = os.path.join(validation_smile_dir, fname)
# shutil.copyfile(src, dst)
# Copy next 500 smile images to test_smile_dir
#fnames = ['smile.{}.jpg'.format(i) for i in range(1500, 2000)]
#for fname in fnames:
# src = os.path.join(original_dataset_dir, fname)
# dst = os.path.join(test_smile_dir, fname)
# shutil.copyfile(src, dst)
# Copy firs