现阶段NLP最火的两个idea 一个是对比学习(contrastive learning) 另一个就是 prompt
prompt 说简单也很简单 看了几篇论文之后发现其实就是构建一个语言模板 但是仔细想想又觉得复杂 总感觉里面还有很多细节 因此我想从头到尾梳理一下prompt 很多地方会把它翻译成[范式] 但是这个词本身不好理解 我个人更倾向于看作是模板
首先我们要知道预训练模型(Bert为首)到底做了什么?
我觉得是预训练模型提供了一个非常好的初始化参数 这组参数在预训练任务上的表现非常好(预训练损失非常低) 但是由于下游任务千奇百怪 我们需要在这组参数的基础上进行 Fine-tune 以适应我们的下游任务(使得下游任务的损失值非常低)目前做 NLP 任务的大致流程 即 "Pre-train, Fine-tune",而对我们来说实际上大部分时候都是直接拿别人预训练好的模型做 Fine-tune 并没有 Pre-train 这一步 融入了 Prompt 的模式大致可以归纳成 "Pre-train, Prompt, and Predict",在该模式中 下游任务被重新调整成类似预训练任务的形式 ok 下面我们举例说明
假设我现在输入一句话:中午我吃了大盘[MASK]
然后得到一个hidden state 最后的答案必须在vocabulary 里面选择 候选词是整个词库 我们这里希望他输出‘鸡’ 实际上可能并不是 我们需要用上loss function 当他预测不对时就会产生损失 有损失我们就可以反向传播 然后逐渐纠正[MASK] 从而符合我们的预期
我们这里调用hugging face 里面的api 来测试一下
可以看到这里输出概率最高的为饭 这说明在预训练的过程中 实际上并没有看到很多大盘和鸡连在一起的情况 看的比较多的情况是 【中午我吃了大盘饭】 但是你拿下游任务做微调的时候 是可以慢慢的让模型输出‘鸡’ 有更高的概率 那么prompt具体是怎么做呢?这里以情感分析为例
假设这是一个二分类问题 积极或者消极原始我输入的是 【今天天气真好】
我们一般的做法是微调 我们会把这个句子送入bert 然后会得到一个句向量 这个句向量有很多处理方式 crf 或者softmax平均 然后会把它送入一个FC层 他的输出维度一定是二维的 因为是二分类 然后我们做argmax或者softmax 然后得到概率最大的那个下标
prompt这样做:我们会在【今天天气真好】前面问一个问题(或者后面中间也可以)我会问后面的句子情感是积极的还是消极的?然后给他一个MASK 我们希望mask输出是积极 那我们就会映射到真是标签1 但是无论是积极或者是消极 这个token 一定要是vocabulary里面存在的
同时 这个prompt并不是固定的 同样的我们在api中测试一下
在这里我们可以把强映射为1 把弱映射为0 这样就能完成我们的情感分析任务
除了情感分析任务 其他 NLP 任务的 Prompt 如何设计?实际上刘鹏飞大神在他的论文中给我们提供了一些参考
大概了解的prompt任务之后 我们从论文的角度再来深挖一下细节
我们可以将prompt的设计涵盖为两部分:
- 模板 T:例如
[