當我們在10.7 節遇到機器翻譯時,我們設計了一個基于兩個 RNN 的序列到序列 (seq2seq) 學習的編碼器-解碼器架構 ( Sutskever et al. , 2014 )。具體來說,RNN 編碼器將可變長度序列轉換為固定形狀的上下文變量。然后,RNN 解碼器根據生成的標記和上下文變量逐個標記地生成輸出(目標)序列標記。
回想一下我們在下面重印的圖 10.7.2 (圖 11.4.1)以及一些額外的細節。通常,在 RNN 中,有關源序列的所有相關信息都由編碼器轉換為某種內部固定維狀態表示。正是這種狀態被解碼器用作生成翻譯序列的完整和唯一的信息源。換句話說,seq2seq 機制將中間狀態視為可能作為輸入的任何字符串的充分統計。
雖然這對于短序列來說是相當合理的,但很明顯這對于長序列來說是不可行的,比如一本書的章節,甚至只是一個很長的句子。畢竟,一段時間后,中間表示中將根本沒有足夠的“空間”來存儲源序列中所有重要的內容。因此,解碼器將無法翻譯又長又復雜的句子。第一個遇到的人是 格雷夫斯 ( 2013 )當他們試圖設計一個 RNN 來生成手寫文本時。由于源文本具有任意長度,他們設計了一個可區分的注意力模型來將文本字符與更長的筆跡對齊,其中對齊僅在一個方向上移動。這反過來又利用了語音識別中的解碼算法,例如隱馬爾可夫模型 (Rabiner 和 Juang,1993 年)。
受到學??習對齊的想法的啟發, Bahdanau等人。( 2014 )提出了一種沒有單向對齊限制的可區分注意力模型。在預測標記時,如果并非所有輸入標記都相關,則模型僅對齊(或關注)輸入序列中被認為與當前預測相關的部分。然后,這用于在生成下一個令牌之前更新當前狀態。雖然在其描述中相當無傷大雅,但這種Bahdanau 注意力機制可以說已經成為過去十年深度學習中最有影響力的想法之一,并催生了 Transformers (Vaswani等人,2017 年)以及許多相關的新架構。
import tensorflow as tf
from d2l import tensorflow as d2l
11.4.1。模型
我們遵循第 10.7 節的 seq2seq 架構引入的符號 ,特別是(10.7.3)。關鍵思想是,而不是保持狀態,即上下文變量c將源句子總結為固定的,我們動態更新它,作為原始文本(編碼器隱藏狀態)的函數ht) 和已經生成的文本(解碼器隱藏狀態st′?1). 這產生 ct′, 在任何解碼時間步后更新 t′. 假設輸入序列的長度T. 在這種情況下,上下文變量是注意力池的輸出:
我們用了st′?1作為查詢,和 ht作為鍵和值。注意 ct′然后用于生成狀態 st′并生成一個新令牌(參見 (10.7.3))。特別是注意力權重 α使用由 ( 11.3.7 )定義的附加注意評分函數按照 (11.3.3)計算。這種使用注意力的 RNN 編碼器-解碼器架構如圖 11.4.2所示。請注意,后來對該模型進行了修改,例如在解碼器中包含已經生成的標記作為進一步的上下文(即,注意力總和確實停止在T而是它繼續進行t′?1). 例如,參見Chan等人。( 2015 )描述了這種應用于語音識別的策略。
11.4.2。用注意力定義解碼器
要實現帶有注意力的 RNN 編碼器-解碼器,我們只需要重新定義解碼器(從注意力函數中省略生成的符號可以簡化設計)。讓我們通過定義一個意料之中的命名類來開始具有注意力的解碼器的基本接口 AttentionDecoder
。
我們需要在Seq2SeqAttentionDecoder
類中實現 RNN 解碼器。解碼器的狀態初始化為(i)編碼器最后一層在所有時間步的隱藏狀態,用作注意力的鍵和值;(ii) 編碼器在最后一步的所有層的隱藏狀態。這用于初始化解碼器的隱藏狀態;(iii) 編碼器的有效長度,以排除注意力池中的填充標記。在每個解碼時間步,解碼器最后一層的隱藏狀態,在前一個時間步獲得,用作注意機制的查詢。注意機制的輸出和輸入嵌入都被連接起來作為 RNN 解碼器的輸入。
class Seq2SeqAttentionDecoder(AttentionDecoder):
def __init__(self, vocab_size, embed_size<
評論
查看更多