介绍
此次开辟一个新的话题,叫做prompting learning。prompting learning常用于零样本、小样本领域,通过将下游训练数据转换成预训练模型任务,进行小样本微调或者零样本进行预测。
之前在UIE-事件提取中也有涉及prompt,但是UIE的做法是构造prompt输入,再和原句一起微调模型,完成提取任务。那这里我们来看看OpenPrompt是怎么做的。
关于OpenPrompt,此处不做过多介绍,请直接看官网。
官方有张图阐述了OpenPrompt的架构,请看下图。
下面通过官方示例来说明它的工作原理。
主要模块介绍
1. Template
这个从网上一搜prompting learning,不可避免搜到template,这个是将下游训练数据通过template转换成符合预训练模型任务的训练数据,保持和预训练任务一致。
2. Verbalizer
这个应该怎么翻译呢,姑且称为同义词吧。。。它的作用是从预训练模型vocab中获取符合label的词,比如:
1 | { |
此处先不展开介绍,后续会介绍它的作用和比较坑的地方。
3. PLM
这个就没什么可解释的了,就是预训练模型。
流程
整体流程代码可见附录。
1. 推理
比如这个情感分类任务,经过Template转换后变成了如下:
1 | Albert Einstein was one of the greatest intellects of his time. It was [MASK] |
接着输入给bert模型,拿到mask位置的预测结果output,此时shape为(2, 28996),表示batch_size为2,整个bert vocab size为28996。
那如何将这个预测结果对应到negative
或positive
呢,这里就引出来Verbalizer了。
将['bad', 'good', 'wonderful', 'great']
转成tokenizer vocab的index,然后获取output所对应的index,比如下面伪代码:
1 |
|
样本 | bad | good | wonderful | great |
---|---|---|---|---|
1 | 0.0508 | 0.1770 | 0.9680 | 0.0091 |
2 | 0.2045 | 0.9504 | 0.2127 | 0.1417 |
通过aggreate就拿到最终对应negative和postive的logit了。
2. 训练
1 | print(aggreate(logits, mask)) |
拿到这个后,直接和label做交叉熵不就拿到loss啦~
3. Verbalizer缺点
可看到,['bad', 'good', 'wonderful', 'great']
都是在bert vocab中存在的词,但是在中文里面是以字进行拆分的,那么不会存在不好,精彩,漂亮,优秀...
这种词,即使是在WWM模型里面也不存在这些词,那么这个对中文构造这些verbalizer带来了不足。
而这种方式被称为硬解码,后续再说。
附录
1. 完整代码
1 | # -*- coding: utf8 -*- |