我们先来对比一下AlexNet和VGGNet。AlexNet整个网络结构包括五层卷积层和三层全连接层。而VGGNet的结构上来看,有更多的输出channel,因此可以达到更高和更细粒的准确性,可以提取出来更多的信息。下图是VGGNet16的结构:
从卷积核的size来看,AlexNet在浅层网络开始的时候使用11×11卷积核,并且尽量在浅层网络的时候避免使用1×1的卷积核。但VGG在整个网络中使用3x3的卷积核来模仿较大卷积核那样对图像进行局部感知,stride设置为1。比如,使用三个3x3的卷积核而不是一个7x7的卷积核的好处是什么?有两点原因。1. 我们使用了3次非线性函数而不是1次,这样增加了函数的判别能力。2. 这样减少了参数的数量、降低运算时间。假设三个3x3卷积层参数数目为27,而7x7的卷积核参数数目为49个。下表是AlexNet和VGGNet19各层的信息:
(PS:‘conv 3-512’ 是指3x3的卷积核,深度为512)
下面看一下Fine-tunning在VGGNet19中的使用。Fine-tuning就是在对已训练好的模型进行微调,相当于使用别人的模型的前几层来提取浅层特征。ConvNet前几层学到的是更通用的特征,后面几层学到的特征是more original-dataset-specific。为什么要用Fine-tuning呢?比如在一些特定的领域的图像识别中,很难获取大量的数据,即使像在ImageNet上这种巨型的图像数据库中,通常某一特定领域的图像也只有几千张或者几万张。在这种情况下重新训练一个新的网络是比较复杂的,而且参数不好调整,数据量也不够,因此微调是一个比较理想的选择。Fine-tuning最大的好处就在于不需要从头训练,下载预训练模型即可,尤其在数据集相对较少的情况下,既可以有效利用深度神经网络强大的泛化能力,又可以免去设计复杂的模型以及耗时良久的训练。使用Fine-tuning的关键是新数据集的大小和原数据集的相似程度。
下面来看看具体实验。由于我下载别人的npy文件做Fine-tunning,而且其最终输出有1000个分类,而在我们的例子中只有两类,因此我在最后加多了一层全连接,使得最终输出为两分类。由于VGGNet的网络较深,用的是GPU也只有3G的显存,因此batch_size设置为10才刚好够。设置了30个epoch,训练了差不多一天,训练输出如下图:
最终测试集的精度也能去到了99.1%,比AlexNet的89%好太多了。实验代码放在参考网址<1>。
参考网址:
<1> https://github.com/DemonDamon/comparisons-among-various-deep-nets-in-dogs-vs-cats-dataset