Caffe深度学习进阶之Cifar-10分类任务(上)

时间:2024-05-23 11:19:50

前言

Cifar-10数据集是深度学习领域一个常见的数据集。Cifar-10由60000张32*32的RGB彩色图片构成,一共包含有飞机、汽车、鸟、毛、鹿、狗、青蛙、马、船、卡车这10个类别。50000张训练,10000张测试。常被用来作为分类任务来评价深度学习框架和模型的优劣。比较知名的模型如AlexNet、NIN、ResNet等都曾在Cifar-10数据集上来评价自己的性能。它还有一姐妹级的数据集Cifar-100,顾名思义就是包含100个类别,数据更加复杂。关于Cifar数据集的相关介绍以及数据的下载可见官网。正是因为Cifar-10数据集不大、类别明确、获取方便、训练简单,同时模型的可参照性强,因此作为深度学习的初学者作为一个进阶的内容,再适合不过了(本文的前提是对Caffe的使用及相关参数有一定的了解)。

第一个模型

数据拿到手后,第一件事就是想拿个模型来跑跑找找感觉,那么第一个模型选什么呢?我考虑了很久,LeNet?AlexNet?还是VGG?ResNet?其实无论选择什么模型,我都建议大家先把相关的论文仔仔细细的看一遍,了解它的原理后,做起实验来才会得心应手,并且论文中的实验部分也会把实验的相关参数提供出来,也节省了大家调超参的时间。关于VGG、ResNet的论文译文和笔记可以参考本人之前的博客(VGG译文VGG笔记ResNet译文ResNet笔记)。当你了解了一个模型的大概思路后(任意都可以),动动你的小鼠标和键盘,在GitHub上可以下载到大牛们搭建好的模型框架,都是可以拿来直接使用的。不过在这里我也建议大家,当拿到别人提供的prototxt之后,仔细读一读这个框架,可以使用模型的可视化工具Netscope来看模型的部署,这对你更加深入的了解这个模型是有帮助的。这样你就可以开始你的第一个实验了。

这里我使用的是ResNet,为啥?因为作为ImageNet2015的赢家,ResNet这几年依旧是最广泛使用的模型之一、也是大家研究的热点,可扩展性强,它的优点毋庸置疑,还有最重要的一点,ResNet原文中就说了,仅20层的ResNet在Cifar-10上的准确率可以达到91%以上,看着就心动,可参考性也强。于是就选ResNet了。GitHub上有很多ResNet的源码,在这里我推荐:ResNet-on-Cifar10,提供了详细的源码以及相应的结果。在这里我使用了他提供的20层ResNet进行实验。

模型、数据准备好就开始训练,具体的参数设置在这里就不详细说了,大家可以看论文,整个训练过程很顺利,最终测试准确率达到了91.65%,由于当时的训练曲线没有保存下来,这里盗个图(感谢源码的提供者),大家见谅:
Caffe深度学习进阶之Cifar-10分类任务(上)

这个结果是基本符合论文中的结果的,但是我还是不满足,于是我进行了下一步,数据增强。

数据增强

数据增强是深度学习中训练模型时常用的技术手段,它能够很好的增加数据的多样性,能够有效的缓解模型的过拟合,同时能够达到提升模型性能和泛化能力的效果。熟悉图像处理的应该知道,图像增强的方式有很多,如旋转、平移、缩放等等。你在论文中也会经常读到一些数据增强的方式,这里就不一一介绍。

你可以在数据增强使用在模型训练的外部,也就是在训练之前就是用数据增强的方式来扩展你的数据,你也可以把数据增强写在Caffe的源码中,类似于Caffe自带的mirror,当数据输入进去之后,会随机的进行你所写入的数据增强。在这里我比较推荐第二种方法,因为如果你使用在模型的外部,首先你需要大量的时间来处理你的数据,同时你还需要大量的空间来储存你的数据,这对于资源的利用是非常不利的。

在这里大家可以选择自己熟悉的数据增强方式来扩展数据,但是提醒大家一点,一昧的增加数据增强的种类不一定会给模型的性能带来增益,打个比方,观察到Cifar-10数据集中,测试样本和训练样本中目标的朝向都是一样的,因此你对训练样本进行旋转的话,是不会给模型的性能带来提升的,甚至有可能会起到副的作用。因此在选择数据增强之前,建议大家先好好观察数据集中的样本,再来选择需要使用的数据增强方式。这是一个坑,很多人都踩过,我也不例外。

经过数据增强后,你会发现模型的性能发生了质的飞跃,测试准确率可能从91%就窜到了92%、93%甚至更高。但是我们对这个结果依旧不满足,怎么办?我们选择对模型进行扩展。

模型扩展

ResNet是一个使用非常广泛的模型,可扩展性非常强,在ResNet模型上的扩展包括Wide ResNet、ResNet in ResNet、Stochastic Depth ResNet、FractalNet等等。他们的想法,以及实现都非常棒,非常建议大家把这些论文都过一遍,对于大家深入的了解模型结构是非常有帮助的,这里我也为大家提供了一些论文的笔记(Wide ResNetFractalNet)。就拿Wide ResNet来说,其实他的思路很简单,就是增加ResNet的宽度,也就是模型中每一个卷积层的通道数,原理容易理解,实现起来也非常简单。我们就直接在之前的ResNet-20的基础上进行修改,将它的卷积层的输出通道数增加2倍、4倍和8倍,就得到了3个模型可以来进行比较实验。

在这里提醒大家,ResNet的第一个卷积层不进行扩宽,因此第一个卷积层和第一个Residual Block的通道数就不一样了,无法进行shortcut的连接,那么我们就需要在第一个shortcut上增加一个卷积层来同样的提升feature map的通道数,增加方式可以参考原始ResNet中不同通道数的Residual Block之间的映射shortcut。修改好后可以直接跑起来,如果报错的话根据错误的原因去修改,直到可以跑通。(通过这一步,大家就可以发现,现在已经不用再网上download别人的代码,就可以自己来修改代码实现自己需要的功能了,是不是很赞。)

通过这样一个简单的扩展就实现了Wide ResNet,训练过后测试结果为,2倍的WRNS达到了95%以上,而4倍和8倍的WRNS达到了96%以上, 是不是很赞。

通过模型的扩展,模型的性能得到了质的飞跃,但是同时也带来了运算量、参数量等计算资源的消耗,在实际工程中,我们往往希望在保证一定性能的基础上,尽量的降低运算量和参数量,从而最大可能的利用计算资源,为了达到这个目的,我们也进行也一系列的尝试。

(未完待续)