論文紹介 - Universal Language Model Fine-tuning for Text Classification (ULMFiT)

# Universal Language Model Fine-tuning for Text Classification

汎用性が高く性能の良いNLP向けの転移学習手法の提案
Wikipediaのような入手しやすい言語資源を利用することで、少量のラベル付きデータで良い性能を出せることを示している

* [論文](https://arxiv.org/pdf/1801.06146v5.pdf)
* [特設ページ](http://nlp.fast.ai/category/classification.html)
* [Q&A](https://news.ycombinator.com/item?id=17076222)
* [コード](https://github.com/fastai/fastai/tree/master/courses/dl2/imdb_scripts)（Pytorchベース）
* [Fast.aiのCourse](http://forums.fast.ai/t/part-2-lesson-10-wiki/14364)
（本内容が扱われている）

## ハイライト
1. 汎用性の高いNLP向けの転移学習手法を提案
2. 従来の転移学習の際に生じる情報消失を防ぐ学習法の提案
3. 6つの分類タスクでSOTAに比べて18-24%のerror rateの低減を達成
4. サンプル効率が高い（少ないサンプルで性能を出せる）
5. モデルとコードを提供

学習方法の提案で、新しいネットワークアーキテクチャの提案ではない。
数式はほぼ出てこない。

## 背景
* CVは転移学習の恩恵に浴していて羨ましい
* NLPではDNNによってSOTAの成果を得られてはいるが、多くはスクラッチからの学習が必要
* 既存手法の[Language Model](https://arxiv.org/pdf/1511.01432.pdf) は、膨大なin-domain documentが必要
    * → in-domain document集めるの大変だし、転移学習とかでなんとかなれば...
 
### 現在のNLPにおける転移学習事情
* NLPでは、Transductive transfer [^1] が主な研究対象とのこと
* Inductive transfer[^2]の例としては、事前学習したembedding layerをinputにおいて全体を学習するパターンが流行
    * モデリングしなければいけない上層の範囲が大きい
    * しかし、CVでの転移学習と比べると、お手軽さが低い
    * より便利なNLP用の転移学習モデルが欲しい

### 方針
* NLPのモデルとして汎用性のあるものを使って転移学習できるようにする
* モデルではなく学習の方法を工夫する
  * fine-tuningする際に事前学習した情報が失われてしまうのが問題
  * NLPはCVに比べて浅いネットワークなので、CVとは違ったアプローチが必要となるはず

## Universal Language Model Fine-tuning (ULMFiT)
* Language Model（LM; ngramのニューラルネット版）を source taskとする
    * 多くの応用の重要な要素である
    * 様々な言語的な特徴を捉えることができる
    * MT等と比べて、無限に近いデータがある
    * etc.. と、理想的なsource taskに見える

* 実用的なメリット
  * 様々なドキュメントサイズについてworkする
  * single architecture/training process
  * 追加のfeature engineering不要
  * in-domain documents/labelsが不要

* 今回ベースとするモデルは[AWD-LSTM](https://arxiv.org/pdf/1708.02182.pdf)
    * → 3層LSTM+[DropConnect](https://cs.nyu.edu/~wanli/dropc/)[^3]+SGDの変形で頑張った手法）
* また、クラス分類をtarget taskとする


### 学習の流れ
1. General-domain LM pretraining
    * 大規模なGeneral-domain corpusでLMを事前学習
2. Target task LM fine-tuning
    * 1. のLMをTarget taskのコーパスを用いてfine-tuning
3. Target task classifier fine-tuning
    * 2. のLMをベースとしてTarget taskのclassifierを構成し、fine-tuning

<img width="687" alt="スクリーンショット 2018-06-14 11.55.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/e00fc4a6-2963-92b3-06ab-446837bd6f05.png">

### 1. General-domain LM pretraining
はじめに、General-domain corpusにより、LMを一から学習する。

* CVにおけるImageNetのように、大規模で言語の一般的な特徴を捉えることのできるコーパスを対象としてpretrainするのが良い
* 論文中では[Wikitext-103](https://einstein.ai/research/the-wikitext-long-term-dependency-language-modeling-dataset)を選択
  * 28,595 preprocessed Wikipedia articles
  * 103 million words.

この計算コストは高いけど、結果は使いまわせるから気にならないよね。


### 2. Target task LM fine-tuning
次に、1. の学習済みモデルに対し、Target taskのコーパスを使い、fine-tuningを行う。
ここでは学習に際し、Discriminative fine-tuning と Slanted triangular learning rate という２つのテクニックを用いる。
#### Discriminative fine-tuning
* 階層化した各レイヤはそれぞれ違った抽象度/情報を捉える
    * → 各々に適した"程度"でfine-tuningするのがよさそう
    * → それぞれのレイヤ毎で別のlearning-rateをとる
    * → レイヤごとのパラメータ $\theta^l$に、それぞれ異なる学習率$\eta^l$を用意する

これを
<img width="500" alt="スクリーンショット 2018-06-14 2.11.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/58ede8eb-2c58-f8e5-a9a3-a1748976e9a4.png">
こうする。
<img width="500" alt="スクリーンショット 2018-06-14 2.11.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/7ba480e9-d39a-e39b-545d-0862f4548f63.png">
もちろんSGDである必要はない。

* ηl-1 = ηl / 2.6 が経験的にうまくいくとのこと
    * (実装を見る限り、fine-tuningの時は違うパラメータ使っていように見えるが...）

#### Slanted triangular learning rates
* Learning rateをiterationが進むごとにどのように変化させていくか
* [Cyclical learning rates](https://arxiv.org/pdf/1506.01186.pdf)(Triangular learning rates)[^4]の派生形
    * 短期間でlearning rateが増加
    * その後徐々にlearning rateが減少
    * ピークが$\eta^l$となり、それに対する比率で増減させる

<img width="400" alt="d7a17f36-8bda-45a0-ad6f-9b4c2b7aa9ad.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/f2c2a9d2-36ed-8d46-a352-a7af59a426de.png">

### 3. Target task classifier fine-tuning
最後に、2. のモデルを使いTarget taskのclassifierを構成し、学習する。

* classifierの構成に際し、3.2のモデルに以下の２層を追加
  * batch normalization/dropout/ReLU
  * batch normalization/dropout/Softmax → output
* ここでも学習に際し、いくつかの工夫を入れる。

#### Concat pooling
* 分類タスクにおける重要な語は、文書中に点在するごく少数の語彙になる
    * → 最後のtime stepのhidden state（${\bf{h}}_T$）のみの考慮ではうまくいかない。
    * →　前方のtimestepsのhidden statesも考慮するようにする
    * （ただしメモリの許す限り）

<img width="500" alt="スクリーンショット 2018-06-14 2.59.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/ed355751-b8ed-7dd1-0719-be6204fbf844.png">


#### Gradual unfreezing
* 事前学習で得られた有益な情報がfine-tuningで消えてしまうのを避けるための工夫
  * 最初にlast layerをunfreezeする（パラメータのupdateが効くようにする）
  * epochごとにunfreezeするレイヤを増やしていく

（実装では3ステージに分けて、最終層のみ, 最終層+一つ前, 全部の順でunfreezeしてtrainingを回している様子）

#### BPTT for Text Classification (BPT3C)
* documentを固定長のバッチ に分割
* モデルは前のバッチの最後の状態で初期化

#### Bidirectional language model
* 順方向と逆方向のコーパスを作って独立に学習して、classifierの予測結果を平均する




## Experiments
### 実験タスクと利用するデータセット
* Sentiment Analysis
  * IMDb
  * Yelp
* Question Classification
    * TREC-6
* Topic classification
  * large-scale AG news
  * DBPedia ontology datasets

<img width="500" alt="671d0291-5429-4919-a7fe-68ab5d4ec0a0.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/fecc7e2d-6333-39a5-1792-bd8319018696.png">

### 結果

#### IMDb / Trec-6
<img width="586" alt="e7656e4b-a778-460f-85e8-be17708bd803.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/f48ef376-44a3-2e27-2f60-20a94d7c1fb2.png">

* [CoVe](https://arxiv.org/pdf/1708.00107.pdf)（転移学習のSOTA）に対して43.9/22% error rateの低減
* CoVeのような転移学習以外の手法と比較してもより良い結果
    * 複雑なアーキテクチャを採用しなくても、LSTMにdropoutを加えただけのモデルでSOTAを上回る性能
* IMDbは現実的なデータに近いからpromissing
* TREC-6は大幅な改善とはなっていない
  * テストセットが500と小さいため
* 1文からなる小さいデータから、比較的大きなデータも扱えるのは有益
* CoVeみたいに膨大な量（7 million sentences）のデータも必要としない

#### AG / DBPedia / Yelp
<img width="598" alt="3d9771ff-b43c-4cae-9ad0-cb4722308f3d.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/aa5e6e0b-9efc-6609-9bbc-d90bcd5303ed.png">

* これらについても軒並みうまくいっている
* error rateの逓減率
    * AG: 23.7% 
    * DBpedia 4.8%
    * Yelp-bi 18.2%,
    * Yelp-full 2.0%

## Analysis
### Low-shot learning

* ラベル付きデータが少ない場合の振る舞いを調べる
    * 転移学習のメリットを確認
* supervisedとsemi-supervisedでの実験

<img width="700" alt="413a7c9a-2659-4594-a7c4-8cff26e7fbd8.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/b3c0cc86-6ab6-813a-892f-17db8ee8a478.png">

* ラベル付きデータ100サンプル+転移学習の時の数字が、10〜20倍のラベル付きデータを用いてスクラッチで学習した時の数字と同等
* さらに50k〜100kのラベルなしのデータを利用することで、50〜100倍のラベル付きデータを用いてスクラッチで学習した時の数字と同等


### Impact of pretraining
* WikiText-103でのpretraining有無での比較
    * データセットが小さい（TREC-6）場合、大きな改善がある
    * データセットが大きい(IMDb/AG)場合でも、数字の改善に寄与

<img width="331" alt="bf113704-18cc-4408-96ab-cad7650d3877.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/ec48fad7-d2ab-d1fb-7ff0-cf97d71759d2.png">

### Impact of LM quality
* ベースとなるモデルがシンプルなものである場合の性能
    * Vanilla LM (AWD-LSTMからDropoutを外したもの)
    * モデルがシンプルであるにも関わらず、良い数字が出ている

<img width="338" alt="49b69d2b-1d59-4f95-a19b-d9d407c58ba3.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/3e11e9a3-bc43-8e32-dba7-5aba70f2a7fe.png">

### Impact of LM fine-tuning
* LM fine-tuningでの各種のテクニックのablation
    * 小さいデータセット(TREC-6)の場合、Full+discr+stlrでないと効果が無い
    * 大きいデータセット(IMDb/AG)では、fine-tuningの効果を得やすい

<img width="320" alt="22d492bd-709e-488a-ad86-988ec64ce5c7.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/fe455d29-3b06-f792-e888-d8a41278bf46.png">

### Impact of classifier fine-tuning
* classifier fine-tuningでの各種のテクニックのablation、および別手法との比較
    * スクラッチから学習するよりfine-tuningした方がうまくいく
    * 特にデータセットが小さい時に有効
    * 最終層だけのFine-tuningは、小さいデータセットの時に特にunderfitしがち
    * chain-sawはかなり良い結果だが、AGの結果は少し弱い
    * cosは小さいデータに弱い

* ボード上、どれにも良い結果を出しているのはULMFiTだけ
    * (論文中には、だからuniversalなんだと書いてある）

<img width="327" alt="674c334e-f05a-467a-bfbc-f602077c3224.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/2f00e0a6-5a01-a67a-9fb6-e07c886fb72f.png">

### Classifier fine-tuning behavior
* classifierのfine-tuningの「やり方」の違いで学習がどのように進むか
    * 各種テクニックを利用したものと、それらなしでfine-tuningしたものとの比較
    * validation error rateの推移

<img width="500" alt="2c8b8418-6c5d-48f4-ab75-27879897842c.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/401578be-37bb-855b-8d69-7b54faca86ac.png">

### Impact of bidirectionality
* 順方向、逆方向のコーパスそれぞれで個別に学習したモデルのアンサンブルの性能差
  * Unidirectionalなモデルに比べて、error rateが0.5-0.7くらいさらに改善する
  * IMDBでは、error rateが5.30 -> 4.58と改善


## 感想
* 触れ込みの通り、LMをベースにしているため、色々なNLPタスクに使えそうに思える
* 英語と比較すると、日本語のアノテーション済みコーパスは少ないため、本当に使いものになるなら恩恵が大きい
* また、実応用ではラベル付きデータが少ないことはよくあるので、うまくいくなら嬉しい
* アーキテクチャはシンプルだしコードも公開されているので理解はしやすい


---

[^1]: Transductive: transfer元ラベルあり、transfer先ラベルなし ([参考](http://www.kamishima.net/archive/2009-tr-jsai_dmsm1-PR.pdf))
[^2]: Inductive: transfer元ラベルあり、transfer先ラベルあり
[^3]: こんな感じのDropout <img width="625" alt="スクリーンショット 2018-06-14 0.29.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/9b3fa330-a8a1-27e6-63c3-d3882786b14a.png">
[^4]: こんな感じのlearning rateの変化<img width="328" alt="スクリーンショット 2018-06-14 2.39.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/12009/60fb37e7-a138-657c-6159-740ccb394671.png">