活性化関数再考〜微分可能性〜

# TL;DR
ニューラルネット出力の二階微分使いたいなら活性化関数はtanhかsoftplusにしよう。
# はじめに
ニューラルネットの学習にweightやbiasの微分が使われているのは言うまでもない。これらが定義できるためには活性化関数が微分可能である必要がある。しかし、この要求は1階の微分に対してだけであり、２階以上の微分は要求されてない。2階以上の微分の情報が欲しい~~マニアックな~~場合は、それがうまく定義できている必要があるため、いつも使っている活性化関数が適切なのか検討する必要がある。

# 問題設定
1次元ガウス関数の回帰問題を考える。ガウス関数は
$$
y=e^{-x^2}
$$
であり、その1階微分、2階微分は次のようになる。
$$
\frac{dy}{dx}=-2xe^{-x^2}\\\\
\frac{d^2y}{dx^2}=(4x^2-x)e^{-x^2}
$$
これらが正しく求められているかを評価する。ネットワークは隠れ層8層、各隠れ層のノード数20の全結合ネットワークを用いる。学習にはフルバッチのBFGSを用いる。教師データは$x\in[-2, 2]$のデータをランダムに1000点与える。また、テスト用データは$x\in[-2, 2]$を100分割した値を用いる。

#結果
活性化関数はReLu
$$
\sigma(x)=\max(x,0)
$$
tanh
$$
\sigma(x)=\tanh(x)
$$
シグモイド関数
$$
\sigma(x)=\frac{1}{1+e^{-x}}
$$
softplus
$$
\sigma(x)=\log(1+e^x)
$$
selu
$$
\sigma(x)=\lambda
\begin{cases}
x & x>0\\\\
\alpha(e^x-1) &x\leq0
\end{cases}
$$
elu
$$
\sigma(x)=
\begin{cases}
x & x>0\\\\
\alpha(e^x-1) &x\leq0
\end{cases}
$$
を試す。
##ReLU
関数自体は再現できているが、その微分は概形のみしか再現できていない。二階微分に至ってはすべて0になっている。
<img src=https://qiita-image-store.s3.amazonaws.com/0/294848/4848daed-c67b-51b1-8bf9-c624cc234de0.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/96c090b9-00ef-e649-30aa-bb3641662ac7.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/7231fd5e-95ea-a1d3-07fd-2a331eecff91.jpeg width=30%>

MSE誤差

|$y$|$y_x$|$y_{xx}$
|---|---|---
|1.4e-3|5.2e-2|9.6e-1

##tanh
一回微分、二階微分ともによく再現できている。
<img src=https://qiita-image-store.s3.amazonaws.com/0/294848/4b8c0892-ac01-cd6c-84e6-1b4b012bf1d6.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/e166123c-7b1d-444c-cfee-946b3f5e8ebc.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/d5088c2c-93fd-a0ee-628d-d6dc6f471d04.jpeg width=30%>
MSE誤差

|$y$|$y_x$|$y_{xx}$
|---|---|---
|7.5e-4|4.8e-3|3.0e-2

##シグモイド関数
なぜかBFGSがうまくいかなかったのでAdamで学習した。一回微分、二階微分ともにそこそこ再現できているが、tanhには劣る。
<img src=https://qiita-image-store.s3.amazonaws.com/0/294848/d0bb08e7-8975-90c6-8c95-6d602f1814bd.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/cbed92d7-cc6b-8e82-8e07-12a33ba86485.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/a3ec16ed-c67d-f7db-69df-5dcb0fea9451.jpeg width=30%>
MSE誤差

|$y$|$y_x$|$y_{xx}$
|---|---|---
|1.2e-3|1.0e-2|6.6e-2

##softplus
tanhと同じく、一回微分、二階微分ともによく再現できている。
<img src=https://qiita-image-store.s3.amazonaws.com/0/294848/0d4abf68-c8eb-6b68-c047-c7873fe5ed11.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/814cf58f-42d3-dcd8-d291-09757fec659a.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/b709e5ca-2ba8-ea88-9491-845310f1cc33.jpeg width=30%>
MSE誤差

|$y$|$y_x$|$y_{xx}$
|---|---|---
|4.7e-4|3.5e-3|2.0e-2
##selu
一回微分はReLUよりマシだが、2階微分はダメダメ。
<img src=https://qiita-image-store.s3.amazonaws.com/0/294848/014439c2-1a49-e620-4661-8d0cc9b6e8ca.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/b77fec64-f5b2-a5a2-df05-00a372860a14.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/4b61fa8b-b77a-d774-d685-a46e033776ec.jpeg width=30%>
MSE誤差

|$y$|$y_x$|$y_{xx}$
|---|---|---
|7.7e-4|3.1e-2|1.9e+0
##elu
一回微分まではそこそこだが、2階微分は可能性を感じるものの、残念な感じ。
<img src=https://qiita-image-store.s3.amazonaws.com/0/294848/f87e5654-778c-dbdf-bdfb-940cec390de0.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/16122e3d-5cde-db05-af06-60f23a55ff20.jpeg width=30%><img src=https://qiita-image-store.s3.amazonaws.com/0/294848/bdb3a860-a77f-e1cb-d92b-27557d889811.jpeg width=30%>
MSE誤差

|$y$|$y_x$|$y_{xx}$
|---|---|---
|1.2e-3|1.3e-2|4.7e-1

MSE誤差をまとめる次のようになる。

|活性化関数|$y$|$y_x$|$y_{xx}$
|---|---|---|---
|ReLU|1.4e-3|5.2e-2|9.6e-1
|tanh|7.5e-4|4.8e-3|3.0e-2
|シグモイド関数|1.2e-3|1.0e-2|6.6e-2
|softplus|4.7e-4|3.5e-3|2.0e-2
|selu|7.7e-4|3.1e-2|1.9e+0
|elu|1.2e-3|1.3e-2|4.7e-1

# 考察
ReLUがうまくいかない理由は、そもそも（原点を除いて）二階微分が0になるからである。eluやseluは、負の値に関しては二階以上の微分可能であるものの、正の値ではReLUと同様、二階微分が0になるため、うまくいかないと考えられる。tanhやシグモイド関数、softplusはすべての領域に渡って二階以上の微分が可能であるため、うまくいっている考えられる。ただし、シグモイド関数が若干劣っている意味はよくわからない。何かアイデアがあれば教えていただきたい。

# 結論
ニューラルネット出力の二階微分使いたいなら活性化関数はtanhかsoftplusにしよう。

# 参考
二階以上の微分が必要な場合としては、BFGSのような二階微分の情報を使った学習アルゴリズムなどがある。とはいっても、2階微分が0でも1階微分が有限であれば学習が進むため、ReLUでもBFGSは使える。他には、ディープラーニングで微分方程式を解く場合は2階以上の微分が必要となる（拙作の[理論編](https://qiita.com/ryuoujisinta/items/5f65fca836f9dc2b2ad4)、[実践編](https://qiita.com/ryuoujisinta/items/d2fad0587aa124c28e0a)）。