【論文読み】異常検知を支える技術

[前回の記事](https://qiita.com/shinmura0/items/06d81c72601c7578c6d3)では、ディープラーニングの異常検知に関するベンチマークを
行いました。その結果、「L2-SoftmaxLoss」が一番良い性能を示しました。

本稿では、その元になった「論文の概要」と「異常検知に適用した場合の考察」を
記したいと思います。

※なお、本稿の図は特に明記がない場合は論文（[L2-constrained Softmax Loss for Discriminative Face Veriﬁcation
](https://arxiv.org/pdf/1703.09507.pdf)）より引用しています。

#論文の結論
結論からいうと、論文で言いたかったことは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/4a894be4-fe22-90c1-57fc-f8c15e7822e3.png)

ということです。この意味が分かる方は、既に論文のほとんどを理解できています。
あとは、分類精度を向上させるために、ソフトマックス関数をどう改造するかのお話しです。

#ソフトマックス関数のクロスエントロピー
分類問題で良く使われるソフトマックス関数のクロスエントロピーは
以下のとおりです。

```math
L_S=-\frac{1}{M} \sum_{i=1}^M log \frac{e^{W_{y_i}^Tf(x_i)+b_{y_i}}} {\sum_{j=1}^Ce^{W^T_jf(x_i)+b_j}}(1)
```

ただし、

+ M：バッチサイズ
+ C：分類クラスの数
+ $W_{y_i}^Tf(x_i)+b_{y_i}$：ニューラルネットワークのユニットの出力

です。一般的に、この式を最小化することで分類精度は上がっていきます。
しかし、特殊な条件下では、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/4a894be4-fe22-90c1-57fc-f8c15e7822e3.png)

となることがあります。それは、「容易い入力の時はニューラルネットワークの
出力を大きくし、難しい入力のときは出力を小さくするとき」です。

#数値例で考える
式で考えると分かりづらいので、数値例で考えます。

今、バッチサイズをM=3とおきます。
そして、分類クラス数をC=2とおきます。

今、3つの入力があり、正解ラベルyが次のように与えられているとします。

```math
\begin{align}
    y&=
    \begin{pmatrix}
    1 & 0 \\
    1 & 0 \\
    0 & 1 
    \end{pmatrix}
    \\

\end{align}
```

そして、ニューラルネットワークのユニットの出力$O(=W_{y}^Tf(x)+b_{y})$が
次のような値になったとします。

```math
\begin{align}
    O&=
    \begin{pmatrix}
    4 & 6 \\
    10 & 0 \\
    0 & 10 
    \end{pmatrix}(2)

\end{align}
```


ここで気を付けていただきたいのは(2)式をソフトマックス関数に
渡すと、見慣れた以下のような出力に近い値が出てきます。

```math
softmax(O)=
    \begin{pmatrix}
    0.4 & 0.6 \\
    1 & 0 \\
    0 & 1 
    \end{pmatrix}
```

つまり、確率の形式です。正解ラベルyと見比べると、1サンプル目が
間違えており、3サンプル中の精度は66％であることがわかります。
学習によって、（2）式の1行目の値を修正してほしいところです。

$L_S$を使って学習を行います。（1）式に（2）式を代入します。


```math
\begin{align}
L_S&=-\frac{1}{3} \sum_{i=1}^3 log \frac{e^{W_{y_i}^Tf(x_i)+b_{y_i}}} {\sum_{j=1}^2e^{W^T_jf(x_i)+b_j}}\\
   &=-\frac{1}{3} [log\frac{e^{4}}{e^{4}+e^{6}} + log\frac{e^{10}}{e^{10}+e^0} + log\frac{e^{10}}{e^0+e^{10}}]\\
   &=-\frac{1}{3} [log\frac{e^{4}}{e^{4}+e^{6}} + 2log\frac{e^{10}}{e^{10}+1}](3)
\end{align}
```

今問題となっているのは、1サンプル目のスコアです。
従って、（3）式の1項目に着目します。計算すると以下のようになります。

```math
log\frac{e^{4}}{e^{4}+e^{6}}=-2.13(4)
```

学習によって（4）式がどのように変化するのかを見ていきます。
学習とは、$L_s$を最小化することであり、（4）の値を大きくすることに
相当します。（4）式の値を大きくするシナリオは2つあります。

##シナリオ1
（2）式のスコアが$[4,6]→[10,0]$になったとしたら、つまり不正解→正解に
変化したらどうなるでしょうか。このとき、（4）式は以下の値になります。

```math
\begin{align}
log\frac{e^{10}}{e^{10}+e^{0}}&=-4.54\times10^{-5}\\
&> -2.13
\end{align}
```

狙い通り（4）式の数値が大きくなりました。

つまり、学習によって精度が上がったことになります。
常にこのような処理になっていれば良いのですが。。。

##シナリオ2
（2）式のスコアが$[4,6]→[0.4,0.6]$になったとしたら、つまり不正解のまま
数値の大きさ（ノルム）が小さくなったらしたらどうなるでしょうか。
このとき、（4）式は以下の値になります。

```math
\begin{align}
log\frac{e^{0.4}}{e^{0.4}+e^{0.6}}&=-0.798\\
&> -2.13
\end{align}
```

狙いが外れ（4）式の数値が大きくなりました。
つまり、学習したのに精度は上がらないことになります。

##ノルムの大きさ
以上で見てきたように、特殊な条件下では、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/4a894be4-fe22-90c1-57fc-f8c15e7822e3.png)

となることがあります。それは、不正解の画像のスコアを小さく、つまり
数値全体を小さくする（ノルムを小さくする）することで$L_S$を小さく
するときに発生します。

さらに、悪いことに(3)式の2項目のノルムを大きくすることでも$L_S$が下がります。

まとめると、「容易い入力の時はニューラルネットワークの出力のノルムを大きくし、
難しい入力のときは出力のノルムを小さくする」ことで$L_S$を下げ、学習が進んでも
分類精度が上がらない状況が起こりえます。

#ノルムの大きさに制限を加える
そこで、論文ではノルムの大きさに制限を加え

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/4a894be4-fe22-90c1-57fc-f8c15e7822e3.png)

が起きにくい状況を作っています。つまり、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/d26ff31a-54ea-a811-c419-806e4518cf1b.png)


という処理を加えています。まず、単位ベクトルになるように変換を加え、そのあと
$\alpha$倍しています。論文では、これを「L2-SoftmaxLoss」と呼んでいます。
可視化すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/9fdaea27-8e69-7e2f-a43b-a0af4eb3f0f0.png)

図は自作したものです。クラス数が２つの場合を考えています。
ソフトマックス関数に入れる直前の出力$O$をイメージしています。

左図は通常のソフトマックス関数を示しています。ノルムに制限がないため
自由度が高く、かなりばらついています。そして、容易い画像はノルムが大きく、
難しい画像はノルムを小さくする可能性があります。

一方、右図はL2-SoftmaxLossを示しています。ノルムに制限が加えられて
いるため、自由度が低く、結果的に非常にまとまりが良くなっています。
これが距離学習（metric learning）と呼ばれる所以かと思います。
出力が二次元の場合、出力は円上に拘束されることになります。
出力が四次元以上の場合は、超球面上に拘束されます。

#実験結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/1f1679b2-f3bf-cb1f-1bca-ec8b3f390c65.png)

上の図は通常のソフトマックス関数を使ったものです。

一番上の行は出力のノルムが大きい場合、一番下は出力のノルムが小さい場合です。
直感的に、一番上は特徴が掴みやすく、**分類しやすい画像**だと思われます。
一方、一番下は特徴が掴みにくく、**分類しにくい画像**です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/e895dfdb-60a7-0f1a-1f88-feeafa0c3db6.png)

上の図は、データセットLFWを使った場合の精度を表しています。
緑の線は通常のソフトマックス関数で学習したもの。赤い線は$\alpha$を
変えながら、L2-SoftmaxLossで学習したものです。$\alpha=16$の時に
精度が最も高くなっています。最高精度は以下のとおりです。

||精度|
|---|---|
|SoftmaxLoss|98.1%|
|L2-SoftmaxLoss($\alpha=16$)|**99.28%**|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/f92e1b47-52e1-6606-bf53-c9186a287f90.png)

上の表は、データセットMNISTを使って通常のソフトマックス関数と
L2-SoftmaxLossの分類精度を比較したものです。L2-SoftmaxLossの方が
精度が良くなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/d972d4f2-31a4-9802-56e5-f1a89c890501.png)

上の図は、MNISTで学習したモデルの出力を可視化したもの。左図は通常の
ソフトマックス関数、右図はL2-SoftmaxLossのもの。
右図の方がばらつきが小さく、まとまっている印象を受けます。

#異常検知に適用した場合
ここからは、私の考察になります。
論文の内容ではありませんので、ご注意ください。

##L2-SoftmaxLossで異常検知性能は上がるの？

なぜ、L2-SoftmaxLossを適用すると異常検知性能が上がるのでしょうか？
それは、出力のまとまりが良くなるためです。

Figure3で解説したとおり、L2-SoftmaxLossを適用すると非常にまとまりが
良くなります。さらに、密度も通常のソフトマックス関数に比べ、均一になる
傾向にあると思われます。

ディープラーニング（metric learning）で異常検知する際、均一である方が異常検知性能が
上がります。通常、異常スコアはK近傍法やLOFを使って算出されますが、K近傍法だと
不均一なデータには適用できません。一方、LOFだとある程度不均一な部分を吸収できますが、
やはり均一である方が性能が上がります。

直感的にいうと、L2-SoftmaxLossを適用することにより、異常と正常の領域が
よりはっきりイメージです。

##異常スコアの算出方法は？
ここまで、書いてきて気付きましたが、L2-SoftmaxLossで異常スコアを出す際は
LOFじゃなくて、コサイン類似度の方が適切な気がしてきました。

異常スコアの算出方法はLOF以外も色々あり、試行錯誤してみると性能が上がる
かもしれません。

+ ユークリッド距離
+ マハラノビス距離
+ LOF
+ K近傍法（KNN）
+ コサイン類似度

#まとめ
+ 通常のソフトマックス関数を使うと、「精度が上がらないが損失関数が下がる」現象が起こりうる。
+ L2-SoftmaxLossを使うとそれを防ぐことができ、結果的に分類精度が上がる。
+ L2-SoftmaxLossを異常検知に適用すると、異常と正常の領域がはっきりして異常検知性能が上がる。