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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ICLR 2020 | 可提速3000倍的全新信息匹配架构(附代码复现)

發布時間:2024/10/8 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ICLR 2020 | 可提速3000倍的全新信息匹配架构(附代码复现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?PaperWeekly 原創 ·?作者|周樹帆

學校|上海交通大學碩士生

研究方向|自然語言處理

今天聊一篇 FAIR 發表在 ICLR 2020 上的文章:Poly-encoders: Transformer Architectures and Pre-training Strategies for Fast and Accurate Multi-sentence Scoring

論文標題:Poly-encoders: Transformer Architectures and Pre-training Strategies for Fast and Accurate Multi-sentence Scoring

論文來源:ICLR 2020

論文鏈接:https://arxiv.org/abs/1905.01969

和一些花里胡哨但是沒有卵用的論文不同,這篇文章可謂大道至簡。該文用一種非常簡單但是有效的方式同時解決了 DSSM 式的 Bi-encoder 匹配質量低的問題和 ARC-II、BERT 等交互式的 Cross-encoder 匹配速度慢的問題。

背景

眾所周知,常見的搜索、檢索式問答、自然語言推斷等任務,它們本質上都是一種相關性匹配任務:給定一段文本作為 query,然后匹配出最為相關的文檔或答案然后返回給用戶。

目前主流的文本相關性匹配架構有兩大類:以 DSSM 為代表的 Siamese Network 架構、以及形如 ARC-II、ABCNN 或 BERT(基于 Self-Attention)的交互式匹配架構。

1.1 Siamese Network

如圖 1 所示,Siamese Network 式(本篇文章又稱其為 Bi-encoder)的匹配方案會利用 2 個網絡分別將 query 和 candidates 編碼成??和??,最后再通過一個相關性判別函數(通常為 cosine)計算兩個 vec 之間的相似度。

這種方案的最大特點就是 query 和 candidates 直到最后的相關性判別函數時才發生交互,所以會對模型的匹配性能產生一定的影響。

但是這種完全獨立的編碼方式使得我們可以離線計算好所有 candidates 的向量,線上運行時只需計算 query 的向量然后匹配已有向量即可。總的來說,這種方案匹配速度極快,但是匹配質量不能達到最佳。

▲?圖1. Siamese Network(本篇論文又稱其為Bi-encoder)

1.2 交互式匹配

如圖 2 所示,交互式匹配(本文記作 Cross-encoder)的核心思想是則是 query 和 candidates 時時刻刻都應相互感知,相互交融,從而更深刻地感受到相互之間是否足夠匹配。

早期的交互方案如 ARC-II、ABCNN 等會計算??和??之間的word embedding相似度、Q、C 分別過? RNN 之后的??、??之間的相似度,最后再用一些 CNN 之類的方法整合結果,然后用 MLP 做二分類判別是相關還是不相關。

▲ 圖2. 交互式匹配示意圖(圖中為ARC-II)

另外在 BERT 興起之后,如圖 3 所示般將 query 和 candidate 拼成一句話,然后利用 self-attention 完成 query 和 candidate 之間的交互的模型也大量涌現,并且取得了非常顯著的成果。本篇論文實現的 Cross-encoder 也是基于圖 3 的架構。

相較于 Siamese Network,這類交互式匹配方案可以在 Q 和 C 之間實現更細粒度的匹配,所以通常可以取得更好的匹配效果。

但是很顯然,這類方案無法離線計算 candidates的表征向量,每處理一個 query 都只能遍歷所有 (query, candidate) 的 pairs 依次計算相關性,所以這類方案相當耗時(當然也有很多提速手段,不過那不是本文的重點)。

▲ 圖3. Cross-encoder


Poly-Encoder

Bi-encoder (Siamese Network) 和 Cross-encoder(交互式網絡)都有各自顯著的優點和缺點,而本文提出的 Poly-encoder 架構同時集成了兩類方案的優點并避免了缺點。

▲ 圖4. Poly-encoder

Poly-encoder 如圖 4 所示。Poly-encoder 的思想非常簡單(簡單到論文里僅用了 2 段文字),按我的個人理解描述:

Bi-encoder 的主要問題在于它要求 encoder 將 query 的所有信息都塞進一個固定的比較 general 的向量中,這導致最后??和??計算相似度時已經為時過晚,很多細粒度的信息丟失了(e.g. query 為“我要買蘋果”),所以無法完成更精準的匹配。

這就有點像 word2vec 靜態詞向量:即使一個詞有多種語義,它的所有語義也不得不塞進一個固定的詞向量。

為了克服這個問題,Poly-encoder 的方案就是每個 query 產生 m 個不同的??,接著再根據??動態地將 m 個??集成為最終的??(其實有點像封面圖那樣,有一點用 m 個向量組合出最終的 Low Poly(baike.baidu.com/item/Lo)化向量的味道),最后再計算??和??的匹配度。

用論文里的話來說:

論文中的 ctxt 指代 context,相當于 query;cand 指代 candidate。上面這段論文建議我們可以隨機初始化 m 個通過 dot product 計算 attention,從而將長度為 N 的 context 編碼成 m 個向量??(即??)。

接著:

我們再用 candidate 對應的向量??計算 m 個??的 attention,進而得到最終的?。

很顯然,Poly-encoder 架構在實際部署時是可以離線計算好所有 candidates 的向量的,所以只需要計算 query 對應的 m 個??向量,再通過簡單的 dot product 就可以快速計算好對應每個 candidate 的“動態的”?向量。

看起來 Poly-encoder 享有 Bi-encoder 的速度,同時又有實現更精準匹配的潛力。我們通過實驗來一探究竟。



實驗

本文選擇了檢索式對話數據集 ConvAI2、DSTC 7、Ubuntu v2 數據集以及 Wikipedia IR 數據集進行實驗。

訓練 Bi-encoder 和 Poly-encoder 時由于這兩類模型的特性,負采樣方式為:在訓練過程中,使用同一個 batch 中的其他 query 對應的 response 作為負樣本(如果難以理解,可以稍后結合復現代碼來理解)。

而 Cross-encoder 的負采樣方式為:在開始訓練之前,隨機采樣 15 個 responses 作為負樣本。


3.1 檢索質量

圖5給出了一些 baseline 模型以及本文的基于預訓練 BERT 的 Bi-encoder、Poly-encoder 以及 Cross-encoder 在各個數據集上的表現。

當然我們很容易發現,本文的所有模型由于以預訓練的BERT為基礎,他們的表現都要顯著超出不使用 BERT的那些 baseline 們。所以我們只需要關注 Bi、Poly 和 Cross 三種架構之間的表現差異即可。

實驗結果表明即使僅增設少數幾個 code(用于計算 attention 產生向量),Poly-encoder 的表現也要遠優于 Bi-encoder。

實驗結果還表明,Poly-encoder 的表現會隨著 code 個數的增加而逐漸增加,并且慢慢逼近 Cross-encoder 的結果(個人認為 Cross-encoder 的表現應該是 Poly-encoder 的上界,不過偶爾也可能會因為一些偶然因素導致 Poly-encoder 反超 Cross-encoder 的情況)。

另外,為了體現 Cross-encoder 在速度上的局限性,作者還很有意思地跳過了 Cross-encoder 在 Wikipedia IR 上的測評并寫到:“In addition, Cross-encoders are also too slow to evaluate on the evaluation setup of that task, which has 10k candidates”。

▲ 圖5. 模型表現匯總

3.2 檢索速度

圖 5 的實驗結果已經表明 Poly-encoder 的檢索質量明顯優于 Bi-encoder 架構,且能逼近 Cross-encoder 架構的效果。剩下的關鍵問題就是 Poly-encoder 是否會顯著增加檢索耗時?

圖 6 給出了各模型在 ConvAI2 數據集上的檢索耗時。

Bi-encoder 理所當然是最快的架構,當 candidates 為 100k 時,在 CPU 和 GPU 環境下其檢索耗時分別為 160ms 和 22ms;而 Cross-encoder 顯然是最慢的一個:同樣實驗條件下其檢索耗時分別約為 2.2M (220 萬) ms 和 266K (26.6 萬) ms。

反觀 Poly-encoder,以 Poly-encoder 360 為例,該模型可以達到遠超 Bi-encoder、接近甚至反超 Cross-encoder 的檢索質量,但其檢索速度確比 Cross-encoder 足足快了約 2600-3000 倍!

▲ 圖6. 各模型在ConvAI2數據集上的檢索耗時


論文小結

總的來說,本文的出發點就是希望找到一個速度快但質量不足的 Bi-encoder 架構和質量高但速度慢的 Cross-encoder 架構的折中。

本文提出的 Poly-encoder 的核心思想雖然非常簡單,但是卻十分有效(親測),確實在很多場景下可以作為 Bi-encoder 的替代,甚至在一些對速度要求較高的場景下可以作為 Cross-encoder 的替代。

方案簡潔固然是本文的一大優點,不過這也給未來的研究留下了空間。相信未來很快就會有許多基于 Poly-encoder 的改進版出現。



復現結果分享

在讀完論文后的第一時間,我就嘗試了復現工作。我的復現結果表明,Poly-encoder 不管是收斂速度還是模型上限,都要顯著優于 Bi-encoder,且 Poly-encoder 幾乎不增加額外的顯存負擔,對訓練速度的影響也幾乎可以忽略。完整代碼位于:

https://github.com/sfzhou5678/PolyEncoder

5.1 關鍵代碼分析

Poly-encoder 的實現非常簡單,只需在 Bi-encoder 的基礎上略加修改即可。接下來我將介紹實現 Poly-encoder 的核心代碼。

我們首先用 nn.embedding 來作為 m 個 poly_codes 的值, 然后 forward 的時候根據m的值產生對應個數的 poly_codes,這些 codes ?將用于計算不同的? attention weights,以產生多個 vec_ctxt(即 vec_q)。

這里我令 poly_code_ids+=1 是為了讓 context_encoder 和 response_encoder 對稱,所以把 0 號 id 留給了 response_encoder。

self.poly_code_embeddings?=?nn.Embedding(self.poly_m?+?1,?config.hidden_size)poly_code_ids?=?torch.arange(self.poly_m,?dtype=torch.long,?device=context_input_ids.device) poly_code_ids?+=?1 poly_code_ids?=?poly_code_ids.unsqueeze(0).expand(batch_size,?self.poly_m) poly_codes?=?self.poly_code_embeddings(poly_code_ids)

接著,我們用這些 poly_codes 和 bert 的輸出做 attention 得到 context_vecs:

def?dot_attention(q,?k,?v,?v_mask=None,?dropout=None):attention_weights?=?torch.matmul(q,?k.transpose(-1,?-2))if?v_mask?is?not?None:attention_weights?*=?v_mask.unsqueeze(1)attention_weights?=?F.softmax(attention_weights,?-1)if?dropout?is?not?None:attention_weights?=?dropout(attention_weights)output?=?torch.matmul(attention_weights,?v)return?outputstate_vecs?=?self.bert(context_input_ids,?context_input_masks,?context_segment_ids)[0]??#?[bs,?length,?dim] context_vecs?=?dot_attention(poly_codes,?state_vecs,?state_vecs,?context_input_masks,?self.dropout)?#[bs,?m,?dim]

得到 response_vec 的方式類似,不再贅述。最后,只需根據 response_vec 給 context_vecs 做一次 attention 得到 final_context_vec 即可:

if?labels?is?not?None:responses_vec?=?responses_vec.view(1,?batch_size,?-1).expand(batch_size,?batch_size,?self.vec_dim)final_context_vec?=?dot_attention(responses_vec,?context_vecs,?context_vecs,?None,?self.dropout)

在 loss function 方面,雖然我們可以在準備數據的時候就為每個樣本做 N 次負采樣,但是在 Bi-encoder 或 Poly-encoder 這種產生 response_vec 和 query 完全獨立的場景下,可以將同一個 batch 內的其他 response 作為負樣本來避免重復計算,有效提升訓練效率。

具體實現時,我們計算 context_vec_i 和 response_vec_j 的點乘,從而產生一個 [bs, bs] 的余弦相似度矩陣,這個相似度矩陣就是 context_vec_i 和 batch 內的每一個 response_vec 的相似度。

由于我們的目標是最大化 context_vec_i 和對應的正樣本,即 response_vec_i 的相似度,所以我們可以做一個 [bs,bs] 的單位矩陣作為 label,最后應用交叉熵產生訓練用的 loss。

我的代碼中在 dot_product 后面還乘了系數 5,這就是一個用于緩和 softmax 取值的參數,其具體取值通常需要實驗來確定,這里的 5 只是我的經驗值。

#?因為要算余弦相似度,所以給向量都歸一化一下,之后直接點乘即可 context_vec?=?F.normalize(context_vec,?2,?-1) responses_vec?=?F.normalize(responses_vec,?2,?-1)responses_vec?=?responses_vec.squeeze(1) dot_product?=?torch.matmul(context_vec,?responses_vec.t())??#?[bs,?bs] mask?=?torch.eye(context_input_ids.size(0)).to(context_input_ids.device) loss?=?F.log_softmax(dot_product?*?5,?dim=-1)?*?mask loss?=?(-loss.sum(dim=1)).mean()

5.2 實驗結果

我使用的實驗數據是論文中所用的 Ubuntu V2,實驗設備是我筆記本上的一個 1066 顯卡。當然為了實驗跑得更快,我沒有使用論文中所用的 bert-base,而是一個預訓練過的僅 4 層的 bert-small。

另外,此實驗中所用的 batchsize、文本長度、歷史對話信息等都限制的比較小(不然實驗實在是跑得太慢了),因此實驗結果整體會較原論文中偏低。

最終的實驗設置和結果如下:

  • Dataset: Ubuntu V2

  • Device: GTX 1060 6G x1

  • Pretrained model:?BERT-small-uncased (https://storage.googleapis.com/bert_models/2020_02_20/all_bert_models.zip)

  • Batch size:?32

  • max_contexts_length: 128

  • max_context_cnt: 4

  • max_response_length:64

  • lr: 5e-5

  • Epochs: 3

Results:

▲ 復現實驗結果匯總

從上表中明顯可以看出,Poly-encoder 的效果要遠優于 Bi-encoder 的,當使用 16 個 codes 時,poly 較 bi 的提升可得到 2.24 個點,而使用 64、360 個 codes 時提升分別可達 3.12 和 3.52 個點。而且模型的訓練速度幾乎沒有受到影響,同時對顯存的負擔也非常小。



總結

本文提出的 Poly-encoder 思路非常清晰,實現難度不高,而且實驗效果非常理想,我個人非常喜歡!

Poly-encoder 架構還有一個突出優點在于,它可以很輕松地拓展到大量信息檢索相關的領域,無論是搜索、推薦,或是 CV 領域的 ReID 等,只要可以產生 query 和 candidates 的向量 vec_q 和 vec_c,那么都有可能成功應用 Poly-encoder。

我自己十分看好 Poly-encoder,相信在未來它會成為和 DSSM 一樣的經典必讀論文。

點擊以下標題查看更多往期內容:?

  • WWW 2020 開源論文 | 異構圖Transformer

  • Transformer的七十二變

  • 抽取+生成:基于背景知識的參考感知網絡對話模型

  • 二值神經網絡(Binary Neural Networks)最新綜述

  • 文本分類和序列標注“深度”實踐

  • BERT在多模態領域中的應用

#投 稿?通 道#

?讓你的論文被更多人看到?

如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢?答案就是:你不認識的人。

總有一些你不認識的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋梁,促使不同背景、不同方向的學者和學術靈感相互碰撞,迸發出更多的可能性。?

PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是最新論文解讀,也可以是學習心得技術干貨。我們的目的只有一個,讓知識真正流動起來。

?????來稿標準:

? 稿件確系個人原創作品,來稿需注明作者個人信息(姓名+學校/工作單位+學歷/職位+研究方向)?

? 如果文章并非首發,請在投稿時提醒并附上所有已發布鏈接?

? PaperWeekly 默認每篇文章都是首發,均會添加“原創”標志

?????投稿郵箱:

? 投稿郵箱:hr@paperweekly.site?

? 所有文章配圖,請單獨在附件中發送?

? 請留下即時聯系方式(微信或手機),以便我們在編輯發布時和作者溝通

????

現在,在「知乎」也能找到我們了

進入知乎首頁搜索「PaperWeekly」

點擊「關注」訂閱我們的專欄吧

關于PaperWeekly

PaperWeekly 是一個推薦、解讀、討論、報道人工智能前沿論文成果的學術平臺。如果你研究或從事 AI 領域,歡迎在公眾號后臺點擊「交流群」,小助手將把你帶入 PaperWeekly 的交流群里。

總結

以上是生活随笔為你收集整理的ICLR 2020 | 可提速3000倍的全新信息匹配架构(附代码复现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。