論文|記憶網絡之Memory Networks

歡迎直接到我的博客查看最近文章:www.pkudodo.com。更新會比較快,評論回覆我也能比較快看見,排版也會更好一點。

原始blog鏈接:  http://www.pkudodo.com/2019/06/14/1-13/ 

 

 

Memory NetWorks介紹

在文本的處理上,由於很多地方對記憶的需要,因此誕生了RNN及LSTM。但RNN和LSTM也只能用於短時間內的記憶(一般來說也就十幾個step)。所以如果文本較長的話,RNN和LSTM也無能爲力了。

當然也有一種方法,就是直接擴大RNN和LSTM的隱狀態大小,讓其可以存儲更多的信息。但相對於這種方式,我們更希望能夠任意地增加記憶量,同時能夠對模型做盡可能小的改變。

Memory Networks正是從這一角度出發得到的產物。直觀來講,Memory Networks可以理解成正常的model額外加一個記憶模塊。

就好像我們使用的CPU(普通的model),它內部是有一個很小的ram的(我本科階段是嵌入式方向,目前見過cpu內部最小的ram只是kb的量級),但如果要運行操作系統或軟件的話,內部ram就不夠了(memory不夠),所以通常會外擴一個ram芯片(Memory Networks),這樣cpu的運行並沒有什麼改變,只不過在需要memory來配合推理的時候,直接從Memory Networks中存取就可以了。

 

memory network在提出後又經歷了幾次變體,這次先寫《memory networks》,這是memory networks被facebook首次提出的原始論文。後續又經歷了幾次變體。下一篇就會講它end-to-end 的memory network,這是對於原始MemNN的一次改進。

 

《Memory Networks》

Memory Networks一共有5個部分,分別是memory m、I、G、O、R,其中

memory m:m由一系列的mi組成,其中mi是單個向量,每個mi都表示某一個方面的記憶存儲。當要更新記憶的時候,就操作使用新記憶去更新相應的mi,要寫入記憶時直接寫入mi即可。至於i的範圍則依據實際的使用策略不同而作相應的修改。

I:輸入特徵映射,它負責將輸入轉換成內部的特徵表示形式。比如說輸入的是文本,就需要它將其轉換成model可以看懂的數學形式(比如說word轉換成embedding形式、文本轉換成向量等),也可以認爲是數據的預處理的一個過程。用I(x)表示運算過程,其中x是輸入。

G:更新記憶,根據當前的memory狀態(m)、當前的輸入(I(x))、要更新的記憶(mi),得到更新後的記憶,並更新mi。用mi=G(mi, I(x), m)表示,其中i爲m的數目範圍內的任意數,具體怎麼指定i的值,後續會解釋。

O:輸出映射,根據當前的記憶狀態以及當前的輸入,確定當前的輸出,但輸出是內部特徵表示形式(比如說一個稠密的向量),因此還需要一個步驟作轉換。用o=O(I(x), m)表示。

R:迴應,負責將O步驟輸出的o轉換成系統交互的形式,例如文本或系統動作。用r=R(o)表示,最簡單的理解就是把o輸入一個rnn,使用seq2seq或者類似的結構輸出對應的文本或動作即可。

 

一個文本的例子——最基本的模型應用

怎麼把數據存到memory

最簡單的一個方法就是順序存,比如說定義有n個m,即mi中i的取值範圍爲0-999。那麼每次要往memory存的時候,就找到下一個空着的memory,將輸入x原封不動地放進去(這是最簡單的策略,比如說x是個句子,就把句子直接放到memory中),之後N+1,下次就會往下一個memory存。

由於G是負責更新memory的,所以在這種策略中,G只是很簡單的原封不動地輸出x。

怎麼提取指定記憶

那麼存記憶已經搞定了,另一個主要的問題是取記憶,比如說下面這段小故事:

  1. Joe去了廚房。
  2. Fred去了廚房。
  3. Joe拿起了牛奶。
  4. Joe去了辦公室。
  5. Joe放下了牛奶。
  6. Joe上了廁所。

提問:牛奶現在在哪裏?

一共6句話,根據當前的存儲策略,6句話直接以原始形式存在了m中,這個時候根據提問怎麼知道哪句話是和提問相關的呢?

如果我們自己做這個題,就會把每個句子再看一遍,定位到了第五句——Joe放下了牛奶。memory network做的也是這件事情,它使用了O模塊,去計算當前輸入x和每一個m的相關程度,找到最相關的句子mi,公式如下:

其中so是一類計算相關程度的函數,它最後會輸出一個得分,x和所有的m遍歷計算,直到找到得分最高的即爲最相關的句子i。

其中score函數如下:

U的大小爲[n,D],Φx和Φy是D維向量,Φ(x)負責將x映射到內部向量表示形式(比如說最簡單的就是詞袋模型)。所以最後的s(x,y)的結果是一個實數,表示了分數。

但是這其中存在一個問題,比如說我們找到了最相關的i是5,放下了牛奶,但牛奶在哪裏我們仍然不知道。所以對於人來說,會往前看一句,發現第4句“Joe去了辦公室”直接暗示了牛奶在辦公室。第4句和第5句結合才能得到牛奶在辦公室的答案。

因此不光要找到最相關的句子,還應該找到第二相關的句子(paper中用k來定義一共找前k個相關的句子,這裏k=2)。

值得注意的是,並不是簡單地找到前2個相關句子,在找第2個句子時,需要以找到的第一個句子爲條件。像上面的式子中,需要以x和m01爲條件去找mo2。作者沒有提到這麼做的原因,但我認爲是爲了能夠在有了第一個句子的情況下,再去找到一個另外的能夠有最強代表性的句子,而不是說兩個句子其實指代的是同一個方面,這樣跟找一個句子也沒什麼差別。

輸出

在這個例子中,輸出並不要求是字符串,只要一個word即可,比如說“辦公室”(這裏引用的是原文中的例子,在英文中是單個的“office”,如果是中文情況下,可以加一個rnn來生成字符串)。

所以輸出函數的輸入是當前輸入、m01,m02和字典,輸出是字典當中最有可能的那個單詞,公式如下:

訓練

k=2時的目標函數如下:

(6)表示挑出來的句子是否是正確的句子,(7)表示在第一個句子被正確挑出來的情況下,第二個句子是否是正確的句子。(8)最後輸出的是否是正確的答案。

可以看到loss其實對train的各個方面都做了一個約束,最後的performance效果也是非常好。

 

其他

論文的後半部分補充了很多小技巧,例如memory如果非常大的解決方法、遇到新詞等。這裏就不再過多展開了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章