大約一年未動(dòng)筆寫學(xué)習(xí)筆記了底靠,但這一年NLP學(xué)術(shù)領(lǐng)域可謂是飛速發(fā)展。其中最火的兩個(gè)概念就是contrastive Learning(對(duì)比學(xué)習(xí)特铝,simcse 是對(duì)比學(xué)習(xí)框架下較為出名的算法)和 prompt-based learning(模板學(xué)習(xí))暑中。我們都知道AI領(lǐng)域除了算力貴,其實(shí)有價(jià)值的標(biāo)注數(shù)據(jù)也非常昂貴鲫剿。而無論是對(duì)比學(xué)習(xí)還是模板學(xué)習(xí)都開始解決少量標(biāo)注樣本鳄逾,甚至沒有標(biāo)注樣本時(shí),讓模型也能有不錯(cuò)的效果灵莲。這里我通過一個(gè)簡單的文本分類任務(wù)介紹一下傳說中的prompt-based learning雕凹。
NLP 領(lǐng)域中的四范式
學(xué)術(shù)界將NLP任務(wù)的發(fā)展過程,分為下方四個(gè)階段政冻,又稱為NLP四范式枚抵。
第一范式: 基于傳統(tǒng)機(jī)器學(xué)習(xí)模型的范式:比如 tfidf 特征 + 樸素貝葉斯的文本分類任務(wù)
第二范式 : 基于深度學(xué)習(xí) 模型的范式:比如word2vec 特征 + LSTM的文本分類任務(wù)。
相比于第一范式赠幕,模型準(zhǔn)確有所提高俄精,特征工程的工作也有所減少询筏。第三范式: 基于預(yù)訓(xùn)練模型+ fine-tune 的范式: 比如 BERT + finetune 的文本分類任務(wù)榕堰。
相比于第二范式,模型準(zhǔn)確度顯著提高嫌套,但是模型也變得更大逆屡,小數(shù)據(jù)集可以訓(xùn)練出好模型。第四范式:基于預(yù)訓(xùn)練模型+ Prompt + 預(yù)測的范式: 比如 BERT + Prompt 的文本分類任務(wù)
相比于第三范式踱讨,模型訓(xùn)練所需的訓(xùn)練數(shù)據(jù)顯著減少魏蔗。
從整個(gè)發(fā)展過程來看,整個(gè)NLP領(lǐng)域痹筛,朝著 精度更高莺治,少監(jiān)督廓鞠,甚至無監(jiān)督的方向發(fā)展。
而prompt-based learning 算是目前學(xué)術(shù)界向少監(jiān)督谣旁,無監(jiān)督床佳,高精度的方向發(fā)展 最新的研究成果。(畢竟標(biāo)注數(shù)據(jù)很貴榄审,也很難拿到)
prompt baesed learing
prompt baesed learing 本質(zhì)上就是設(shè)計(jì)一個(gè)比較契合上游預(yù)訓(xùn)練模型的模板砌们,讓上游的預(yù)訓(xùn)練模型在盡量不需要標(biāo)注數(shù)據(jù)的情況下比較好的完成下游的任務(wù)
主要包括3個(gè)最關(guān)鍵的步驟。
1.設(shè)計(jì)預(yù)訓(xùn)練的語言模型的任務(wù)(Pretrained Models)
2.設(shè)計(jì)輸入模板樣式 (Prompt Engineering)
3.設(shè)計(jì)label樣式 ,以及模型的輸出映射到label的方式 (Answer Engineering)
其核心奧義通過模板的設(shè)計(jì)就是挖掘出上游預(yù)訓(xùn)練模型的潛力搁进。
下面我們通過一個(gè)文本分類任務(wù)詳細(xì)的了解一下prompt baesed learing 是如何操作的浪感。
prompt 文本分類
整個(gè)prompt 文本分類任務(wù)大致分為如下四個(gè)步驟:
- (1)加載預(yù)訓(xùn)練的語言模型:
本實(shí)驗(yàn)加載了bert-wwm模型 - (2)設(shè)計(jì)一個(gè)符合進(jìn)行下游任務(wù)的輸入模板,設(shè)計(jì)一個(gè)符合下游的label樣式:本實(shí)驗(yàn)的輸入模板和預(yù)測label的樣式如下饼问,
輸入模板: '接下來報(bào)導(dǎo)一則xx新聞,'+ 待預(yù)測的文本
輸出label :["文化"影兽,"娛樂","體育"......] - (3)將自己的數(shù)據(jù)填充到模板匆瓜,并進(jìn)行預(yù)處理:
這里就是將文本需要 處理成Bert的輸入格式赢笨,然后將 "xx新聞" 的xx 用mask_id 替換掉即可(原因:后續(xù)的預(yù)測任務(wù)采樣的bert 的MLM任務(wù)) - (4)設(shè)計(jì)一個(gè)將模型輸出映射到自己label的得分公式,然后進(jìn)行預(yù)測驮吱。
本實(shí)驗(yàn)是采樣的bert MLM的輸出直接預(yù)測被mask的字
其實(shí)不難發(fā)現(xiàn)這里的文本分類任務(wù)茧妒,就是設(shè)計(jì)了一個(gè)類完形填空的模板去挖掘出上游Bert 模型的潛力(Bert的預(yù)訓(xùn)練任務(wù)中有MLM 訓(xùn)練)。
代碼詳解
整個(gè)代碼其實(shí)參考蘇神的 https://github.com/bojone/Pattern-Exploiting-Training左冬,
有興趣的同學(xué)可以去上方鏈接學(xué)習(xí)更多的知識(shí)桐筏。
加載預(yù)訓(xùn)練的語言模型
導(dǎo)入必要的包,同時(shí)加載bert-wwm預(yù)訓(xùn)練模型
import json
import numpy as np
from bert4keras.backend import keras, K
from bert4keras.layers import Loss
from bert4keras.tokenizers import Tokenizer
from bert4keras.models import build_transformer_model
from bert4keras.optimizers import Adam
from bert4keras.snippets import sequence_padding, DataGenerator
from bert4keras.snippets import open
from keras.layers import Lambda, Dense
# 加載預(yù)訓(xùn)練模型和分詞器
config_path = './model/bert_config.json'
checkpoint_path = './model/bert_model.ckpt'
dict_path = './model/vocab.txt'
maxlen = 50
# 這里with_mlm 打開預(yù)測單字模式
model = build_transformer_model(
config_path=config_path, checkpoint_path=checkpoint_path, with_mlm=True
)
tokenizer = Tokenizer(dict_path, do_lower_case=True)
定義好輸入模板和預(yù)測結(jié)果
# 定義好模板
prefix = u'接下來報(bào)導(dǎo)一則xx新聞拇砰。'
mask_idxs = [8, 9]
# 定義類別
labels = [
u'文化', u'娛樂', u'體育', u'財(cái)經(jīng)', u'房產(chǎn)', u'汽車', u'教育', u'科技', u'軍事', u'旅游', u'國際',
u'證券', u'農(nóng)業(yè)', u'電競', u'民生'
]
輸入數(shù)據(jù)預(yù)處理
將xx位置編碼成mask_id ,表示這兩個(gè)字是什么需要mlm去做預(yù)測
##將xx這兩個(gè)字符 用[mask]的id 代替
text = prefix + "長沙驛路高歌路虎極光汽車音響改裝升級(jí)雷貝琴——純凈圓潤"
token_ids, segment_ids = tokenizer.encode(text, maxlen=maxlen)
token_ids[8] = tokenizer._token_mask_id
token_ids[9] = tokenizer._token_mask_id
token_ids = sequence_padding([token_ids])
segment_ids = sequence_padding([segment_ids])
輸出后處理以及結(jié)果預(yù)測
把label中的兩個(gè)字 帶入到 模型在 mask位置輸出中梅忌,計(jì)算得分,然后將兩個(gè)字得分相乘除破,得分label的詞語即為分類結(jié)果牧氮。
注:mask 位置輸出的是兩個(gè) 2w多維的向量。 每個(gè)index中的值 ,代表預(yù)測的字 是詞典中對(duì)映該 index 的字的可能性的大小
label_ids = np.array([tokenizer.encode(l)[0][1:-1] for l in labels])
y_pred = model.predict([token_ids,segment_ids])[:, mask_idxs]
y_pred = y_pred[:, 0, label_ids[:, 0]] * y_pred[:, 1, label_ids[:, 1]]
y_pred = y_pred.argmax(axis=1)
labels[y_pred[0]]
結(jié)語
整個(gè)過程瑰枫,我沒有使用任何標(biāo)注數(shù)據(jù)踱葛,就能成功完成一個(gè)文本分類任務(wù),這確實(shí)證明了模板學(xué)習(xí)的有效光坝。我沒做定量的準(zhǔn)確度評(píng)估尸诽,從這篇文章的定量結(jié)論可以看出,模板學(xué)習(xí)表現(xiàn)其實(shí)并不差盯另,但是目前的水準(zhǔn)還達(dá)不到工業(yè)應(yīng)用的水準(zhǔn)性含。但通過模板發(fā)揮出預(yù)訓(xùn)練模型的潛力,這個(gè)方向還是不錯(cuò)的鸳惯。 筆者曾經(jīng)做過實(shí)驗(yàn)在 有監(jiān)督finetune的時(shí)候加上模板商蕴,也能夠讓模型的效果變得更好叠萍。看來挖掘預(yù)訓(xùn)練模型的潛力绪商,還有很多工作可以做俭令。
參考文獻(xiàn):
https://spaces.ac.cn/archives/7764
https://arxiv.org/pdf/2107.13586.pdf