迁移学习--fasttext概述

迁移学习

1、fasttext概述

作为NLP工程领域常用的工具包, fasttext有两大作用:进行文本分类、训练词向量

正如它的名字, 在保持较高精度的情况下, 快速的进行训练和预测是fasttext的最大优势。fasttext工具包中内含的fasttext模型具有十分简单的网络结构。使用fasttext模型训练词向量时使用层次softmax结构, 来提升超多类别下的模型性能。由于fasttext模型过于简单无法捕捉词序特征, 因此会进行n-gram特征提取以弥补模型缺陷提升精度。

2、fasttext模型架构

FastText 模型架构和 Word2Vec 中的 CBOW 模型很类似, 不同之处在于, FastText 预测标签, 而 CBOW 模型预测中间词。

FastText的模型分为三层架构:

  • 输入层: 是对文档embedding之后的向量, 包含N-gram特征
  • 隐藏层: 是对输入数据的求和平均
  • 输出层: 是文档对应的label

(一)、层次softmax

为了提高效率, 在fastText中计算分类标签概率的时候, 不再使用传统的softmax来进行多分类的计算, 而是使用哈夫曼树, 使用层次化的softmax来进行概率的计算。

(1)、哈夫曼树

当利用n 个结点试图构建一棵树时, 如果构建的这棵树的带权路径长度最小, 称这棵树为“最优二叉树”, 有时也叫“赫夫曼树”或者“哈夫曼树”。

权值越大的节点距离根节点也较近。

(2)、构建哈夫曼树

假设有n个权值, 则构造出的哈夫曼树有n个叶子节点. n个权值分别设为 w1、w2、…、wn, 则哈夫曼树的构造规则为:

  • 步骤1: 将w1、w2、…, wn看成是有n 棵树的森林(每棵树仅有一个节点);
  • 步骤2: 在森林中选出两个根节点的权值最小的树合并, 作为一颗新树的左、右子树, 且新树的根节点权值为其左、右子树根节点权值之和;
  • 步骤3: 从森林中删除选取的两棵树, 并将新树加入森林;
  • 步骤4: 重复2-3步骤, 直到森林只有一颗树为止, 该树就是所求的哈夫曼树。
(3)、哈夫曼树编码

哈夫曼编码一般规定哈夫曼树中的左分支为 0, 右分支为 1, 从根节点到每个叶节点所经过的分支对应的 0 和 1 组成的序列便为该节点对应字符的编码。这样的编码称为哈夫曼编码。

(二)、负采样

(1)、策略

减少计算softmax的token数量。

噪声词获取策略:指定拿到噪声词的数量K,每个噪声词token被取为噪声词的概率为
P=f(ti)0.75∑(f(tj)0.75) P=\frac{f(t_i)^{0.75}}{\sum(f(t_j)^{0.75})} P=(f(tj)0.75)f(ti)0.75

(2)、优势
  • 提高训练速度, 选择了部分数据进行计算损失, 损失计算更加简单
  • 改进效果, 增加部分负样本, 能够模拟真实场景下的噪声情况, 能够让模型的稳健性更强,泛化能力更强

3、fasttext文本分类

  • 模型训练
# 进行文本分类任务(有监督)
'''
input:输入的文本
lr:学习率
epoch:训练轮次
wordNgram:n-gram特征
dim:词向量维度
loss:计算损失的方式,默认是softmax,'hs';还可以选择'ova',代表one vs all,改变意味着我们在统一语料下同时训练多个二分类模型
'''
fasttext.train_supervised()
# 进行文本分类任务(无监督)
fasttext.train_unsupervised()
  • 预测
model.predict('需要预测的内容')

# 返回结果:
# 元组中的第一项代表标签, 第二项代表对应的概率
  • 测试
model.test('验证集/测试集')

# 返回结果:
# 元组中的每项分别代表, 验证集样本数量, 精度以及召回率
  • 保存模型
model.save_model('模型存储位置')
  • 重加载模型
fasttext.load_model('模型存储位置')

4、训练词向量

(一)、训练词向量的过程:

  • 获取数据
  • 训练词向量
  • 模型超参数设定
  • 模型效果检验
  • 模型的保存与重加载

(二)、API

  • 获得指定词汇的词向量
model.get_word_vector(word='指定词汇')
  • 查找邻近词
model.get_nearest_neighbors(word='指定词汇')

5、词向量迁移

大型语料库上已经进行训练完成的词向量模型,我们可以直接使用这些模型,或者对模型进行改造。

  • 下载词向量模型压缩的bin.gz文件
  • 解压bin.gz文件到bin文件
  • 加载bin文件获取词向量
  • 利用邻近词进行效果检验
# 使用gunzip进行解压, 获取cc.zh.300.bin文件
gunzip cc.zh.300.bin.gz
# 加载模型
model = fasttext.load_model("cc.zh.300.bin")
# 使用模型获得'音乐'这个名词的词向量
model.get_word_vector("海鸥")
# 以'音乐'为例, 返回的邻近词基本上与音乐都有关系, 如乐曲, 音乐会, 声乐等
model.get_nearest_neighbors("海鸥")

6、迁移学习

(一)、概述

(1)、预训练模型

一般情况下预训练模型都是大型模型,具备复杂的网络结构,众多的参数量,以及在足够大的数据集下进行训练而产生的模型.。

在NLP领域,预训练模型往往是语言模型。因为语言模型的训练是无监督的,可以获得大规模语料,同时语言模型又是许多典型NLP任务的基础,如机器翻译,文本生成,阅读理解等,

常见的预训练模型有BERT, GPT, roBERTa, transformer-XL

(2)、微调

根据给定的预训练模型,改变它的部分参数或者为其新增部分输出结构后,通过在小部分数据集上训练,来使整个模型更好的适应特定任务

(3)、两种迁移方式
  • 直接使用预训练模型,进行相同任务的处理,不需要调整参数或模型结构,这些模型开箱即用。但是这种情况一般只适用于普适任务, 如:fasttest工具包中预训练的词向量模型。另外,很多预训练模型开发者为了达到开箱即用的效果,将模型结构分各个部分保存为不同的预训练模型,提供对应的加载方法来完成特定目标。

  • 更主流的迁移学习方式是发挥预训练模型特征抽象的能力,然后再通过微调的方式,通过训练更新小部分参数以此来适应不同的任务。这种迁移方式需要提供小部分的标注数据来进行监督学习。

(二)、NLP中常见的预训练模型

(1)、常见的训练模型

BERT、GPT、GPT-2、Transformer-XL、XLNet、XLM、RoBERTa、DistilBERT、ALBERT、T5、XLM-RoBERTa

(2)、BERT及其变体
  • bert-base-uncased: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共110M参数量, 在小写的英文文本上进行训练而得到.
  • bert-large-uncased: 编码器具有24个隐层, 输出1024维张量, 16个自注意力头, 共340M参数量, 在小写的英文文本上进行训练而得到.
  • bert-base-cased: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共110M参数量, 在不区分大小写的英文文本上进行训练而得到.
  • bert-large-cased: 编码器具有24个隐层, 输出1024维张量, 16个自注意力头, 共340M参数量, 在不区分大小写的英文文本上进行训练而得到.
  • bert-base-multilingual-uncased: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共110M参数量, 在小写的102种语言文本上进行训练而得到.
  • bert-large-multilingual-uncased: 编码器具有24个隐层, 输出1024维张量, 16个自注意力头, 共340M参数量, 在小写的102种语言文本上进行训练而得到.
  • bert-base-chinese: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共110M参数量, 在简体和繁体中文文本上进行训练而得到.
(3)、GPT

openai-gpt: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共110M参数量, 由OpenAI在英文语料上进行训练而得到

(4)、GPT-2及其变体
  • gpt2: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共117M参数量, 在OpenAI GPT-2英文语料上进行训练而得到.
  • gpt2-xl: 编码器具有48个隐层, 输出1600维张量, 25个自注意力头, 共1558M参数量, 在大型的OpenAI GPT-2英文语料上进行训练而得到.
(5)、Transformer-XL

transfo-xl-wt103: 编码器具有18个隐层, 输出1024维张量, 16个自注意力头, 共257M参数量, 在wikitext-103英文语料进行训练而得到

(6)、XLNet及其变体
  • xlnet-base-cased: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共110M参数量, 在英文语料上进行训练而得到.
  • xlnet-large-cased: 编码器具有24个隐层, 输出1024维张量, 16个自注意力头, 共240参数量, 在英文语料上进行训练而得到.
(6)、XLM

xlm-mlm-en-2048: 编码器具有12个隐层, 输出2048维张量, 16个自注意力头, 在英文文本上进行训练而得到

(7)、RoBERTa及其变体
  • roberta-base: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共125M参数量, 在英文文本上进行训练而得到.
  • roberta-large: 编码器具有24个隐层, 输出1024维张量, 16个自注意力头, 共355M参数量, 在英文文本上进行训练而得到.
(8)、DistilBERT及其变体
  • distilbert-base-uncased: 基于bert-base-uncased的蒸馏(压缩)模型, 编码器具有6个隐层, 输出768维张量, 12个自注意力头, 共66M参数量.
  • distilbert-base-multilingual-cased: 基于bert-base-multilingual-uncased的蒸馏(压缩)模型, 编码器具有6个隐层, 输出768维张量, 12个自注意力头, 共66M参数量.
(9)、ALBERT
  • albert-base-v1: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共125M参数量, 在英文文本上进行训练而得到.
  • albert-base-v2: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共125M参数量, 在英文文本上进行训练而得到, 相比v1使用了更多的数据量, 花费更长的训练时间.
(10)、T5及其变体
  • t5-small: 编码器具有6个隐层, 输出512维张量, 8个自注意力头, 共60M参数量, 在C4语料上进行训练而得到.
  • t5-base: 编码器具有12个隐层, 输出768维张量, 12个自注意力头, 共220M参数量, 在C4语料上进行训练而得到.
  • t5-large: 编码器具有24个隐层, 输出1024维张量, 16个自注意力头, 共770M参数量, 在C4语料上进行训练而得到.
(11)、XLM-RoBERTa及其变体
  • xlm-roberta-base: 编码器具有12个隐层, 输出768维张量, 8个自注意力头, 共125M参数量, 在2.5TB的100种语言文本上进行训练而得到.
  • xlm-roberta-large: 编码器具有24个隐层, 输出1027维张量, 16个自注意力头, 共355M参数量, 在2.5TB的100种语言文本上进行训练而得到.

(三)、Transformers库使用

(1)、Transformer库三层应用结构
  • 管道(Pipline)方式:高度集成的极简使用方式,只需要几行代码即可实现一个NLP任务。
  • 自动模型(AutoMode)方式:可载入并使用BERTology系列模型。
  • 具体模型(SpecificModel)方式:在使用时,需要明确指定具体的模型,并按照每个BERTology系列模型中的特定参数进行调用,该方式相对复杂,但具有较高的灵活度。
(2)、编码解码函数
<一>、编码
tokenizer.encode()
tokenizer.tokenize()
tokenizer.encode_plus()
tokenizer.batch_encode_plus()
tokenizer.convert_tokens_to_ids()
<1>、tokenizer.encode()
# 1、tokenizer.encode()
# 进行分词和token转换,encode=tokenize+convert_tokens_to_ids
# 单个句子 or 句子列表:分开编码,分开padding,一个句子对应一个向量
# 句子对(pair)和句子元组(tuple):组合编码,统一padding,句子之间用 102 隔开

# 单个句子,默认只返回 input_ids
out = tokenizer.encode(
    text=sents[0],
    truncation=True,
    padding='max_length',
    max_length=20,
    return_tensors='pt'
)
print(out)
print(out.shape)
# exit()

# pair对中的两个句子,合并编码,默认只返回 input_ids
out = tokenizer.encode(
    text=(sents[0], sents[1]),
    truncation=True,
    padding='max_length',
    max_length=20,
    return_tensors='pt',
)
print(out)
print(out.shape)
<2>、tokenizer.tokenize()
# 2、tokenizer.tokenize()
# 只做分词
out = tokenizer.tokenize(
    text=sents[:2],
    truncation=True,
    padding='max_length',
    max_length=20,
    return_tensors='pt'
)
print(out)
<3>、tokenizer.encode_plus()
# 3、tokenizer.encode_plus()
# 在encode的基础之上生成input_ids、token_type_ids、attention_mask
# 单个句子编码,默认返回 input_ids、token_type_ids、attention_mask
out = tokenizer.encode_plus(
    text=sents[0],
    truncation=True,
    padding='max_length',
    max_length=20,
    return_tensors='pt'
)
print(out
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值