マイナーな正則化手法「ラベル平滑化」は実は効果アリアリらしい

教師あり学習のクラス分類タスクにおいては、既に様々な正則化手法が考案・実用化されています。
例えば、荷重減衰（Weight Decay）、ドロップアウト、バッチ正規化やレイヤー正規化などが知名度高いでしょう。
しかし「ラベル平滑化（Label Smoothing)」というのは、「あ～なんか聞いたことある」とか「何それ？」というくらい、認知度がありません。
なぜでしょう？**実装は恐ろしいほど簡単**で、ちゃんと **[論文](https://arxiv.org/abs/1512.00567)もある（※1）** んですが。

※1）「Rethinking the Inception Architecture for Computer Vision」のP6「7. Model Regularization via Label Smoothing」

本稿では、ラベル平滑化の正則化の効果をMNISTを使用して実験し、少なくとも**この実験の条件下においては正則化の効果がある**ことを示しています。
また、ラベル平滑化を適用すると起こる興味深い現象についても取り上げています。


### ラベル平滑化とは

#### 仕組み

**訓練**データの正解ラベルのone-hot vectorを、「0」「1」と白黒はっきりさせないで、「少しボカした」数値にする、というものです。
（**テスト**データの正解ラベルに対しては行いません）

ハイパーパラメータ「ε」（0 < ε < 1.0）というのを決めます。
正解クラスのラベル数値を、「1」→「1 − 𝜖」
他の不正解クラスラベル数値を、「0」→「𝜖 / (k − 1)」　（kはクラス数）
に置き換えます。
![ラベル平滑化の正解ラベルベクトルの図_80.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613026/c8c3f468-f70f-3bf0-f2ea-d32a854400de.png)

この「＜ラベル平滑化後＞」を正解ラベルとして、いつもと同じように教師ありクラス分類タスクの訓練を施します。
「実装は恐ろしいほど簡単」の意味がお分かりいただけたと思います。

#### 解釈

訓練データの正解ラベルのone-hot vectorを、「0」「1」と白黒はっきりさせないで、「少しボカした」数値にする
⇒
**訓練の目的地を”少し曖昧にして広めに取る”、ということで、訓練データに対する過剰適合を抑制している**、と解釈できます。

本来は、正則化というよりも、訓練データ集合内のラベルの誤りの多さに対応したものです。
εは、「訓練データの正解ラベルが確率𝜖で誤っている」と仮定する数値です。
訓練の目的地を”少し曖昧にして広めに取る”、という内容からして正則化にも効果ありそう、ということで、このように正則化に使用されるようになったようです。

### ラベル平滑化の効果測定実験

実際に実験してみました。

条件は以下の通りです。
タスク種類：画像クラス分類
データセット：MNIST
　訓練データは先頭24000件/60000件、テストデータは10000件全件
モデル：下記図（要するにごく普通の構成）
　バッチ正規化とドロップアウトを併用（ドロップアウトの方が後ろなので問題無し）
　※モデルのパラメーターの初期値は、常に必ず同一
エポック数：100エポック
バッチサイズ：32
荷重減衰の係数：0（つまり適用しない）

#### モデル構成
![model構成_80.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613026/80e15552-04a5-8940-7c0f-a1c538aba9f1.png)

#### 実験1：いろんなεでTest AccuracyとTest Lossを比較

以下の何通りかのεでTest AccuracyとTest Lossを観測しました。

##### 実験1の条件

|ε |意味・意図  |実験結果のグラフの線の色|
|:-:|---|:-:|
|0|ラベル平滑化を適用しない<br>例）：{ 1.0, 0, 0, … ,0 }|**黒**|
|0.0015|正解ラベルをやや平滑化<br>ε本来の意味では、正解ラベルの667個に1個誤りがあることを示す<br>例）：{ 0.9985, 0.0001667, 0.0001667, … ,0.001667 }|**<font color="pink">ピンク</font>**|
|0.0040|正解ラベルを平滑化<br>ε本来の意味では、正解ラベルの250個に1個誤りがあることを示す<br>例）：{ 0.996, 0.0004444, 0.0004444, … ,0.004444 }|**<font color="orange">オレンジ</font>**|
|0.03|正解ラベルを大きく平滑化<br>ε本来の意味では、正解ラベルの33個に1個誤りがあることを示す<br>例）：{ 0.97, 0.0033333, 0.0033333, … ,0.0033333 }|**<font color="purple">紫</font>**|

##### 実験1の結果と考察

実験結果のTest AccuracyとTest Lossは以下の通りです。
![TestAccuracy_TestLoss_実験1_注釈付き.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613026/d2bbbfe5-0cd4-7781-3b36-73ba17d5f659.png)

**ラベル平滑化非適用のε＝0は、開始早々、過剰適合**を起こし始めています。
また、Test Accuracyの順位は、<font color="orange">ε＝0.004</font> ≒ <font color="pink">ε＝0.0015</font> > <font color="purple">ε＝0.03</font> > ε＝0 となっています。
これらのことから、**ラベル平滑化は、Test Accuracyを上げる効果はあった、** と言えるでしょう。

**<font color="orange">ε＝0.004</font>、<font color="pink">ε＝0.0015</font>は、Test Accuracyが高く、Test Lossが一貫して逓減傾向にある＝過剰適合を一貫して抑制しており、正則化の効果があった、** と言えるでしょう。

一方で、<font color="purple">ε＝0.03</font>は、Test AccuracyもTest Lossも双方高い、という、一見すると矛盾した状態になっています。
これは、「Accuracyという指標の性質」と「強めのラベル平滑化による訓練結果の傾向」の複合現象と推測します。
以下のようなことが起こっていると思われます。
訓練データ内の正解ラベルのone-hot vectorを「強め」にボカして訓練した結果、テストデータに対する推論結果は、以下のように「弱気」になる傾向が生じるでしょう。
例）：{ 0.64, 0.02, 0.09, … ,0.04 }
が、Accuracy「正解率」という観点では、以下のような「強気」の推論結果
例）：{ 0.94, 0.002, 0.009, … ,0.004 }
と同じ「1問正解」とカウントされます。
しかし一方で、Cross Entropy Lossでは、両者の違いが如実に表れます。
これが、εが過大でLossが高くても、Accuracyの高さを維持する理由です。

まとめると、
**・Accuracyの高さのみを求めるなら、εは過大な数値でもよい（でなくてもよい）**
となります。
　※少し考えればわかりますが、この結論はクラス数に依存します。**クラス数が少なくなるほど、εの数値の大きさを許容しなくなる**でしょう。
また、
**・Accuracyの高さとLossの低さの両方を求めるなら、εはそこそこ大きな数値が良い**
　「そこそこ」がどのくらいなのかは、Cross Validationなどやって探索するか、εの元々の定義である「そのデータセットの正解ラベル中にどのくらい誤りが含まれていそうか」を目安に決めるしかないです。
**・εが過大でも過少でもないある程度の幅の中にある場合、訓練の進行に伴い過剰適合に陥ることなく汎化性能がアップしていく**
　これがラベル平滑化という手法の最大の利点だと、個人的には思います。
　ここでは、汎化性能 ≒ Test Lossの低さ としています。

-----
#### ここまでのまとめ

・ラベル平滑化には正則化の効果がある
・汎化性能の高さとして、Accuracyの高さのみを求めるなら、εは過大な数値でもよい（でなくてもよい）
　（ただし、クラス数が少なくなるにつれ、数値の大きさを徐々に許容しなくなる）
・汎化性能の高さとして、Accuracyの高さとLossの低さの両方を求めるなら、εはそこそこ大きな数値が良い
・εが過大でも過少でもないある程度の幅の中にある場合、訓練の進行に伴い過剰適合に陥ることなく汎化性能がアップしていく

-----


#### 実験2：異常に大きいεでTest AccuracyとTest Lossを比較

「Accuracyの高さのみを求めるなら、εは過大な数値でもよい」と言われても、「過大ってどれほど？」と疑問がわくでしょう。
そこで、εを、以下の通常ではありえないほど大きな数値にして、実験してみました。
**ε＝0.49・・・これは、εの元々の定義では、訓練データの正解ラベルの半分に誤りがあることを意味し、本来ならばありえない想定を表す「異常値」** です。

##### 実験2の条件

最後の行「ε＝0.49」のみ新規追加で、他の行は実験1と同じ

|ε |意味・意図  |実験結果のグラフの線の色|
|:-:|---|:-:|
|0|ラベル平滑化を適用しない|**黒**|
|0.0015|正解ラベルをやや平滑化<br>ε本来の意味では、正解ラベルの667個に1個誤りがあることを示す<br>例）：{ 0.9985, 0.0001667, 0.0001667, … ,0.001667 }|**<font color="pink">ピンク</font>**|
|0.0040|正解ラベルを平滑化<br>ε本来の意味では、正解ラベルの250個に1個誤りがあることを示す<br>例）：{ 0.996, 0.0004444, 0.0004444, … ,0.004444 }|**<font color="orange">オレンジ</font>**|
|0.03|正解ラベルを大きく平滑化<br>ε本来の意味では、正解ラベルの33個に1個誤りがあることを示す<br>例）：{ 0.97, 0.0033333, 0.0033333, … ,0.0033333 }|**<font color="purple">紫</font>**|
|0.49|正解ラベルを強烈に平滑化<br>ε本来の意味では、正解ラベルの半分に誤りがあることを示す<br>例）：{ 0.51, 0.0544444, 0.0544444, … ,0.0544444 }|**<font color="red">赤</font>**|

##### 実験2の結果と考察

実験結果のTest AccuracyとTest Lossは以下の通りです。
![TestAccuracy_TestLoss_実験2_注釈付き.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613026/8e4b434a-648f-534e-d195-a7100aa8a41e.png)

<font color="red">ε＝0.49</font>は、**通常では想定しえない異常に大きな数値であるにもかかわらず、Test Accuracyでは本稿におけるsotaを達成**してしまいました。
一方で、Test Lossでは、他のεに対して見る影もなく大惨敗しています。
中で起こっていることは、実験1の考察で挙げた、
『「Accuracyという指標の性質」と「強めのラベル平滑化による訓練結果の傾向」の複合現象』
でしょう。

まとめると、
**・Accuracyの高さのみを求めるなら、εは異常なくらい大きくてもOK**
　（くどいようですが、クラス数にも依存します）
となります。

-----
#### ここまでのまとめ

・ラベル平滑化には正則化の効果がある
・汎化性能の高さとして、Accuracyの高さのみを求めるなら、εは異常なくらい大きい数値でもよい（でなくてもよい）
　（ただし、クラス数が少なくなるにつれ、数値の大きさを徐々に許容しなくなる）
・汎化性能の高さとして、Accuracyの高さとLossの低さの両方を求めるなら、εはそこそこ大きな数値が良い
・εが過大でも過少でもないある程度の幅の中にある場合、訓練の進行に伴い過剰適合に陥ることなく汎化性能がアップしていく

-----

#### おもしろい現象　Train LossとTest Lossの大小関係逆転

通常、Train LossとTest Lossの大小関係は、
Train Loss < Test Loss
になります（よほど強い正則化をしなければ）。
これは当たり前で、訓練データ中の正解ラベルに向かって訓練するからです。

しかし**ラベル平滑化の下では、εの数値が微小でなければ、逆の大小関係
Train Loss > Test Loss**
となります。
以下のグラフをご覧ください。

ε=0.004での、Train LossとTest Lossの比較
明白に、<font color="#1f77b4">Train Loss</font> > <font color="orange">Test Loss</font>　となっています。
![TrainLossとTestLossの比較_ls0004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613026/4d584fa0-bb94-239a-57ed-b21013ac39b4.png)

以下は、私が推測する理由です。

訓練データの正解ラベルは、「0」と「1」から少しだけボカした数値になっています。
訓練データの正解ラベルの例 ）{0.996, 0.0004444, 0.0004444, … ,0.004444 }
上記の例の場合、正解クラス（インデックス＝0、先頭）は確率の上限値「1」ではなく、「0.996」なので、クラスインデックス＝0に対する推論確率は、0.996未満も、0.996超もあり得ます。
つまり、推論結果として確率0.996の**上下両側**がありうる、ということです。
例えば、クラスインデックス=0の正解クラスに対して、0.998と推論したとします。
人間の感覚としては、「より正確に推論してていいじゃないか」となりますが、それは人間の感覚でしかなく、訓練データの正解ラベルとしては、あくまでも「0.996という推論確率が100点満点」であり、0.994でも、0.998でも、（人間にとっての100点満点である）1.0でも、「100点満点の答え0.996からズレた推論」となり、Lossが発生する、ということです。
不正解クラス（例えばインデックス＝1、左から2番目）は確率の下限値「0」ではなく、「0.0004444」なので、クラスインデックス＝1に対する推論確率は、0.0004444未満も、0.0004444超もあり得ます。
つまり、推論結果として確率0.0004444の**上下両側**がありうる、ということです。
例えば、クラスインデックス=1の不正解クラスに対して、0.00032と推論したとします。
ここも同様に、訓練データの正解ラベルとしては、あくまでも「0.000444という推論確率が100点満点」であり、0.0005でも、0.00032でも、（人間にとっての100点満点である）0でも、「100点満点の答え0.000444からズレた推論」となり、Lossが発生する、ということです。

一方で、テストデータの正解ラベルは、当然ですが、「0」と「1」のone-hot vectorのままです。
テストデータの正解ラベルの例 ）{1.0, 0, 0, … ,0 }
この場合、「推論結果は上下両側がありうる」ということはなく、正解クラスインデックス＝0に対する推論確率は1を超えないし、不正解クラスインデックス≠0に対する推論確率は0を下回らないです。

これが、私が推測する理由です。
（ということが、[論文](https://arxiv.org/abs/1512.00567)にも書いてあったと認識しています。私の勘違いなら、どなたか優しく指摘お願いします。）

### まとめ

ラベル平滑化は、コストパフォーマンスの優れた正則化手法です。

汎化性能の高さとして、Accuracyの高さだけを求めるなら、εはかなり大きい数値でもよいです。
適切なεの数値がわからなくても、（Accuracyを高くするだけなら）かなり大きい数値を設定すればよい、ということです。
もちろん、大きい数値でなければダメ、というわけではありません。
ただし、クラス数が少なくなるにつれ、数値の大きさを徐々に許容しなくなることに注意してください。

もし、汎化性能の高さとして、Accuracyの高さとLossの低さの両方を求めるなら、εはそこそこ大きな数値が良いです。
どれくらいが良いかは、Cross Validationで決めるか、訓練データセット内に誤った/紛らわしい正解ラベルがどのくらい含まれているか、を目安に決めるといいでしょう。

εが過大でも過少でもないある程度の幅の中にある場合、訓練の進行に伴い、過剰適合に陥ることなく汎化性能が着実にアップしていく、というハッピーな状態が到来します（※2）。
悪あがきなどせず、テレビでも見ながら、規定のエポックが終わるのを落ち着いて待ちましょう。
※2：お約束するものではありません。

#### ご注意

本稿に記載した実験結果、及びその実験結果の考察や私の意見は、以下の条件
・MNISTという単純な画像データセット
・画像をモデルに通して各クラスの確率を出すだけの単純なクラス分類タスク
・訓練に使用した自作モデル
・その他、「実験の条件」等で記した条件
の下でのものです。
例えば、画像データセットを、MNIST → CIFAR10　と、画像1枚のデータ量がより多いものに変えた場合、同じ実験結果が得られるか、は分かりません。