Sequence Generation
引入
在循環神經網絡(RNN)入門詳細介紹一文中,我們簡單介紹了Seq2Seq,我們在這里展開一下
一個句子是由 characters(字) 或 words(詞) 組成的,中文的詞可能是由數個字構成的。
如果要用訓練RNN寫句子的話,以 character 或 word 為單位都可以
以上圖為例,RNN的輸入的為前一時間點產生的token(character 或 word)
假設機器上一時間點產生的 character 是 “我”,我們輸出的向量 y 是在 character 上的分布,它有0.7的幾率寫出 “我是”,有0.3的幾率寫出 “我很” 。
例子:寫詩
在產生句子第一個 character 的時候,由於前面沒有東西,我們需要給機器一個特殊的character—— <BOS>
BOS:Begin of Sentence
輸出的第一個character $y^{1}$ 可以下面的條件概率表示
我們再輸出概率最大的那個 character,然后把$y^{1}$作為輸入,……,不斷重復這個行為,直到我們輸出 <EOS>
EOS:End of Sentence
我們訓練 RNN 的數據集也類似上面這個樣子。如下圖所示,我們的輸入是古詩的每一個字,輸出是輸入的下一個字,通過最小化 cross-entropy 來得到我們的模型
例子:畫圖
圖片由 pixel 組成,我們可以把一張圖片的像素點想成詞匯,讓RNN產生像素點,道理也是一樣的。
但是圖片每一行最右邊的像素點 $a_{i,j}$ 和下一行最左邊 $a_{i+1, j-2}$ 的像素距離很遠,他們可能沒有關系,$a_{i+1, j-2}$ 反而可能跟正上方的像素 $a_{i, j-2}$ 關系大些。
比如下圖中 灰色 的像素點和 黃色 的像素點可能關系不大,而跟 藍色 的像素點更有關系。
所以我們生成圖片像素點的時候,灰色 的像素點是由 藍色 像素點生成的,而不是 由 黃色像素點生成。
Conditional Generation
但我們不想隨機生成句子,我們更期望它能根據我們的場景生成相應的句子。比如給張圖片,輸出對圖片的描述;聊天機器人中輸入一句話,輸出這句話的response。
Image Caption Generation
比如我們要訓練一個模型,用來生成圖片的文字說明。
我們可以讓圖片通過一個CNN,輸出一個vector,再把這個vector丟到RNN中。
- 這個vector可以只在第一個時間點輸入,讓RNN把這個vector存到memory中,后面的時間點補零。
- 也可以在每個時間點都輸入這個vector,因為RNN到后面可能忘記了我們輸入的vector。
Machine translation / Chat-bot
如果要做一個翻譯機或者一個聊天機器人,我們的輸入是一個句子,輸出是翻譯結果或者response。
這個模型可以分為兩個部分,Encoder 和 Decoder
把句子輸入 Encoder 然后在最后一個時間點把 output 取出來
可以取output,也可以取 $h_{t}$,還有$c_{t}$
再把 Encoder 輸出的vector 作為 Decoder 每一個時間點的輸入。Encoder 和 Decoder 是一起訓練的。
上面這種情況,我們的輸入是Sequence,我們的輸出也是Sequence,所以被稱為 Sequence to Sequence Model
Dynamic Conditional Generation
這種模型又叫做 Attention Based Model。前面介紹的 Encoder- Decoder 這種架構,它可能沒有能力把一個很長的 input 壓縮到一個 vector 中,這樣 vector 就不能表示句子里的所有信息,導致模型表現不如人意。 前面 Decoder 每個時間點輸入都是同樣的 vector 。在 Dynamic Conditional Generation 中,我們希望 Decoder 在每個時間點獲得的信息是不一樣的。
我們繼續上面的例子,來訓練一個翻譯模型。 這里多了一個向量$z^{0}$,$z^{0}$也是模型需要訓練的參數向量(稱為key)
我們先把每個隱藏層的輸出放到一個 Database 中,用$z^{0}$去搜尋 Database 中的內容。它會和隱藏層的每個輸出$h^{i}$做匹配,得到一個匹配的程度 $\alpha ^{i}_{0}$
這就是Attention
匹配的方法 match 可以自己設計,比如:
- match 可以是 $z$ 和 $h$ 的余弦相似度(cosine similarity)
- match 也可以是個網絡,輸入是 $z$ 和 $h$,輸出是一個數值
- match 還可以像這樣設計:$\alpha =h^{T}Wz$
第二種網絡的參數和第三種方法中的參數$W$是機器自己學習的
經過 match 后得到的$\alpha ^{i}_{0}$后面可以再接一個 softmax,得到$\hat{\alpha}^{i}_{0}$,再讓$h$和$\hat{\alpha}$對應相乘再相加得到$c^{0}$
再把$c^{0}$作為 Decoer 的輸入,根據 $z^{0}$ 和 $c^{0}$ ,Decoder 會得到一個 $z^{1}$ 並輸出一個 word。
我們得到 $z^{1}$ 后,我們再計算一次Attention。一直重復這個動作,直到產生 <EOS>
Attention讓我們不關心整個句子,而是關注在某個地方
Tips
Attention過於集中
$^{\alpha ^{i}_{t}}$ ,下標代表時間,上標代表第幾個 component 的 Attention weight
比如觀看影片,輸出對影片的內容的描述文字。
如果我們的 Attention 樣子像上圖中的 條形圖 所示,它都集中 第二個 畫面里面。在這個畫面中,第二個時間點和第四個時間點的 Attention 都很高。
那么我們的輸出可能是下面這樣奇奇怪怪的句子:
A woman and woman is doing a woman
我們希望我們的 Attention 是平均的,不應該特別只看某一個 frame,而是影片的每一個 frame 都要平均地看到。
我們可以對我們的 Attention 下一個 Regularization term,在機器學習中我們也常用 l1 和 l2 正則。
上面的式子中,$\sum _t\alpha ^{i}_{t}$把同一幀中的所有Attention累加,希望跟一個常數$\tau $越接近越好。
這樣我們得到的 Attention weight 就會平均散布在不同的幀上,而不會特別集中在某一幀上
training 和 testing 不一致
引入
如上圖所示,我們訓練的時候,我們期望輸出的是 A、B、B,通過最小化交叉熵損失得到我們的模型
在測試的時候,假如我們第一個時間點輸出是B,它會作為第二個時間點輸入的一部分。但測試的時候沒有標,我們不知道第二個時間點輸入是錯誤的。
即在測試的時候,輸入的一部分是機器自己生成的,有可能有錯的東西。這種情況稱為 exposure bias。
exposure bias指模型在訓練的時候,有些狀況它是沒有去探測過的
我們來看一下 training 和 testing 的情況
訓練的時候,我們的模型只有看到過3條支路的比較,其他的狀況在 training 的時候是沒有模型是沒有看到過的
測試的時候,我們沒有了上面的限制。如果我們測試的時候,第一步就犯錯了,而在 training 的時候我們的模型沒有看到過其他支路的狀況,導致一步錯,步步錯。
Scheduled Sampling
我們可以用 Scheduled Sampling 解決這種現象
Scheduled Sampling的意思是說給機器看自己生成的東西,會很難訓練,給機器看正確的答案,training和testing會不一致。那就折中考慮。
就像用一個骰子來決定,如果是正面就看機器自己生成的東西,反面就看正確的答案。
這個骰子的幾率是動態決定的,在一開始的時候答案出現的幾率比較高,隨着training的進行,機器自己生成的東西幾率比較高。因為testing的時候,機器自己生成的東西幾率是100,答案出現的幾率是0。
Beam Search
我們還可以使用Beam Search。我們機器在 output 的時候,都是輸出一個概率,然后選擇概率高的。
那有沒有可能在第一步選了 B 后面的幾率更大?比 0.6 * 0.6 * 0.6 大?如下圖所示
也許犧牲第一個時間點之后我們可以選到更好的結果。我們沒有辦法窮舉所有可能,Beam Search就是要克服這個問題
每次在做 sequence 生成的時候,我們都會保留前N個分數最高的可能。存的數目就叫做Beam Size。下圖中Beam Szie=2
testing才用Beam Search,training用不上
另一個Beam Search例子