在《21个项目玩转深度学习》这本书中读到了这章,突然发现和我之前构思过想法:利用人脸识别的深度网络实现自己的表情识别模型这一概念有些奇妙的共同之处,看到了实现我想法的曙光,决定记录下来方便以后用到。
我曾经画过这样一张图,想要利用两级网络实现表情识别:
想法是这样:
- 首先我们要实现表情识别这一目标,采用的是连续维度下的A、V值作为表情的衡量框架。
- 第一级深度神经网络(比如原本用来实现人脸识别、人脸检测等的网络模型),去掉其最终的全连接层,将整个网络所学习到的关于人脸的共通的表示特征进行耦合整理,作为第二级深度神经网络的输入(这里就可以用到这节内容讲到的微调)。
- 而第二级深度神经网络原本是可以作为一个单独的网络,输入人脸图像,输出连续维度下的表情。 但这里我们将其改进为,用第一级网络输出的关于人脸的本质的特征作为第二级深度神经网络的输入,继续进行学习。 经过第一级网络,我们学习到排除掉人脸之外因素的本质特征,再将其作为输入样本,用第二级网络继续学习关于表情识别的特征,最终经过全连接层输出表情识别结果。
下面记录书中的细节:
这一节内容关注的重点是如何使用TensorFlow 在自己的图像数据上训练深度学习模型,主要涉及的方法是对已经预训练好的ImageNet模型进行微调( Fine-tune)。下面将会从四个方面讲解:数据准备、训练模型、在测试集上验证准确率、导出模型并对单张图片分类。
同时,关于这节内容的代码以及我的一些小笔记打包如下:
链接:https://pan.baidu.com/s/1VbpsShJG3Oky-erDqxQJkw 提取码:l6qm
1. 微调的原理
示例采用VGG16进行微调,如下图所示,VGG16的结构为 卷积+全连接层卷积层分为5 个部分共13 层, 即图中的conv 1~ conv 5。还高3 层是全连接层,即圈中的fc6 、
fc7 、 fc8 0 卷积层加上全连接层合起来一共为16 层,因此它被称为VGG16 。
这是ImageNet的较为经典的网络模型,当我们要将其运用到一个新的数据集时,第一步就是先去掉 fc8 全连接层,因为基于ImageNet,fc8的输入是fc7层的特征,输出为对应1000个类别的概率。 若需换成自己的数据集,也应该将重新设置 fc8层 输出对应的类别数(比如5、6类等等,如果你的问题是 分类问题)。若你的问题是回归问题,同样也需要改,但可能不像这个这么简单(我是要改成这样,后面试试)。
同时,在我们引入网络结构进行训练的时候,网络参数的初始值并不是随机生成的,而是采用VGG16在ImageNet上已经训练好的初始值。
原因在于,在ImageNet数据集上训练过的VGG16 中的参数已经包含了大量有用的卷积过滤器,与其从零开始初始化VGG16 的所需参数,不如使用已经训练好的参数当作训练的起点。这样做不仅可以节约大量训练时间,而且有助于分类器性能的提高。
载入参数后,就可以进行训练了。此时需要指定训练层数的范围。一般来说,可以选择以下几种:
- 只训练 fc8层。 训练范围一定要包含fc8 这一层。之前说过,fc8 的结构须经过调整,因此它的参数不能直接从ImageNet 预训练模型中取得。可以只训练fc8 ,保持其他层的参数不动。这就相当于将VGG16 当作一个“特征提取器”:用fc7 层提取的特征做一个softmax模型分类。这样做的好处是训练速度快,但往往性能不会太好
- 训练所有参数。 这相当于只采用VGG16魔性的架构,对之前学习的参数都进行微调。对网络中的所有参数进行训练,这种方法的训练速度可能比较慢,但是能取得较高的性能,可以充分发挥深度模型的优势。
- 训练部分参数。通常是固定浅层参数不变,训练深层参数。如固定conv1 、conv2 部分的参数不训练,只训练conv 3 、conv 4, conv 5, fc6 、fc7 、fc8层 的参数。
这种训练方法就称为对神经网络模型做微调。借助微调,我们可以将深度网络模型运用到自己的数据集上。
2. 数据准备
首先要做一些数据准备方面的工作:一是把数据集切分为训练集和验证集, 二是转换为 tfrecord 格式。在data_prepare/文件夹中提供了会用到的数据集和代码。
首先要将自己的数据集切分为训练集和验证集,训练集用于训练模型,
验证集用来验证模型的准确率。这篇文章已经提供了一个实验用的卫星图片分类数据集,这个数据集一共高6个类别, 见表3-1
在data_prepare 目录中用一个pic 文件夹保存原始的图像文件,图像 文件保存的结构如下:
将图片分为 train 和 validation 两个目录,分别表示训练使用的图片和验证使用的图片。在每个目录中,分别以类别名为文件夹名保存所有图像。在每个类别文件夹下,存放的就是原始的图像(如jpg 格式的图像文件)。
切分好了之后,我们就预先编辑好的脚本 data_convert.py将图片转化为 tfrecord格式:
命令窗口切换到数据集所在的文件夹,然后输入:
- -t pic/: 表示转换pic文件夹中的数据。pic文件夹中必须有一个train目录和一个validation目录,分别代表训练和验证数据集。每个目录下按类别存放了图像数据。
- –train-shards 2:将训练数据集分成两块,即最后的训练数据就是两个tfrecord格式的文件。如果自己的数据集较大,可以考虑将其分为更多的数据块。<