1,概述
目前有效的文本分類方法都是建立在具有大量的標簽數據下的有監督學習,例如常見的textcnn,textrnn等,但是在很多場景下的文本分類是無法提供這么多訓練數據的,比如對話場景下的意圖識別,這個時候如果我們還以傳統的深度學習模型+softmax的形式來分類的話,是極容易陷入過擬合的狀態。因此就有很多人研究在少量樣本下如何建模。one-shot learning,few-shot learning,甚至是zero-shot learning都是旨在解決這類的問題。
本篇博客將會介紹下幾種比較經典的one-shot learning或者是few-shot learning。
2,模型介紹
接下來我們來介紹幾篇經典的文章,來看看都是怎么去做few-shot learning或者one-shot learning的。但因為大部分文章中的例子都是在圖像領域的,因此不會很細的去描述模型的結構,應用到文本中這些結構可以自己去選擇,在這里會側重講述其做法,代碼實現見https://github.com/jiangxinyang227/few_shot_learning。數據集采用的是由阿里巴巴團隊整理出來的ARSC數據集。
論文一:Siamese Neural Networks for One-shot Image Recognition
這篇論文的主體結構是孿生網絡(Siamese Network),之前的一片博客有專門介紹過孿生網絡,詳情見孿生網絡(Siamese Network)在句子語義相似度計算中的應用。這一篇介紹下孿生網絡在one-shot learning中的應用。
假定你現在對孿生網絡結構有個清晰的了解,我們現在來看看是怎么用孿生網絡做one-shot learning的。我們給定三份數據集,用於訓練的train set,用於測試時的support set,query。
train set包含M個類別,每個類別下有N個樣本,我們現在隨機從每個類別下去采樣,從同一類別下采樣相同的兩個句子作為正樣本,從不同的類別下采樣兩個句子作為負樣本,保證正負樣本對的數量為1:1。然后輸入到孿生網絡中作為一個二分類的任務來度量兩個句子之間的距離。
在本論文中的度量方式用的是曼哈頓距離,並采用了加權和的方式來加權,加權系數是通過網絡自己學習的,其表達式如下:
上面式子中$h_{1, L-1}^{(j)},h_{2, L-1}^{(j)}$分別表示第一個句子和第二個句子最終的向量表示,$\alpha_j$是上面兩個向量相減后得到的向量的第$j$個值得系數,這個值是通過網絡自己學習得到的,$\sigma$表示sigmoid函數,輸入一個0-1之間的概率值。
上面說到通過這種采樣方式將問題轉化成一個0,1的二分類問題,因此損失函數可以采用二元交叉熵損失函數。
論文中也給出了自己的優化算法:
引入了動量和正則,不過這里的正則的作用是什么,我不太清楚。
one-shot learning在測試階段是怎么實現的呢?具體如下:
首先在給定的測試時的support set,support set是一個C個類別(原則上這C個類別和train set中的M個類別是不相交的,這樣才符合one-shot learning的本質),且每個類別下只有一個樣本的數據集,現在給定一個query,將query和support set中的樣本輸入到孿生網絡中,得到query和每個樣本之間的概率分數,在這里因為是one-shot,因此support set中每個樣本表示一個類別,然后取概率分數最大的類別作為輸出類別,表達式如下:
上面式子中$P^{(c)}$表示query和support set中的樣本的概率分數。
論文二:Prototypical Networks for Few-shot Learning
原型網絡(Prototypical Network)中引入了一個混合密度估計的思想,用few-shot樣本集的均值來表示該類別的向量,我們來看看具體的做法
給定一個訓練時的train set,測試時的support set和query。support set 包含C個類別,每個類別下含有K個樣本。train set 包含M個類別,每個類別下含有N個樣本。為了在訓練時期模擬測試時的場景,我們在訓練時構造一系列的episode,每個episode實際上就是一個meta task。那該怎么構造這樣一個episode呢?從train set中隨機抽取C個類別,然后從每個類別中隨機抽取K個樣本,構造訓練時期的support set,這樣的問題也稱為C-way K-shot問題,接着從另外N-K個樣本中選取n個樣本作為訓練時期的query。構造一系列這樣的episode來訓練網絡。其具體的結構可以描述如下:
1)embedding層,將訓練時的support set和query embedding成向量表示
2)特征提取層,這里可以用LSTM來提取句子的高層特征
3)針對support set做的類的向量表示層,其實就是對每個類中的K個樣本取平均來表示這個類
上面式子中$f_{\phi}(x_i)$表示support set中第$i$個樣本的向量表示,$k$表示第$k$個類別。
4)計算query和每個類別之間的分數
上面式子中$f_{\phi}(X)$表示query的向量表示,$d(.)$是一個距離度量函數,上面整個式子是一個softmax函數,得到query和每個類別的概率分數。
真個算法流程圖如下:
整個算法原理圖示化:
如上圖所示,整個模型也是可以很好的遷移到zero-shot,one-shot的任務上的。
到了這里還有一個問題,就是距離度量函數$d(.)$該怎么選擇,上面我們說到是通過計算類別下所有樣本的均值來表示該類別,文章中引入了Bregman 散度的概念,Bregman 散度認為:達到與指定點(query)最小距離的點為樣本均值點,也就是說當我們的度量函數$d(.)$選擇Bregman 散度時,用樣本均值來表示類向量是最佳選擇,而歐式距離的平方就是一種Bregman 散度。因此本文的距離度量函數是歐式距離的平方:
上面添加的負號是將求距離最小轉換成求距離最大。
測試的時候和訓練時的episode中的操作一樣,將測試時的support set 和query輸入到模型中,然后計算query和每個類別的概率分數,選擇最大的概率值的類。
論文三:Learning to Compare: Relation Network for Few-Shot Learning
這篇論文中提出了關系網絡(Relation Network)的概念。整個訓練和預測時的方法和上一篇的原型是一樣的。其主要創新點在於之前的網絡都會給定一個確定的距離度量函數,然而作者認為沒有一個確定的距離函數能作為所有類別的最佳度量函數,因此作者讓網絡自己去學習一個這樣的度量函數,這里的Relation network就是通過關系網絡來度量query和各類別之間的關系。
其網絡結構圖如下:
在這里是一個圖像分類的例子,轉換到文本上只要更改第一個embedding module。在這個模塊之后有一個relation module模塊,這個模塊就是度量query和每個類別的關系分數的。
假設support set總共有C個類別,以one-shot為例,其關系分數表達式如下:
上面式子中$x_i$表示support set中第$i$個樣本,因為是one-shot,所以一個樣本表示一個類別,因此$f_{\varphi}(x_i)$表示的是第$i$個類別的向量,$f_{\varphi}(x_j)$表示的是query中第$j$個樣本的向量。
而轉換到few-shot的場景下,論文這里是通過對樣本向量求和的方式來表示類向量。因為關系網絡得到是一個關系分數,因此作者認為用回歸的方式來訓練網絡更合適,因此這里的損失函數是均方誤差,表達式如下:
真實的標簽還是0和1,用計算出來的關系分數和0,1計算均方誤差。
論文四:Few-Shot Text Classification with Induction Network
這篇論文是阿里小蜜團隊提出的,並成功用在了他們的對話平台中,用來做少樣本的意圖識別。整體的訓練方式和上面兩篇論文一致,但是在類向量的表示上不再是簡單的求均值或者求和,此外也引入了關系網絡來計算query和類別之間的關系分數。
訓練模型的算法如下:
和上面的訓練方式基本一致。
首先來看下整個網絡結構圖:
整個網絡結構由三個模塊組成:Encoder Module,Induction Module,Relation Module。我們接下來一一介紹這三個模塊:
1)Encoder Module
這個模塊就是對輸入的樣本提取高層特征,用向量來表示它們。
在這里用的方法就是Bi-Lstm + attention的方式,這個做NLP的基本都很清楚,就不詳述。
2)Induction Module
這里也是整個論文的創新點,提出用膠囊網絡(Capsules Network)來動態的表征類向量,首先膠囊網絡是有Hinton提出的,關於膠囊網絡具體的描述見看完這篇,別說你還不懂Hinton大神的膠囊網絡,capsule network。在這里通過動態路由算法來得到某個類別下不同樣本對類向量的貢獻,簡單理解和attention中的加權和類似,所以后面作者也給出了基於attention的方法來表示類向量的實驗結果,但是效果較膠囊網絡要差一些。
首先將Encoder Module得到的support set的結果表示為$e^s$,query的結果表示為$e^q$,具體的流程如下:
(1)首先用一個矩陣將$e^s$映射到另一個空間,作者認為這一步很重要,可以起到類似聚類的效果,將相同的樣本映射到一個相同的子空間中,作者給出了轉換前后可視化圖的對比
可以看到矩陣映射之后類別之間的界面更加明顯,此外也和論文三做了對比:
可以看到本論文提出的Induction Network在類別聚合上的效果更好。
這個映射轉換的公式如下:
(2)對動態路由的值歸一化, 注意:這里的$b_i$在每個batch進來訓練時都應該初始化為0,因此它只是一個每次迭代的臨時變量,而不是計算圖中被訓練的永久變量。
上面的$i$表示第$i$個類
(3)加權和得到類向量
(4)經過激活函數squash函數,得到新的類向量
(5)更新動態路由值
這里的更新方式確保了和類向量相近的樣本向量對應的路由值會增大,即$e_{i, j}^s$ 和 $c_i$的點積大,則$b_{i, j}$就大,在迭代計算$c_i$的時候,樣本$j$的貢獻就大。
動態路由值在一開始會全部初始化為0,經過softmax后可以認為所有的樣本對類向量的貢獻是一樣的,經過迭代可以得到新的動態路由值。在這里的迭代次數為3,整個Induction Module的算法如下:
3)Relation Module
關系模塊就是來度量query和類別之間的關系分數的,注意,這里的權重$W_r, b_r$在每個類別中是共享參數的,其計算公式如下:
最后的損失函數也是采用了均方誤差。
參考文獻:
Siamese Neural Networks for One-shot Image Recognition
Prototypical Networks for Few-shot Learning
Learning to Compare: Relation Network for Few-Shot Learning
Few-Shot Text Classification with Induction Network
數據集來源:Mo Yu, Xiaoxiao Guo, Jinfeng Yi, Shiyu Chang, Saloni Potdar, Yu Cheng, Gerald Tesauro, Haoyu Wang, and Bowen Zhou. 2018. Diverse few-shot text classification with multiple metrics