PyTorch 迁移学习
1661 字约 6 分钟
2026-05-20
2.1 迁移学习理论
学习目标
了解迁移学习中的有关概念.
掌握迁移学习的两种迁移方式.
迁移学习中的有关概念:
- 预训练模型
- 微调
- 微调脚本
预训练模型(Pretrained model):
- 一般情况下预训练模型都是大型模型,具备复杂的网络结构,众多的参数量,以及在足够大的数据集下进行训练而产生的模型. 在NLP领域,预训练模型往往是语言模型,因为语言模型的训练是无监督的,可以获得大规模语料,同时语言模型又是许多典型NLP任务的基础,如机器翻译,文本生成,阅读理解等,常见的预训练模型有BERT, GPT, roBERTa, transformer-XL等.
微调(Fine-tuning):
- 根据给定的预训练模型,改变它的部分参数或者为其新增部分输出结构后,通过在小部分数据集上训练,来使整个模型更好的适应特定任务.
微调脚本(Fine-tuning script):
- 实现微调过程的代码文件。这些脚本文件中,应包括对预训练模型的调用,对微调参数的选定以及对微调结构的更改等,同时,因为微调是一个训练过程,它同样需要一些超参数的设定,以及损失函数和优化器的选取等, 因此微调脚本往往也包含了整个迁移学习的过程.
关于微调脚本的说明:
- 一般情况下,微调脚本应该由不同的任务类型开发者自己编写,但是由于目前研究的NLP任务类型(分类,提取,生成)以及对应的微调输出结构都是有限的,有些微调方式已经在很多数据集上被验证是有效的,因此微调脚本也可以使用已经完成的规范脚本.
两种迁移方式:
- 直接使用预训练模型,进行相同任务的处理,不需要调整参数或模型结构,这些模型开箱即用。但是这种情况一般只适用于普适任务, 如:fasttest工具包中预训练的词向量模型。另外,很多预训练模型开发者为了达到开箱即用的效果,将模型结构分各个部分保存为不同的预训练模型,提供对应的加载方法来完成特定目标.
- 更加主流的迁移学习方式是发挥预训练模型特征抽象的能力,然后再通过微调的方式,通过训练更新小部分参数以此来适应不同的任务。这种迁移方式需要提供小部分的标注数据来进行监督学习.
关于迁移方式的说明:
- 直接使用预训练模型的方式, 已经在fasttext的词向量迁移中学习. 接下来的迁移学习实践将主要讲解通过微调的方式进行迁移学习.
2.4 加载和使用预训练模型
学习目标
- 了解加载和使用预训练模型的工具.
- 掌握加载和使用预训练模型的过程.
加载和使用预训练模型的工具
- 在这里我们使用torch.hub工具进行模型的加载和使用.
- 这些预训练模型由世界先进的NLP研发团队huggingface提供.
- 注意: 下面使用的代码需要国外服务器的资源, 在国内使用的时候, 国内的网站下载可能会出现在原地卡死不动, 或是网络连接超时等一些网络报错, 均是网络问题, 不是代码问题, 这个可以先行跳过, 把主要逻辑梳理完成即可
加载和使用预训练模型的步骤
- 第一步: 确定需要加载的预训练模型并安装依赖包.
- 第二步: 加载预训练模型的映射器tokenizer.
- 第三步: 加载带/不带头的预训练模型.
- 第四步: 使用模型获得输出结果.
第一步: 确定需要加载的预训练模型并安装依赖包
- 能够加载哪些模型可以参考2.3 NLP中的常用预训练模型
- 这里假设我们处理的是中文文本任务, 需要加载的模型是BERT的中文模型: bert-base-chinese
- 在使用工具加载模型前需要安装必备的依赖包:
pip install tqdm boto3 requests regex sentencepiece sacremoses第二步: 加载预训练模型的映射器tokenizer
import torch
# 预训练模型来源
source = 'huggingface/pytorch-transformers'
# 选定加载模型的哪一部分, 这里是模型的映射器
part = 'tokenizer'
# 加载的预训练模型的名字
model_name = 'bert-base-chinese'
tokenizer = torch.hub.load(source, part, model_name)第三步: 加载带/不带头的预训练模型
- 加载预训练模型时我们可以选择带头或者不带头的模型
- 这里的'头'是指模型的任务输出层, 选择加载不带头的模型, 相当于使用模型对输入文本进行特征表示.
- 选择加载带头的模型时, 有三种类型的'头'可供选择, modelWithLMHead(语言模型头), modelForSequenceClassification(分类模型头), modelForQuestionAnswering(问答模型头)
- 不同类型的'头', 可以使预训练模型输出指定的张量维度. 如使用'分类模型头', 则输出尺寸为(1,2)的张量, 用于进行分类任务判定结果.
# 加载不带头的预训练模型
part = 'model'
model = torch.hub.load(source, part, model_name)
# 加载带有语言模型头的预训练模型
part = 'modelWithLMHead'
lm_model = torch.hub.load(source, part, model_name)
# 加载带有类模型头的预训练模型
part = 'modelForSequenceClassification'
classification_model = torch.hub.load(source, part, model_name)
# 加载带有问答模型头的预训练模型
part = 'modelForQuestionAnswering'
qa_model = torch.hub.load(source, part, model_name)第四步: 使用模型获得输出结果
- 使用不带头的模型进行输出:
# 输入的中文文本
input_text = "人生该如何起头"
# 使用tokenizer进行数值映射
indexed_tokens = tokenizer.encode(input_text)
# 打印映射后的结构
print("indexed_tokens:", indexed_tokens)
# 将映射结构转化为张量输送给不带头的预训练模型
tokens_tensor = torch.tensor([indexed_tokens])
# 使用不带头的预训练模型获得结果
with torch.no_grad():
encoded_layers, _ = model(tokens_tensor)
print("不带头的模型输出结果:", encoded_layers)
print("不带头的模型输出结果的尺寸:", encoded_layers.shape)