NLP中的Mask全解
?PaperWeekly 原創 ·?作者|海晨威
學校|同濟大學碩士生
研究方向|自然語言處理
Mask 在 NLP 中是一個很常規的操作,也有多種應用的場景和形式,下面嘗試從以下幾個方面去全解(用了夸張的修辭手法)Mask,并盡可能地輔以圖片說明和代碼解釋:?
1. Mask 的作用?
處理非定長序列
RNN 中的 Mask?
Attention 中 Mask?
2. 防止標簽泄露?
Transformer 中的 Mask?
BERT 中的 Mask?
XLNet 中的 Mask
Mask的作用
對于 NLP 中 mask 的作用,先上結論:?
1. padding mask:處理非定長序列,區分 padding 和非 padding 部分,如在 RNN 等模型和 Attention 機制中的應用等;
2. sequence mask:防止標簽泄露,如:Transformer decoder 中的 mask 矩陣,BERT 中的 [Mask] 位,XLNet 中的 mask 矩陣等。
PS:padding mask 和 sequence mask非官方命名。
處理非定長序列?
在 NLP 中,文本一般是不定長的,所以在進行 batch 訓練之前,要先進行長度的統一,過長的句子可以通過 truncating 截斷到固定的長度,過短的句子可以通過 padding 增加到固定的長度,但是 padding 對應的字符只是為了統一長度,并沒有實際的價值,因此希望在之后的計算中屏蔽它們,這時候就需要 Mask。
上圖(圖片參考?[1])為中文場景下,一個 batch=5 的,以字為單位的輸入矩陣(也可以在分詞后以詞為單位)和 mask 矩陣,左圖已經將文本 padding 到統一長度了,右圖中的 1 表示有效字,0 代表無效字。
RNN中的Mask?
對于 RNN 等模型,本身是可以直接處理不定長數據的,因此它不需要提前告知? sequence length,如下是 PyTorch 下的 LSTM 定義:
nn.LSTM(input_size,?hidden_size,?*args,?**kwargs)最終,R-MeN 將這 3 個編碼向量反饋給基于 CNN 的解碼器,返回一個三元組的得分。
但是在實踐中,為了 batch 訓練,一般會把不定長的序列 padding 到相同長度,再用 mask 去區分非 padding 部分和 padding 部分。?
區分的目的是使得 RNN 只作用到它實際長度的句子,而不會處理無用的 padding 部分,這樣 RNN 的輸出和隱狀態都會是對應句子實際的最后一位。另外,對于 token 級別的任務,也可以通過 mask 去忽略 padding 部分對應的 loss。?
不過,在 PyTorch 中,對 mask 的具體實現形式不是 mask 矩陣,而是通過一個句子長度列表來實現的,但本質一樣。實現如下,sentence_lens 表示的是這個 batch 中每一個句子的實際長度(參考 [2])。
embed_input_x_packed?=?pack_padded_sequence(embed_input_x,?sentence_lens,?batch_first=True) encoder_outputs_packed,?(h_last,?c_last)?=?self.lstm(embed_input_x_packed) encoder_outputs,?_?=?pad_packed_sequence(encoder_outputs_packed,?batch_first=True)btw,在 PyTorch 的 Embedding 和 Loss 中也有對 padding 值的設置:
#?padding_idx?(int,?optional):?If?given,?pads?the?output?with?the?embedding?vector?at? #?`padding_idx`?(initialized?to?zeros)?whenever?it?encounters?the?index. embedding?=?nn.Embedding(vocab_size,?embed_dim,?padding_idx=0)#?ignore_index?(int,?optional):?Specifies?a?target?value?that?is?ignored #?and?does?not?contribute?to?the?input?gradient. criterion?=?nn.CrossEntropyLoss(ignore_index=0)Attention中Mask?
在 Attention 機制中,同樣需要忽略 padding 部分的影響,這里以 transformer encoder 中的 self-attention 為例:?
self-attention 中,Q 和 K 在點積之后,需要先經過 mask 再進行 softmax,因此,對于要屏蔽的部分,mask 之后的輸出需要為負無窮,這樣 softmax 之后輸出才為 0。
▲ The self-attention calculation in matrix form?(圖片參考 [3])
def?attention(query,?key,?value,?mask=None,?dropout=None):"Compute?'Scaled?Dot?Product?Attention'"d_k?=?query.size(-1)scores?=?torch.matmul(query,?key.transpose(-2,?-1))?\/?math.sqrt(d_k)if?mask?is?not?None:scores?=?scores.masked_fill(mask?==?0,?-1e9)?#?mask步驟,用?-1e9?代表負無窮p_attn?=?F.softmax(scores,?dim?=?-1)if?dropout?is?not?None:p_attn?=?dropout(p_attn)return?torch.matmul(p_attn,?value),?p_attn▲ 代碼參考 [4]
PS:上述兩個參考都是非常好的 transformer 介紹文章,參考 1,圖片與文字相得益彰,參考 2,代碼與講解相輔相成。
防止標簽泄露
在語言模型中,常常需要從上一個詞預測下一個詞,但如果要在 LM 中應用 self attention 或者是同時使用上下文的信息,要想不泄露要預測的標簽信息,就需要 mask 來“遮蓋”它。不同的 mask 方式,也對應了一篇篇的 paper,這里選取典型的幾個。?
Transformer中的Mask?
Transformer 是包括 Encoder和 Decoder的,Encoder中 self-attention 的 padding mask 如上,而 Decoder 還需要防止標簽泄露,即在 t 時刻不能看到 t 時刻之后的信息,因此在上述 padding mask 的基礎上,還要加上 sequence mask。?
sequence mask 一般是通過生成一個上三角矩陣來實現的,上三角區域對應要 mask 的部分。?
在 Transformer 的 Decoder 中,先不考慮 padding mask,一個包括四個詞的句子 [A,B,C,D] 在計算了相似度 scores 之后,得到下面第一幅圖,將 scores 的上三角區域 mask 掉,即替換為負無窮,再做 softmax 得到第三幅圖。這樣,比如輸入 B 在 self-attention 之后,也只和 A,B 有關,而與后序信息無關。?
因為在 softmax 之后的加權平均中: B‘ = 0.48*A+0.52*B,而 C,D 對 B' 不做貢獻。
▲ 圖片參考?[5]
實際應用中,Decoder 需要結合 padding mask 和 sequence mask,下面在 PyTorch 框架下以一個很簡化的例子展示 Transformer 中的兩種 Mask。
import?torchdef?padding_mask(seq,?pad_idx):return?(seq?!=?pad_idx).unsqueeze(-2)???#?[B,?1,?L]def?sequence_mask(seq):batch_size,?seq_len?=?seq.size()mask?=?1-?torch.triu(torch.ones((seq_len,?seq_len),?dtype=torch.uint8),diagonal=1)mask?=?mask.unsqueeze(0).expand(batch_size,?-1,?-1)??#?[B,?L,?L]return?maskdef?test():#?以最簡化的形式測試Transformer的兩種maskseq?=?torch.LongTensor([[1,2,0]])?#?batch_size=1,?seq_len=3,padding_idx=0embedding?=?torch.nn.Embedding(num_embeddings=3,?embedding_dim=10,?padding_idx=0)query,?key?=?embedding(seq),?embedding(seq)scores?=?torch.matmul(query,?key.transpose(-2,?-1))mask_p?=?padding_mask(seq,?0)mask_s?=?sequence_mask(seq)mask_decoder?=?mask_p?&?mask_s?#?結合?padding?mask?和?sequence?maskscores_encoder?=?scores.masked_fill(mask_p==0,?-1e9)?#?對于scores,在mask==0的位置填充scores_decoder?=?scores.masked_fill(mask_decoder==0,?-1e9)test()對應的各 mask 值為:
#?mask_p [[[1?1?0]]] #?mask_s [[[1?0?0][1?1?0][1?1?1]]] #?mask_decoder [[[1?0?0][1?1?0][1?1?0]]]可以看到 mask_decoder 的第三列為 0 ,對應 padding mask,上三角為 0,對應 sequence mask。?
BERT中的Mask?
BERT 實際上是 Transformer 的 Encoder,為了在語言模型的訓練中,使用上下文信息又不泄露標簽信息,采用了 Masked LM,簡單來說就是隨機的選擇序列的部分 token 用 [Mask] 標記代替。這波 Mask 操作,思想很直接,實現很簡單,效果很驚人。
BERT 之后,也有不少在 Mask 的范圍和形式上做文章的,比如:ERNIE,但大同小異,不多贅述。?
而 XLNet 的 Mask 操作非常的巧(nan)妙(dong),如下。?
XLNet中的Mask?
XLNet 通過 Permutation Language Modeling 實現了不在輸入中加 [Mask],同樣可以利用上下文信息,關鍵的操作就是下面所示的 Attention Mask 機制。
但并不是那么好理解,要理解 XLNet 中的 Mask,一定要先看張俊林老師的:XLNet:運行機制及和 Bert 的異同比較 [6],再來看下面的內容。上圖也是引自該文,這里再引用一句我認為非常關鍵的一段話:?
在 Transformer 內部,通過 Attention 掩碼,從 X 的輸入單詞里面,也就是 Ti 的上文和下文單詞中,隨機選擇 i-1 個,放到 Ti 的上文位置中,把其它單詞的輸入通過 Attention 掩碼隱藏掉,于是就能夠達成我們期望的目標(當然這個所謂放到 Ti 的上文位置,只是一種形象的說法,其實在內部,就是通過 Attention Mask,把其它沒有被選到的單詞 Mask 掉,不讓它們在預測單詞 Ti 的時候發生作用,如此而已。看著就類似于把這些被選中的單詞放到了上文 Context_before 的位置了)。?
對于排列序列:3->2->4->1,通過 Attention Mask,在 self-attention 的加權平均計算中,以上圖中的??為例:?
self-attention 計算之后 Content stream 中的?,其中??表示第 2 個詞對應的向量,其他同理。這樣在??中就看到了它的下文?,就好像是把??放到了它的上文位置一樣,但實際順序并沒有改變。?
對序列進行排列的目的是為了生成這個 Attention Mask,再加上雙流注意力去解決預測歧義的問題,可以說就是 Permutation Language Modeling 的全部了。?
到這里,就是本文全部的 Mask,但這肯定不是 NLP 中 Mask 的全部,但希望能幫助你去更好地理解 Mask。
參考文獻
[1] https://www.cnblogs.com/neopenx/p/4806006.html
[2] https://zhuanlan.zhihu.com/p/34418001
[3] https://jalammar.github.io/illustrated-transformer/
[4]?http://nlp.seas.harvard.edu/2018/04/03/attention.html#attention
[5] https://baijiahao.baidu.com/s?id=1652093322137148754&wfr=spider&for=pc
[6] https://zhuanlan.zhihu.com/p/70257427
點擊以下標題查看更多往期內容:?
對比學習(Contrastive Learning)相關進展梳理
從ACL和ICLR看知識圖譜嵌入的近期研究進展
BERT在小米NLP業務中的實戰探索
針對復雜問題的知識圖譜問答最新進展
復旦大學邱錫鵬教授:NLP預訓練模型綜述
淺談嵌套命名實體識別(Nested NER)
#投 稿?通 道#
?讓你的論文被更多人看到?
如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢?答案就是:你不認識的人。
總有一些你不認識的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋梁,促使不同背景、不同方向的學者和學術靈感相互碰撞,迸發出更多的可能性。?
PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是最新論文解讀,也可以是學習心得或技術干貨。我們的目的只有一個,讓知識真正流動起來。
?????來稿標準:
? 稿件確系個人原創作品,來稿需注明作者個人信息(姓名+學校/工作單位+學歷/職位+研究方向)?
? 如果文章并非首發,請在投稿時提醒并附上所有已發布鏈接?
? PaperWeekly 默認每篇文章都是首發,均會添加“原創”標志
?????投稿郵箱:
? 投稿郵箱:hr@paperweekly.site?
? 所有文章配圖,請單獨在附件中發送?
? 請留下即時聯系方式(微信或手機),以便我們在編輯發布時和作者溝通
????
現在,在「知乎」也能找到我們了
進入知乎首頁搜索「PaperWeekly」
點擊「關注」訂閱我們的專欄吧
關于PaperWeekly
PaperWeekly 是一個推薦、解讀、討論、報道人工智能前沿論文成果的學術平臺。如果你研究或從事 AI 領域,歡迎在公眾號后臺點擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。
總結
以上是生活随笔為你收集整理的NLP中的Mask全解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做过这个NLP项目的面试通过率高达 90
- 下一篇: 军校博士生毕业军医上尉军衔工资待遇?