预训练模型简介
预训练模型是一种深度学习的方法(强化学习中就基本没有预训练方法),它利用大量的无标注数据来训练一个通用的模型,然后在特定的任务上进行微调,以适应不同的场景和需求。比如NLP中的BERT,CV中的ResNet、Swin Transformer。预训练模型可以学习到语言的通用知识和特征,提高模型的泛化能力和鲁棒性。
预训练-微调方法指的是首先在大数据集上训练得到一个具有强泛化能力的模型(预训练模型),然后在下游任务上进行微调的过程。预训练-微调方法属于基于模型的迁移方法(Parameter/Model-based TransferLearning)。该大类方法旨在从源域和目标域中找到它们之间共享的参数信息以实现迁移。
此迁移方式要求的假设条件是:源域中的数据与目标域中的数据可以共享一些模型的参数。
预训练语言模型采用两阶段学习方法,首先在大型语料库中训练模型,使模型学习通用语言表示,再根据不同的下游任务对预训练模型进行微调:
-
预训练阶段
预训练阶段是指在大规模的无标注数据上,使用一种或多种自监督学习的方式,来训练一个通用的语言模型。自监督学习是指利用数据本身的结构或规律,来生成标签或目标,从而实现无监督或半监督的学习。
-
微调阶段
微调阶段是指在特定的任务上,使用少量的有标注数据,来对预训练好的模型进行调整和优化。微调阶段通常有两种方法:feature-based 和 fine-tuning。通过微调阶段,模型可以学习到特定任务相关的知识和特征,例如情感分类、命名实体识别、机器翻译等。这些知识和特征可以提高模型在特定任务上的性能和效率。
微调具有如下优势:
- 不需要针对新任务从头开始训练网络,节省了时间成本;
- 预训练好的模型通常都是在大数据集上进行的,无形中扩充了我们的训练数据,使得模型更鲁棒、泛化能力更好;
- 微调实现简单,使我们只关注自己的任务即可
模型的性能
预训练模型是已经经过大量数据集训练过的模型,可直接进行使用。例如BERT模型就是一个著名的预训练模型。由于预训练模型所需的数据集非常大,因此一般来说它们的性能会比自己训练的模型更好。而自己训练的模型则受到训练数据集大小的限制,很难达到预训练模型的性能。
举个例子,假设我们要训练一个文本分类模型,预训练模型和自己训练的模型分别在同样的数据集上进行训练。实验结果表明,预训练模型可以达到90%的准确率,而自己训练的模型只能达到70%的准确率
模型的复用性
预训练模型通常可以通过简单的微调来适应各种不同的任务。这使得相同的预训练模型在多种不同的领域都可以得到很好的应用。例如,BERT模型已经在各种自然语言处理领域得到广泛的应用。
而自己训练的模型通常只适用于特定的任务和数据集。如果我们需要将自己训练的模型应用到其他领域,我们可能需要重新训练模型或修改模型结构以适应新的数据集。
预训练模型的使用
使用预训练模型的一些步骤:
1)选择与要解决问题相关的预训练模型。例如,想在图像分类任务中使用预训练模型,则可以选择像ResNet、Inception、VGG等预训练模型。
2)对预训练模型进行微调以适应新的任务。微调意味着在已经训练好的模型上进行额外的训练,以使其适应新的任务。这通常涉及到更改模型的最后一层或几层。
3)用新场景的数据集训练模型。
4)对模型进行评估和优化。使用新场景的测试数据对模型进行评估,以确定模型是否达到性能目标,并对其进行调整以进一步优化性能。
5)使用优化后的模型进行推断。将训练好的模型应用于解决特定问题的新数据集。
以上是使用预训练模型的一些基本步骤。但是,具体的步骤会因使用的预训练模型和任务而有所不同。整体而言,有两种场景:
● 同任务、不同数据集;
● 不同任务
-
同任务、不同数据集
对于同任务、不同数据集来说,使用预训练模型更简单一些。
举个例子,现在我们有个任务:需要识别出监控视角下的People和Car,这属于CV目标检测一类的任务。在目标检测任务中,YOLO系列算是性能最优的模型,People和Car这两个类型刚好又在YOLO官网提供的原生模型80分类范围内,直接使用原生YOLO模型,没有问题,但由于原生模型是基于COCO数据集训练,和我们的监控视角数据集显然有所区别,因此,使用监控视角数据集进行微调,可以进一步提升模型精度。
由于新的数据集只需要关心People和Car两个类型,这时候,有两种方式可供选择:
1)Linear protocal:冻结原始模型的所有层,只修改分类数量相关的层,新的数据只用来训练该层参数。这种方法由于训练的参数更少,因此训练速度更快,通常在训练数据较少的时候使用。
2)Finetune:不冻结原始模型的所有层,修改分类数量,新的数据对整个模型参数进行微调。
通常而言,方法2)训练速度更慢一些,但对新的数据集的拟合效果更好。但具体到底哪种方式更好,还需要做比对实验。
在YOLO中,上面这种情况,只需要修改配置文件中的几个参数,就可以完成类型数量的改变,其采用方法2)的方式进行微调。
-
不同任务
对于不同任务而言,使用预训练模型,通常需要:
● 收集新任务数据,并根据任务进行标注;
● 去掉新任务不需要的层;
● 增加新任务需要的层;
● 构建新任务有效的Loss。
举个例子:我们想用ResNet预训练模型作为我们的特征提取器,然后做目标检测。这里我们需要做的事情是:
1)获取可以训练的数据;
2)去掉ResNet中最后分类的层,包括Softmax、FC;
3)增加检测任务需要的检测头,比如像Faster R-CNN中的检测头
4)构建新任务的Loss;
5)Finetune。
参考:
https://zhuanlan.zhihu.com/p/557958732?utm_id=0
https://www.python100.com/html/34OD3OSV623C.html
https://zhuanlan.zhihu.com/p/623455256