小样本学习难点在于:
1.数据量较少,比如10-16个样本
2.fintune后接后置任务模型层,参数比较多
可以把这个问题看成是矩阵求解时候的,函数参数比较多、但是方程等式较少,这样求解方程组会导致方程组的解有很多种,那如何选出符合业务最优解就是个难题,如果随机的选很容易出现选出一个泛化力不够的解。针对这种问题一般的解法有三:
1.增加更多的等式——>增加数据量
2.增加约束条件,让函数参数减少——>引入注意力机制
3.正样本数据少,但有负样本拒绝条件——>数据增强+拒绝采样
历史的fintune,就相当于用足够多的样本对大模型做了带条件的后验分布的修正,让大模型+后验分布修正后分布符合后置任务。
而新出现的prompt Learning相当于是利用了后面两个解法,通过额外的参数引入使得小样本分布可以有目的的采样增长符合预训练模型,使得后置任务模型参数有针对性的减少。
属于小样本学习
小样本学习的几种方法
PET
优点:
1.人工模版,释放预训练模型潜力
2.不引入随机初始化参数,避免过拟合
缺点:
1.稳定性差,不同模版效果相差比较大,考验人选模版能力
2.模版表示无法全局优化
P-TUNING
实现流程:
1.输入时候给prompt预留几个位置+输入文本
2.训练时候prompt除了[MASK]部分,是需要随backgroup做变化的
3.训练几轮稳定后,prompt就自动学出了全局稳定的模版了
优点:
1.可以学习模版参数,全局优化到更好的模版表示
2.缓解人工模版带来的不稳定性
缺点:
1.超多分类任务场景预测难度大
2.蕴含任务不适合基于模版解决
蕴含任务用语言模型预测,比较违反语言模型前后生成文本顺序性要求,如下图:
今天买彩票中奖了,矛盾/蕴含我很生气。完全不通顺
Emtailment as fewshot learning
把所有模版问题转化成二分类问题,通过构造原文本+可能出现的分类模版作为输入,下游接二分类模型判断是否对,有点软件测试断言的意思。
是分类问题,那么就会面临正负样本均衡问题
预测时候增加预测计算量和复杂度
prompt learning有效的原因:
1.模版参数相当于采样过程中真实分布和近似分布的调整因子分布p(x)/q(x)=M,让后置任务数据集分布与训练模型数据集分布一致,减少后置任务和前置任务不一致下模型微调带来的过拟合
2.模版参数的引入,在后置任务学习时,模版参数相当于是任务的attention引导,通过注意力机制对预测模型分布做了微调
3.模版参数引入,在做分类时候限制负样本数据增强的采样,适应预训练模型分布,以致模型不容易过拟合
SongNet(Tencent)控制输出诗词歌赋的字数、平仄和押韵;StylePTB(CMU)按照控制信号改变句子的语法结构、单词形式、语义等;CTRL(Salesforce)在预训练阶段加入了 control codes 与 prompts 作为控制信号,影响文本的领域、主题、实体和风格。可控文本生成模型等方案也多种多样,此处按照进行可控的着手点和切入角度,将可控文本生成方案分为:构造 Control Codes、设计 Prompt、加入解码策略(Decoding Strategy),以及 Write-then-Edit 共四类。
可控就是如何建模出 p(x|a) 这样的概率模型,也就是基于某个属性 a,生成文本 x,获得满意结果。
关于前面几种方法大概分别是这样获得 p(x|a):
CTRL
PPLM
PPLM 最关键的是将 p(x|a) 通过贝叶斯公式改写成了下面形式:
其实这个很好理解,要获得所需基于属性 a 生成文本的 p(x|a)。我们已有一个语言模型 p(x) 能够很好地生成符合自然语言的文本,那么一个非常简单的方法就是用一个分类器(也能是人)来判断语言模型生成的文本 x 是否具有 a 属性,也就是 p(a|x),于是就能获得 p(x|a). 这其实就是文中提到的 rerank 法。
首先解释一点背景知识,在每个 t 时间步上,语言模型 LM 干的活就是基于过去的历史信息 H 来生成当前的输出 o,同时也将当前时间步信息存入历史,用于下一个时间步的生成:
而 p(a|x) 在这的作用是,判断当前生成是否接近属性 a 的需求,根据反馈,去修改之前的历史 H,之后语言模型根据新历史来生成更接近属性 a 需求的句子。
一个好玩的比方是把这个看作时间旅行,比如说大雄跑到未来瞅瞅静香是不是嫁给了他,如果没有就回去改变历史,然后得到一个基于新历史的结果。如何改变历史呢,现实中当然还未实现,但在这里,就可以用到我们的老朋友,反向传播。
通过每次 p(a|x) 的误差传播,可以获得一个梯度,之后用这个更新过去的历史,就可以获得一个新的历史:
变更后的历史就能比较大的概率让语言模型生成我们想要的属性的句子,整个过程大致如下:
总共分三步:
补充一些关于历史 H,还有其梯度更新的其他信息。
虽然上面赋予属性的操作很巧妙,也能保证让文本生成方向朝着属性判别器满意的方向生成,但判别器 p(a|x) 满意并不代表我们会满意。如果只用上面技巧,会导致生成一些有问题的句子,比如说要生成正面的话,那么说不定会疯狂重复,“好好好好好”,这当然不是我们想要的。
我们还是希望能够生成更多样性,并且符合语言模型的句子。因此文中采取了两个保证生成句子的语言模型尽量与原语言模型接近的方法:
通过上面这些步骤实际上相当于完成了一个下图中的过程:
关于具体的属性判别器 p(a|x),文中用了两种不同的方法。
第一种是BOW(词袋) 属性模型,没有额外参数。针对每个主题先总结一批有代表性的词,之后具体实现时只用在每个时间步上对输出概率分布取出对应词袋中词的位置,计算 loss,加和起来反向传播就行。方法虽然简单却意外有效,可以看些例子。
第二种是简单属性分类器,非常少参数。就是在 freeze 住大模型的情况下,拿已有的标注数据,先预训练一个分类器出来。比如文中就用感情分类数据集 SST-5,之后输入GPT2模型,最后一层向量取平均,接着输入分类器分类,训练分类器。
COCON
loss
VAE
训练流程
模块介绍
inverse prompting
self-traning
[pplm]Controlling Text Generation with Plug and Play Language Models - Uber Engineering Blog
[pplm&hugginface]https://github.com/huggingface/transformers/tree/main/examples/research_projects/pplm
[openprompt]https://github.com/thunlp/OpenPrompt
[prompt过去现在未来综述]https://arxiv.org/pdf/2106.07139.pdf