3.7 预训练与微调

3.7.1 什么是预训练和微调

预训练

假如你需要搭建一个网络模型来完成一个特定的图像分类的任务。首先,你需要随机初始化参数,然后开始训练网络,不断调整,直到网络的损失越来越小。在训练的过程中,一开始初始化的参数会不断变化。当你对结果满意时,就可以将训练模型的参数保存下来,以便训练好的模型可以在下次执行类似任务时获得较好的结果。这个过程就是预训练(Pre-Training)。

微调

在完成上面的模型训练后,你又接收到一个类似的图像分类的任务。这时候,你可以直接使用之前保存下来的模型的参数来作为这一任务的初始化参数,然后在训练的过程中,依据结果不断进行一些修改。这时候,你使用的就是一个预训练模型,而过程就是微调(Fine Tuning)。

总结起来,预训练就是指预先训练的一个模型或预先训练模型的过程;微调就是指将预训练过的模型作用于自己的数据集,并使参数适应自己数据集的过程。

3.7.2 预训练和微调的作用

深度网络存在网络越深,需要的训练样本越多的问题,如果采用普通的监督学习方式,则需要大量的标注样本,不然小数据样本会很容易造成过拟合。此时一般的解决办法主要有采用参数初始化的无监督学习方式和采用预训练的监督学习方式,通常经过无监督预训练最终能得到比较好的局部最优解。

比如你想训练一个识别猫的模型,但是你的数据只有100张图片,怎么办呢?此时可以考虑ImageNet数据集,ImageNet有120万张图片,我们可以在ImageNet上训练一个模型,然后使用该模型作为类似任务的初始化或特征提取器。比如VGG、Inception等模型都提供了自己的训练参数,以便人们可以拿来微调。这样既节省了时间和计算资源,又能很快地达到较好的效果。

3.7.3 预训练模型的复用

在根据需要重用预训练模型时,首先要删除原始的分类器,然后添加一个适合的新分类器,最后必须根据以下的三种策略之一对模型进行微调。

(1)训练整个模型。即利用预训练模型的体系结构,根据数据集对其进行训练。如果从零开始学习模型,那么就需要一个大数据集和大量的计算资源。

(2)训练一些层而冻结其他的层。较低层适用的是通用特征,而较高层适用的是特殊特征。通过选择要调整的网络的权重来协调高层特征和底层特征。通常,如果有一个较小的数据集和大量的参数,会冻结更多的层,以避免过拟合。相比之下,如果数据集很大,并且参数的数量很少,那么可以通过给新任务训练更多的层来完善模型,因为此时过拟合的概率很低。

(3)冻结卷积基。卷积基由卷积层和池化层的堆栈组成。这种情况适用于训练/冻结平衡的极端情况。其主要思想是将卷积基保持在原始形式,然后将其输出提供给分类器。

3.7.4 预训练和迁移学习

迁移学习过程主要包含选择预训练模型、根据大小相似性矩阵进行分类及微调模型三个环节。

(1)选择预训练模型。从大量的预训练模型中,可以选择一个适合你要解决的问题的模型,如VGG、Inception v3、MaskRCNN和ResNet-5。

(2)根据大小相似性矩阵进行分类。相似性矩阵表示为象限形式。

象限1:大数据集,但不同于预训练模型的数据集。

象限2:大数据集,类似于预训练模型的数据集。

象限3:小数据集,不同于预训练模型的数据集。

象限4:小数据集,但类似于预训练模型的数据集。

根据大小相似性矩阵进行分类就是根据以上四象限特征进行选择。根据经验,如果每个类的图像少于1000个,则认为是小数据集。就数据集的相似性而言,常识占了上风。例如,如果是识别猫和狗,那么ImageNet将是一个类似的数据集,因为它有猫和狗的图像。然而,如果是识别癌细胞,ImageNet就不行了。

(3)微调模型。这里可以使用大小和相似性矩阵来指导你的选择,然后参考前面提到的重用预训练模型的三个策略进行微调。

3.7.5 微调时网络参数是否更新

微调时网络参数会更新,主要原因如下。

(1)微调的过程相当于继续训练,跟直接训练的区别在于初始化时是否有初始参数。

(2)直接训练是按照网络定义指定的方式初始化,微调是用你已经有的参数文件来初始化。

3.7.6 微调模型的三种状态

微调模型状态总结如下。

(1)状态一:只预测,不训练。特点是相对快、简单,针对那些已经训练好,现在要实际对未知数据进行标注的项目,非常高效。

(2)状态二:训练,但只训练最后分类层。特点是微调模型最终的分类已经符合要求,现在只是在它们的基础上进行类别降维。

(3)状态三:完全训练,分类层和之前卷积层都训练。特点是比较耗时和耗费GPU资源,不过非常适合迁移到自己想要的模型里面,预测精度与状态二相比提高很多。

3.7.7 为什么深层神经网络难以训练

深层网络训练主要存在以下问题。

(1)梯度消失问题。梯度消失是指通过隐含层从后向前看,梯度会变得越来越小,说明前面层的学习会显著慢于后面层的学习,所以学习会卡住,除非梯度变大。梯度消失的原因受到多种因素影响,例如学习率的大小,网络参数的初始化,激活函数的边缘效应等。在深层神经网络中,每一个神经元计算得到的梯度都会传递给前一层,较浅层的神经元接收到的梯度受到之前所有层梯度的影响。如果计算得到的梯度值非常小,随着层数增多,求出的梯度更新信息将会以指数形式衰减,就会发生梯度消失。

(2)梯度爆炸问题。在深度网络或循环神经网络等网络结构中,梯度可在网络更新的过程中不断累积,变成非常大的梯度,导致网络权重值的大幅更新,使网络不稳定;在极端情况下,权重值甚至会溢出,变为NaN值,再也无法更新。

(3)权重矩阵的退化导致模型的有效自由度减少。参数空间中学习的退化速度减慢,导致模型的有效维数减少,网络的可用自由度对学习中梯度范数的贡献不均衡,随着相乘矩阵的数量(即网络深度)的增加,矩阵的乘积变得越来越退化。在有硬饱和边界的非线性网络中(例如Relu网络),随着深度增加,退化过程会变得越来越快。Duvenaud等人在2014年展示了关于该退化过程的可视化,图3-34所示为权重矩阵的退化。

图3-34 权重矩阵的退化

随着深度的增加,输入空间(如图3-34的左上角所示)会在输入空间中的每个点处被扭曲成越来越细的单丝,只有一个与细丝正交的方向影响网络的响应。沿着这个方向,网络对变化非常敏感。