日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

机器学习NLP领域入门

發(fā)布時(shí)間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 机器学习NLP领域入门 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

學(xué)習(xí)路徑:自然語(yǔ)言處理怎么最快入門? - 知乎

Ⅰ. 統(tǒng)計(jì)機(jī)器學(xué)習(xí)


一、HMM隱含馬爾科夫模型

在NLP領(lǐng)域, HMM用來解決文本序列標(biāo)注問題. 如分詞, 詞性標(biāo)注, 命名實(shí)體識(shí)別都可以看作是序列標(biāo)注問題。一般以文本序列數(shù)據(jù)為輸入, 以該序列對(duì)應(yīng)的隱含序列為輸出。HMM屬于生成模型,是有向圖。

1. HMM的基本定義: HMM是用于描述由隱藏的狀態(tài)序列和顯性的觀測(cè)序列組合而成的雙重隨機(jī)過程

2. HMM的假設(shè)

  • 馬爾科夫性假設(shè)。當(dāng)前時(shí)刻的狀態(tài)值,僅依賴于前一時(shí)刻的狀態(tài)值,而不依賴于更早時(shí)刻的狀態(tài)值。(“無記憶性”)
  • 齊次性假設(shè)。狀態(tài)轉(zhuǎn)移概率矩陣與時(shí)間無關(guān)。即所有時(shí)刻共享同一個(gè)狀態(tài)轉(zhuǎn)移矩陣。
  • 觀測(cè)獨(dú)立性假設(shè)。當(dāng)前時(shí)刻的觀察值,僅依賴于當(dāng)前時(shí)刻的狀態(tài)值。

3. HMM的應(yīng)用目的:通過可觀測(cè)到的數(shù)據(jù),預(yù)測(cè)不可觀測(cè)到的數(shù)據(jù)。標(biāo)注任務(wù)中,狀態(tài)值對(duì)應(yīng)著標(biāo)記,任務(wù)會(huì)給定觀測(cè)序列,以預(yù)測(cè)其對(duì)應(yīng)的標(biāo)記序列。

4. 使用HMM的三個(gè)問題:

  • 概率計(jì)算問題:給定模型參數(shù)和觀測(cè)序列,計(jì)算該觀測(cè)序列的概率。是后面兩個(gè)問題的基礎(chǔ)。

HMM三個(gè)參數(shù):A:狀態(tài)轉(zhuǎn)移概率矩陣。表征轉(zhuǎn)移概率,維度為N*N。B:觀測(cè)概率矩陣。表征發(fā)射概率,維度為N*M。π:初始狀態(tài)概率向量。維度為N*1。

  • 學(xué)習(xí)訓(xùn)練問題:給定觀測(cè)序列,估計(jì)模型參數(shù)。

HMM兩種學(xué)習(xí)方式:如果訓(xùn)練數(shù)據(jù)包含觀測(cè)序列和狀態(tài)序列則為有監(jiān)督(通過統(tǒng)計(jì)方法,求得模型的狀態(tài)轉(zhuǎn)移概率矩陣A、觀測(cè)概率矩陣B、初始狀態(tài)概率向量π)
如果訓(xùn)練數(shù)據(jù)只包含觀測(cè)序列則為無監(jiān)督(模型使用Baum-Welch算法來求得模型參數(shù))

  • 解碼預(yù)測(cè)問題:給定模型參數(shù)和觀測(cè)序列,求概率最大的狀態(tài)序列。(維特比算法)

二、CRF模型

CRF(Conditional Random Fields), 中文稱作條件隨機(jī)場(chǎng), 同HMM一樣, 它一般也以文本序列數(shù)據(jù)為輸入, 以該序列對(duì)應(yīng)的隱含序列為輸出。CRF用來解決文本序列標(biāo)注問題. 如分詞, 詞性標(biāo)注, 命名實(shí)體識(shí)別.

  • (1)CRF是判別模型,是黑箱模型,不關(guān)心概率分布情況,只關(guān)心輸出結(jié)果。
  • (2)CRF最重要的工作,是提取特征,構(gòu)建特征函數(shù)
  • (3)CRF使用特征函數(shù)給不同的標(biāo)注網(wǎng)絡(luò)打分,根據(jù)分?jǐn)?shù)選出可能性最高的標(biāo)注網(wǎng)絡(luò)。
  • (4)CRF模型的計(jì)算過程,使用的是以e為底的指數(shù)。這個(gè)建模思路和深度學(xué)習(xí)輸出層的softmax是一致的。先計(jì)算各個(gè)可能情況的分?jǐn)?shù),再進(jìn)行softmax歸一化操作

學(xué)習(xí)訓(xùn)練問題:CRF模型采用正則化的極大似然估計(jì)最大化概率。

預(yù)測(cè)解碼問題:和HMM完全一樣,采用維特比算法進(jìn)行預(yù)測(cè)解碼

HMM與CRF模型之間差異

  • HMM模型存在隱馬假設(shè), 而CRF不存在, 因此HMM的計(jì)算速度要比CRF模型快很多, 適用于對(duì)預(yù)測(cè)性能要求較高的場(chǎng)合.
  • 同樣因?yàn)殡[馬假設(shè), 當(dāng)預(yù)測(cè)問題中隱含序列單元并不是只與上一個(gè)單元有關(guān)時(shí), HMM的準(zhǔn)確率會(huì)大大降低, 而CRF不受這樣限制, 準(zhǔn)確率明顯高于HMM.
  • CRF能夠獲取長(zhǎng)文本的遠(yuǎn)距離依賴的信息,并規(guī)避了齊次性,模型能夠獲取序列的位置信息,并且序列的位置信息會(huì)影響預(yù)測(cè)出的狀態(tài)序列。

命名實(shí)體識(shí)別任務(wù)要在特征編碼層(如RNN、CNN、BERT等 )后接CRF

雙向的LSTM后面接softmax,但此時(shí)輸出標(biāo)簽之間是沒有關(guān)系的,加了CRF后,可以建立起輸出標(biāo)簽之間的關(guān)聯(lián)關(guān)系。

Ⅱ. HuggingFace實(shí)戰(zhàn)


多種多樣的NLP模型

BERT處理各式NLP 任務(wù)的通用架構(gòu)

NLP領(lǐng)域非常流行的兩階段遷移學(xué)習(xí):

  • 先以LM Pretraining 的方式預(yù)先訓(xùn)練出一個(gè)對(duì)自然語(yǔ)言有一定「理解」的通用模型
  • 再將該模型拿來做特征擷取或是fine tune 下游的(監(jiān)督式)任務(wù)

預(yù)訓(xùn)練BERT時(shí)讓它同時(shí)進(jìn)行兩個(gè)任務(wù):

  • MLM:漏字填空(Masked Language Model)
  • NSP:判斷第2個(gè)句子在原始文本中是否跟第1個(gè)句子相接(Next Sentence Prediction, NSP)

BERT中的文本處理

BERT使用當(dāng)初Google NMT提出的WordPiece Tokenization,將本來的words拆成更小粒度的wordpieces,有效處理不在字典里頭的詞匯(OOV)。中文的話大致上就像是character-level tokenization,而有##前綴的tokens即為wordpieces。

以詞匯fragment來說,其可以被拆成frag與##ment兩個(gè)pieces,而一個(gè)word也可以獨(dú)自形成一個(gè)wordpiece。wordpieces可以由搜集大量文本并找出其中常見的pattern取得。

from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained('bert-base-cased')text = "[CLS] 等到潮水 [MASK] 了,就知道誰(shuí)沒穿褲子。" tokens = tokenizer.tokenize(text) #中文斷句 ids = tokenizer.convert_tokens_to_ids(tokens) #轉(zhuǎn)換為文本id

除了一般的wordpieces 以外,BERT 里頭有5 個(gè)特殊tokens 各司其職:

  • [CLS]:在做分類任務(wù)時(shí)其最后一層的repr. 會(huì)被視為整個(gè)輸入序列的repr.
  • [SEP]:有兩個(gè)句子的文本會(huì)被串接成一個(gè)輸入序列,并在兩句之間插入這個(gè)token 以做區(qū)隔
  • [UNK]:沒出現(xiàn)在BERT 字典里頭的字會(huì)被這個(gè) token 取代
  • [PAD]:zero padding 遮罩,將長(zhǎng)度不一的輸入序列補(bǔ)齊方便做batch 運(yùn)算
  • [MASK]:未知遮罩,僅在預(yù)訓(xùn)練階段會(huì)用到
  • 如上例所示,[CLS]一般會(huì)被放在輸入序列的最前面,而zero padding在之前的Transformer文章里已經(jīng)有非常詳細(xì)的介紹。[MASK]token一般在fine-tuning或是feature extraction時(shí)不會(huì)用到

代碼實(shí)例

transformers庫(kù)設(shè)計(jì):

  • Tokenizer 類支持從預(yù)訓(xùn)練模型中進(jìn)行加載或者直接手動(dòng)配置
  • transformers 提供 一系列的Auto classes,使得快速進(jìn)行模型切換非常方便。
  • Head 不同于attention的head,這邊的 head 指的是下游任務(wù)的輸出層,它將模型的contextual embedding 轉(zhuǎn)化為特定任務(wù)的預(yù)測(cè)值
  • Pretraining Head
    • Casual Language Modeling(普通自回歸的語(yǔ)言模型):GPT, GPT-2,CTRL
    • Masked Language Modeling(掩碼語(yǔ)言模型):BERT, RoBERTa
    • Permuted Language Modeling(亂序重排語(yǔ)言模型):XLNet
  • Fine-tuning Head
    • Language Modeling:語(yǔ)言模型訓(xùn)練,預(yù)測(cè)下一個(gè)詞。主要用于文本生成
    • Sequence Classification:文本分類任務(wù),情感分析任務(wù)
    • Question Answering:機(jī)器閱讀理解任務(wù),QA
    • Token Classification:token級(jí)別的分類,主要用于命名實(shí)體識(shí)別(NER)任務(wù),句法解析Tagging任務(wù)
    • Multiple Choice:多選任務(wù),主要是文本選擇任務(wù)
    • Masked LM:掩碼預(yù)測(cè),隨機(jī)mask一個(gè)token,預(yù)測(cè)該 token 是什么詞,用于預(yù)訓(xùn)練
    • Conditional Generation:條件生成任務(wù),主要用于翻譯以及摘要任務(wù)。
#導(dǎo)入模型和對(duì)應(yīng)分詞器 from transformers import BertModel, BertTokenizer, CTRLModel, CTRLTokenizer, TransfoXLModel, TransfoXLTokenizer, XLNetModel, XLNetTokenizer, XLMModel, XLMTokenizer, DistilBertModel, DistilBertTokenizer, RobertaModel, RobertaTokenizerfrom transformers import AutoTokenizer, AutoModelForMaskedLM#載入預(yù)訓(xùn)練數(shù)據(jù) tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese") model = AutoModelForMaskedLM.from_pretrained("bert-base-chinese")vocab = tokenizer.vocab #字典大小#進(jìn)行下游的文本分類任務(wù) from transformers import AutoModelForSequenceClassification model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=2

encode和encode_plus和tokenizer的區(qū)別

Tokenizer 返回的是一個(gè)字典,里面的列表包含了int類別的數(shù)據(jù)。

encoded_input = tokenizer("Hello, I'm a single sentence!") print(encoded_input) # {'input_ids': [101, 138, 18696, 155, 1942, 3190, 1144, 1572, 13745, 1104, 159, 9664, 2107, 102], # 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
  • “input_id”是對(duì)應(yīng)于文本序列中每個(gè)token的索引(在vocab中的索引);
  • “token_type_ids”是對(duì)應(yīng)于不同的文本序列,例如在NSP(BERT及某些語(yǔ)言模型中的“Next Sentence Prediction”)任務(wù)中需要輸入兩個(gè)文本序列。
  • “attention_mask”是對(duì)應(yīng)于注意力機(jī)制的計(jì)算,各元素的值為0或1,如果當(dāng)前token被mask或者是只是用來作為填充的元素,那么其不需要進(jìn)行注意力機(jī)制的計(jì)算,其值為0;

tokenizer解碼:

tokenizer.decode(encoded_input["input_ids"]) # "[CLS] Hello, I'm a single sentence! [SEP]"

[CLS]字符就是大多數(shù)預(yù)訓(xùn)練語(yǔ)言模型會(huì)自動(dòng)加入的特殊token。tokenizer會(huì)自動(dòng)添加了模型期望的一些特殊token。可以通過傳遞add_special_tokens = False來禁用加入特殊token

tokenizer也可輸入列表:

batch_sentences = ["Hello I'm a single sentence","And another sentence","And the very very last one"] encoded_inputs = tokenizer(batch_sentences) print(encoded_inputs) # {'input_ids': [[101, 8667, 146, 112, 182, 170, 1423, 5650, 102], # [101, 1262, 1330, 5650, 102], # [101, 1262, 1103, 1304, 1304, 1314, 1141, 102]], # 'token_type_ids': [[0, 0, 0, 0, 0, 0, 0, 0, 0], # [0, 0, 0, 0, 0], # [0, 0, 0, 0, 0, 0, 0, 0]], # 'attention_mask': [[1, 1, 1, 1, 1, 1, 1, 1, 1], # [1, 1, 1, 1, 1], # [1, 1, 1, 1, 1, 1, 1, 1]]}

填充(padding)和截?cái)?#xff08;truncation)

一個(gè)batch中的序列長(zhǎng)度不一致時(shí),

三個(gè)參數(shù)padding,truncation和max_length

encode和encode_plus的區(qū)別

1. encode僅返回input_ids
2. encode_plus返回所有的編碼信息,具體如下:
’input_ids:是單詞在詞典中的編碼
‘token_type_ids’:區(qū)分兩個(gè)句子的編碼(上句全為0,下句全為1)
‘a(chǎn)ttention_mask’:指定對(duì)哪些詞進(jìn)行self-Attention操作

import torch from transformers import BertTokenizermodel_name = 'bert-base-uncased'# a.通過詞典導(dǎo)入分詞器 tokenizer = BertTokenizer.from_pretrained(model_name) sentence = "Hello, my son is laughing."print(tokenizer.encode(sentence)) print(tokenizer.encode_plus(sentence))#[101, 7592, 1010, 2026, 2365, 2003, 5870, 1012, 102] #{'input_ids': [101, 7592, 1010, 2026, 2365, 2003, 5870, 1012, 102], #'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0], #'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}

學(xué)習(xí)率預(yù)熱

from transformers import get_cosine_schedule_with_warmup,get_linear_schedule_with_warmupsch = get_linear_schedule_with_warmup(optimizer, #優(yōu)化器 包含lr參數(shù)num_warmup_steps= 0, #預(yù)熱階段的步驟數(shù)num_training_steps, #訓(xùn)練的總步驟數(shù)last_epoch=-1 #恢復(fù)訓(xùn)練時(shí)最后一個(gè)epoch的索引 )

Ⅲ. NLP對(duì)抗訓(xùn)練


對(duì)抗訓(xùn)練有兩個(gè)作用,一是提高模型對(duì)惡意攻擊的魯棒性,二是提高模型的泛化能力

對(duì)抗訓(xùn)練旨在對(duì)原始輸入樣本 x 上施加擾動(dòng) r_adv?,得到對(duì)抗樣本后用其進(jìn)行訓(xùn)練:

  • 最大化擾動(dòng):挑選一個(gè)能使得模型產(chǎn)生更大損失(梯度較大)的擾動(dòng)量,作為攻擊;
  • 最小化損失:根據(jù)最大的擾動(dòng)量,添加到輸入樣本后,朝著最小化含有擾動(dòng)的損失(梯度下降)方向更新參數(shù);

這個(gè)被構(gòu)造出來的“對(duì)抗樣本”并不能具體對(duì)應(yīng)到某個(gè)單詞,因此,反過來在推理階段是沒有辦法通過修改原始輸入得到這樣的對(duì)抗樣本。

常用的幾種對(duì)抗訓(xùn)練方法有FGSM、FGM、PGD、FreeAT、YOPO、FreeLB、SMART。

一、FGM算法

  • 首先計(jì)算輸入樣本x(通常為word embedding)的損失函數(shù)以及在x 處的梯度:
  • 計(jì)算在輸入樣本的擾動(dòng)量: ,其中 ? 為超參數(shù),默認(rèn)取1.0;
  • 得到對(duì)抗樣本:
  • 根據(jù)得到的對(duì)抗樣本,再次喂入模型中,計(jì)算損失,并累積梯度;
  • 恢復(fù)原始的word embedding,接著下一個(gè)batch。
import torch class FGM():def __init__(self, model):self.model = modelself.backup = {} # 用于保存模型擾動(dòng)前的參數(shù)def attack(self, epsilon=1., emb_name='word_embeddings' # emb_name表示模型中embedding的參數(shù)名):'''生成擾動(dòng)和對(duì)抗樣本'''for name, param in self.model.named_parameters(): # 遍歷模型的所有參數(shù) if param.requires_grad and emb_name in name: # 只取word embedding層的參數(shù)self.backup[name] = param.data.clone() # 保存參數(shù)值norm = torch.norm(param.grad) # 對(duì)參數(shù)梯度進(jìn)行二范式歸一化if norm != 0 and not torch.isnan(norm): # 計(jì)算擾動(dòng),并在輸入?yún)?shù)值上添加擾動(dòng)r_at = epsilon * param.grad / normparam.data.add_(r_at)def restore(self, emb_name='word_embeddings' # emb_name表示模型中embedding的參數(shù)名):'''恢復(fù)添加擾動(dòng)的參數(shù)'''for name, param in self.model.named_parameters(): # 遍歷模型的所有參數(shù)if param.requires_grad and emb_name in name: # 只取word embedding層的參數(shù)assert name in self.backupparam.data = self.backup[name] # 重新加載保存的參數(shù)值self.backup = {}

訓(xùn)練的時(shí)候再添加五行:

fgm = FGM(model) # (#1)初始化 for batch_input, batch_label in data:loss = model(batch_input, batch_label) # 正常訓(xùn)練loss.backward() # 反向傳播,得到正常的grad# 對(duì)抗訓(xùn)練fgm.attack() # (#2)在embedding上添加對(duì)抗擾動(dòng)loss_adv = model(batch_input, batch_label) # (#3)計(jì)算含有擾動(dòng)的對(duì)抗樣本的lossloss_adv.backward() # (#4)反向傳播,并在正常的grad基礎(chǔ)上,累加對(duì)抗訓(xùn)練的梯度fgm.restore() # (#5)恢復(fù)embedding參數(shù)# 梯度下降,更新參數(shù)optimizer.step()model.zero_grad()

二、PGD算法

Project Gradient Descent(PGD)是一種迭代攻擊算法,相比于普通的FGM 僅做一次迭代,PGD是做多次迭代,每次走一小步,每次迭代都會(huì)將擾動(dòng)投射到規(guī)定范圍內(nèi)。形式化描述為:

擾動(dòng)約束空間為一個(gè)球體,原始的輸入樣本對(duì)應(yīng)的初識(shí)點(diǎn)為球心,迭代多次后,避免擾動(dòng)超過球面。

import torch class PGD():def __init__(self, model):self.model = modelself.emb_backup = {}self.grad_backup = {}def attack(self, epsilon=1., alpha=0.3, emb_name='word_embeddings', is_first_attack=False):for name, param in self.model.named_parameters():if param.requires_grad and emb_name in name:if is_first_attack:self.emb_backup[name] = param.data.clone()norm = torch.norm(param.grad)if norm != 0 and not torch.isnan(norm):r_at = alpha * param.grad / normparam.data.add_(r_at)param.data = self.project(name, param.data, epsilon)def restore(self, emb_name='word_embeddings'):for name, param in self.model.named_parameters():if param.requires_grad and emb_name in name: assert name in self.emb_backupparam.data = self.emb_backup[name]self.emb_backup = {}def project(self, param_name, param_data, epsilon):r = param_data - self.emb_backup[param_name]if torch.norm(r) > epsilon:r = epsilon * r / torch.norm(r)return self.emb_backup[param_name] + rdef backup_grad(self):for name, param in self.model.named_parameters():if param.requires_grad:self.grad_backup[name] = param.grad.clone()def restore_grad(self):for name, param in self.model.named_parameters():if param.requires_grad:param.grad = self.grad_backup[name]

訓(xùn)練的時(shí)候添加:

pgd = PGD(model) K = 3 for batch_input, batch_label in data:# 正常訓(xùn)練loss = model(batch_input, batch_label)loss.backward() # 反向傳播,得到正常的gradpgd.backup_grad()# 累積多次對(duì)抗訓(xùn)練——每次生成對(duì)抗樣本后,進(jìn)行一次對(duì)抗訓(xùn)練,并不斷累積梯度for t in range(K):pgd.attack(is_first_attack=(t==0)) # 在embedding上添加對(duì)抗擾動(dòng), first attack時(shí)備份param.dataif t != K-1:model.zero_grad()else:pgd.restore_grad()loss_adv = model(batch_input, batch_label)loss_adv.backward() # 反向傳播,并在正常的grad基礎(chǔ)上,累加對(duì)抗訓(xùn)練的梯度pgd.restore() # 恢復(fù)embedding參數(shù)# 梯度下降,更新參數(shù)optimizer.step()model.zero_grad()

三、VAT虛擬對(duì)抗訓(xùn)練

抽取一個(gè)隨機(jī)標(biāo)準(zhǔn)正態(tài)擾動(dòng),加到embedding上,并用KL散度計(jì)算擾動(dòng)的梯度,然后用得到的梯度,計(jì)算對(duì)抗擾動(dòng),并進(jìn)行對(duì)抗訓(xùn)練,實(shí)現(xiàn)方法跟FGM差不多。特別提到的一點(diǎn)是,因?yàn)槠渌悸芬灿蓄~外的一致性損失的loss,因此可以用于半監(jiān)督學(xué)習(xí),在無監(jiān)督數(shù)據(jù)集合上計(jì)算一致性的loss。

Ⅳ. NLP比賽提分技巧


1. EMA指數(shù)移動(dòng)平均

EMA在深度學(xué)習(xí)的優(yōu)化過程中,是t時(shí)刻的模型權(quán)重weights,是t時(shí)刻的影子權(quán)重(shadow weights)。在梯度下降的過程中,會(huì)一直維護(hù)著這個(gè)影子權(quán)重,但是這個(gè)影子權(quán)重并不會(huì)參與訓(xùn)練。基本的假設(shè)是,模型權(quán)重在最后的n步內(nèi),會(huì)在實(shí)際的最優(yōu)點(diǎn)處抖動(dòng),所以我們?nèi)∽詈髇步的平均,能使得模型更加的魯棒

EMA對(duì)第i步的梯度下降的步長(zhǎng)增加了權(quán)重系數(shù) ,相當(dāng)于做了一個(gè)learning rate decay

在保存模型或者評(píng)估模型時(shí),會(huì)利用影子權(quán)重進(jìn)行評(píng)估,如果效果比當(dāng)前效果好,則保存影子權(quán)重的參數(shù),但是之后在繼續(xù)訓(xùn)練的時(shí)候會(huì)還原之前的參數(shù)進(jìn)行訓(xùn)練。

class EMA():def __init__(self, model, decay):self.model = modelself.decay = decayself.shadow = {}self.backup = {}def register(self):for name, param in self.model.named_parameters():if param.requires_grad:self.shadow[name] = param.data.clone()def update(self):for name, param in self.model.named_parameters():if param.requires_grad:assert name in self.shadownew_average = (1.0 - self.decay) * param.data + self.decay * self.shadow[name]self.shadow[name] = new_average.clone()def apply_shadow(self):for name, param in self.model.named_parameters():if param.requires_grad:assert name in self.shadowself.backup[name] = param.dataparam.data = self.shadow[name]def restore(self):for name, param in self.model.named_parameters():if param.requires_grad:assert name in self.backupparam.data = self.backup[name]self.backup = {}# 初始化 ema = EMA(model, 0.999) ema.register()# 訓(xùn)練過程中,更新完參數(shù)后,同步update shadow weights def train():optimizer.step()ema.update()# eval前,apply shadow weights;eval之后,恢復(fù)原來模型的參數(shù) def evaluate():ema.apply_shadow()# evaluateema.restore()

2. UDPLoss, RDropLoss

在正常的監(jiān)督學(xué)習(xí)損失外,增加一個(gè)一致性損失((一般是kl散度)),也有多drop層這種

Ⅴ. 實(shí)戰(zhàn)匯總

Kaggle 專利匹配比賽賽后總結(jié)

雜文:NLP競(jìng)賽&競(jìng)賽tricks整理 - 知乎

Ⅵ. 提分策略

新手入門 Kaggle NLP類比賽總結(jié) - 知乎

SWA, Apex AMP & Interpreting Transformers in Torch | Kaggle

Utilizing Transformer Representations Efficiently | Kaggle

NLP比賽中有哪些常用的Trick? - 墨天輪

1.文本特征token:長(zhǎng)度(Seq Length)限制進(jìn)行截?cái)?/span>

  • pre-truncate
  • post-truncate
  • middle-truncate (head + tail)

?2.增加特征(附加信息)

  • Bert 輸入端,添加 special tokens(如類別信息 [CAT=CULTURE])
tokens : [CLS] [CAT=CULTURE] question [SEP] answer [SEP] input_ids : 101 1 3322 102 9987 102 segment_ids: 0 0 0 0 1 1
  • Bert 輸出端,直接做 embedding,?然后與文本特征的 Vector Representation 進(jìn)行融合
emb = nn.Embedding(10, 32) # 初始化一個(gè) Embedding 層meta_vector = emb(cat) # 將類別編碼成 vectorlogits = torch.cat([txt_vector, meta_vector], dim=-1) # 文本向量和類別向量融合

3. Pseudo-labeling

1. 訓(xùn)練集上訓(xùn)練得到 model1; 2. 使用 model1 在測(cè)試集上做預(yù)測(cè)得到有偽標(biāo)簽的測(cè)試集; 3. 使用訓(xùn)練集+帶偽標(biāo)簽的測(cè)試集訓(xùn)練得最終模型 model2;

偽標(biāo)簽數(shù)據(jù)可以作為訓(xùn)練數(shù)據(jù)而被加入到訓(xùn)練集中,是因?yàn)樯窠?jīng)網(wǎng)絡(luò)模型有一定的容錯(cuò)能力。需要注意的是偽標(biāo)簽數(shù)據(jù)質(zhì)量可能會(huì)很差,在使用過程中要多加小心,比如不要用在 validation set 中。

4. pooling技巧

Transformers?三種輸出形式:

  • pooler output?(batch size, hidden size) : 句嵌入,即CLS token的embedding
  • last hidden state?(batch size, seq Len, hidden size) 最后隱藏層
  • hidden states?(n layers, batch size, seq Len, hidden size) - 所有的隱藏層

Weighted Layer Pooling

5.?隨機(jī)權(quán)重平均(SWA)

SWA通過對(duì)訓(xùn)練過程中多個(gè)時(shí)間點(diǎn)的模型權(quán)重(checkpoint)求平均達(dá)到集成的效果,并且該方法不會(huì)為訓(xùn)練增加額外的消耗,也不會(huì)增加計(jì)算量,同時(shí)該方法還可以嵌入到Pytorch中的任何優(yōu)化器類中。

Stochastic Weight Averaging in PyTorch | PyTorch?(即插即用?)

6.?Multi-Sample Dropout

可以看做是對(duì)傳統(tǒng)dropout的一種改進(jìn),同一樣本經(jīng)過多次dropout, 由于dropout具有隨機(jī)性,可以得到多個(gè)不同的樣本。基于連續(xù)的dropout,加快模型收斂,提升泛化能力。

7. 分層學(xué)習(xí)率

def get_grouped_params(args, model):no_decay = ["bias", "LayerNorm.weight"]group1 = ['layer.0.', 'layer.1.', 'layer.2.', 'layer.3.']group2 = ['layer.4.', 'layer.5.', 'layer.6.', 'layer.7.']group3 = ['layer.8.', 'layer.9.', 'layer.10.', 'layer.11.']group_all = ['layer.0.', 'layer.1.', 'layer.2.', 'layer.3.', 'layer.4.', 'layer.5.', 'layer.6.', 'layer.7.','layer.8.', 'layer.9.', 'layer.10.', 'layer.11.']optimizer_grouped_parameters = [{'params': [p for n, p in model.bert_named_params() if not any(nd in n for nd in no_decay) and not any(nd in n for nd in group_all)],'weight_decay': args.weight_decay},{'params': [p for n, p in model.bert_named_params() if not any(nd in n for nd in no_decay) and any(nd in n for nd in group1)],'weight_decay': args.weight_decay, 'lr': args.bert_lr 2},{'params': [p for n, p in model.bert_named_params() ifnot any(nd in n for nd in no_decay) and any(nd in n for nd in group2)],'weight_decay': args.weight_decay, 'lr': args.bert_lr},{'params': [p for n, p in model.bert_named_params() ifnot any(nd in n for nd in no_decay) and any(nd in n for nd in group3)],'weight_decay': args.weight_decay, 'lr': args.bert_lr * 2},{'params': [p for n, p in model.bert_named_params() ifany(nd in n for nd in no_decay) and not any(nd in n for nd in group_all)], 'weight_decay': 0.0},{'params': [p for n, p in model.bert_named_params() ifany(nd in n for nd in no_decay) and any(nd in n for nd in group1)], 'weight_decay': 0.0,'lr': args.bert_lr 2},{'params': [p for n, p in model.bert_named_params() ifany(nd in n for nd in no_decay) and any(nd in n for nd in group2)], 'weight_decay': 0.0,'lr': args.bert_lr},{'params': [p for n, p in model.bert_named_params() ifany(nd in n for nd in no_decay) and any(nd in n for nd in group3)], 'weight_decay': 0.0,'lr': args.bert_lr * 2},{'params': [p for n, p in model.base_named_params()], 'lr': args.learning_rate, "weight_decay": args.weight_decay}]return optimizer_grouped_parametersoptimizer_bert_parameters = get_grouped_params(args, model) optimizer = torch.optim.AdamW(optimizer_bert_parameters, lr=args.bert_lr, eps=args.eps)

Ⅶ.模型加速

Transformers 優(yōu)化方法匯總 - 知乎

  • 梯度累加(Gradient Accumulation):調(diào)整更新步長(zhǎng),模擬大批量
  • 自動(dòng)混合精度(AMP):梯度縮放

推薦閱讀 / Ref

NLP硬核入門-隱馬爾科夫模型HMM - 知乎

NLP幾種常用的對(duì)抗訓(xùn)練方法_華師數(shù)據(jù)學(xué)院·王嘉寧的博客-CSDN博客_nlp對(duì)抗訓(xùn)練

NLP煉丹技巧合集

總結(jié)

以上是生活随笔為你收集整理的机器学习NLP领域入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。