fastai10-NLP
Andrej Karpathy 有一个专栏专门介绍NLP(chat GPT)
在将语言模型转移到分类任务之前,对语言模型进行额外的微调阶段,会导致预测结果显著提高。
文本预处理
我们几乎可以用处理分类变量的方法处理文本, 新的想法是序列的概念.
- 将数据集中的所有文档连接成一个非常长的字符串
- 将其分割成单词, 这样我们就得到了一个非常长的单词列表(或"标记")
- 自变量是我们的长列表中从第一个单词开始到倒数第二个单词结束的单词序列,而因变量将是从第二个单词开始到最后一个单词结束的单词序列
分词
- 基于单词的:将句子按空格分割,并应用特定于语言的规则尝试在无空格的情况下分离意义的部分(例如将"don't"转换为"do n't").通常,标点符号也被分割成单独的标记.
- 基于子词的:将单词分解成更小的部分,基于最常见的子串.例如,"occasion"可能被标记为"o c ca sion".
- 基于字符的:将句子分解为单个字符.
使用fastai进行词条化
xxbos
表示文本的开始xxmaj
表示下一个单词以大写字母开头xxunk
表示该词未知
主要功能简要说明
fix_html
将特殊HTML字符替换为可读版本(IMDb评论中有不少这样的字符)replace_rep
将任何重复三次或更多的字符替换为重复的特殊标记(xxrep
),然后是重复的次数,最后是该字符replace_wrep
将任何重复三次或以上的单词替换为表示单词重复的特殊标记(xxwrep
),然后是该单词重复的次数,最后是该单词spec_add_spaces
添加空格在 / 和 # 周围rm_useless_spaces
移除所有空格字符的重复replace_all_caps
将全大写的单词转换为小写,并在其前面添加一个全大写的特殊标记(xxup
)replace_maj
将大写字母转换为小写,并在其前面添加一个特殊标记,表示大写(xxmaj
)lowercase
将所有文本转换为小写,并在开头(xxbos
)和/或结尾(xxeos
)添加特殊标记
这些规则给人的感受是如果不这样做,训练的时候肯定会出问题
子词分词
效果图
子词分词提供了一种在字符分词(即使用小字符词汇)和词分词(即使用大字符词汇)之间轻松扩展的方法,并且无需开发特定于语言的算法即可处理所有人类语言。它甚至可以处理其他“语言”,例如基因序列或MIDI音乐符号!因此,在过去一年中,它的受欢迎程度飙升,并且似乎很可能成为最常见的分词方法(到您阅读本文时,它可能已经是了!)。
使用fastai进行数值化
这个截屏软件输不了中文
将我们的文本分批用于语言模型
小插曲:看起来deepseek的语言模型词汇表中也使用了xxbos的标签
直接看我们实现的效果
训练文本分类器
文本生成
注意,前面只是引言,从这个地方实际应该重新思考NLP问题--用fastai的方式.实际上感觉不到训练BLP和之前分类问题,表格问题的不同
# 使用 TextBlock 来创建语言模型
get_imdb = partial(get_text_files, folders=['train', 'test', 'unsup'])
dls_lm = DataBlock(
blocks=TextBlock.from_folder(path, is_lm=True),
get_items=get_imdb, splitter=RandomSplitter(0.1)
).dataloaders(path, path=path, bs=128, seq_len=80)
learn = language_model_learner(
dls_lm, AWD_LSTM, drop_mult=0.3,
metrics=[accuracy, Perplexity()]).to_fp16()
learn.fit_one_cycle(1, 2e-2)
# 一旦初始训练完成,我们可以在解冻后继续对模型进行微调
learn.unfreeze()
learn.fit_one_cycle(10, 2e-3)
learn.save_encoder('finetuned')
编码器:不包括特定任务的最终层(们)的模型。这个词在应用于视觉CNN时与“主体”大致相同,但“编码器”在NLP和生成模型中更常用。
到此我们完成的是一个语言生成模型,给它一些关键词就可以开始生成文本, 下面我们将用这个模型
创建分类器数据加载器
它最后这儿的这个操作我没太弄懂, 所以回到了这章节最前面的介绍,有这样的一句话
对于IMDb情感分析任务,数据集包括50,000个额外的电影评论,这些评论没有附带任何正面或负面的标签。由于训练集中有25,000个标记的评论,验证集中有25,000个,总共就有100,000个电影评论。我们可以使用所有这些评论来微调预训练的语言模型,该模型仅在维基百科文章上进行训练;这将得到一个特别擅长预测电影评论下一个单词的语言模型。
这里提到有50000个额外的电影评论没有标签,前面的文本生成器可以用这50000个电影评论进行训练,让它很擅长预测电影评论的下一个单词?然后我再往后看,发现文本生成模型在这里的角色是"编码器"
这里也是创建分类器然后微调,不同在于
使用有区别的学习率和逐步解冻进行训练。在计算机视觉中,我们通常会一次性解冻模型,但对于NLP分类器,我们发现一次解冻几层确实有所不同
总结
在本章中,我们探索了fastai库开箱即用的最后一个应用:文本。我们看到了两种类型的模型:可以生成文本的语言模型,以及可以确定评论是正面还是负面的分类器。为了构建一个最先进的分类器,我们使用了一个预训练的语言模型,将其微调到我们任务的语料库中,然后使用其主体(编码器)与一个新的头来执行分类。