活性化関数とは
活性化関数とは、ニューラルネットにおいて、次の層に入力を渡す時に通る橋なようなもので、その橋を渡る過程でどのように変換されるかは活性化関数ごとに異なります。
また、どのような変換をさせたいかは隠れ層なのか出力層なのかによっても変わってきます。
そこで、目的別に活性化関数の数式と概形、Pythonにおける実装を見ていきたいと思います。
以下、すべてにおいて入力$x$ を活性化させたときに、$y=\phi(x)$ という変換が起きたというように記述します。
また、数学的な定義が定かでない部分がありますが、活性化関数としての使用という点から温かい目で見守ってください。
恒等関数:そのまんま変換
本当にそのまんま入力を渡したいときに使います。
数式
$$
\phi(x)=x
$$
実装と描画
わざわざやる必要もないかもしれませんが、一応。
import numpy as np
import matplotlib.pyplot as plt
def iden(x): #恒等は英語でidentity
return x
x=np.arange(-5.0, 5.0, 0.01) #xは-5から5を0.01刻み
y=iden(x)
plt.plot(x,y)
plt.ylim(-5.0,5.0)
plt.show()
ReLu関数: プラスならそのままだけど、0より小さくはさせない
ReLu関数は、勾配消失問題などを解決しているため、最もよく使われている活性化関数です。
数式
\phi(x)=\left\{
\begin{array}{}
x & (x\geq 0)\\
0 & (x<0)
\end{array}
\right.
実装と描画
np.maximumを用いる
def relu(x):
return np.maximum(0,x) #入力された値から大きい方を選んで出力する。
x=np.arange(-5.0,5.0,0.1)
y=relu(x)
plt.plot(x,y)
plt.ylim(-0.1,6.0)
plt.show()
数式のとおりになっています。
(単位)ステップ関数: 0か1か
0か1かに仕分けする関数です。
2クラスに分類するときに使えそうですが、問題があって実際には2クラス分類では後述するシグモイド関数が用いられます。
数式
\phi(x)=\left\{
\begin{array}{}
1 & (x\geq 0)\\
0 & (x<0)
\end{array}
\right.
実装と描画
def step_function(x):
return np.array(x>=0,dtype=np.int64) #x>=0ならばTrue,x<0ならばFalseが出力されるが、それをintにすると、それぞれ1,0に変換される。
x=np.arange(-5.0, 5.0, 0.1)
y=step_function(x)
plt.plot(x,y)
plt.ylim(-0.1,1.1)
plt.show()
形を見るととてもカクカクしています。
これは、$x=0$ で関数が連続でないからです。つまり$x=0$で微分不可能な関数になっています。
しかし、ニューラルネットでは微分を用いて最適なパラメータを探索するため、微分不可能な関数を活性化関数として使用するのは適切ではありません。そこで、次に、値域は同じで滑らかな関数であるシグモイド関数について紹介します。
シグモイド関数:滑らかverのステップ関数
これは2値分類の出力層に使用される関数です。また、ロジスティック回帰の主役でもあります。
数式
$$
\phi(x)=\frac{1}{1+\exp(-x)}
$$
実装と描画
def sigmoid(x):
return 1/(1+np.exp(-x))
x=np.arange(-5.0,5.0,0.1)
y=sigmoid(x)
plt.plot(x,y)
plt.ylim(-0.1,1.1)
plt.show()
微分可能であるということで、ステップ関数の悪いところを改善しています。
この活性化関数に通した後、閾値を決めて出力させれば、最終的に0か1かの分類をすることが可能です。
tanh(双曲線正接関数):シグモイドの-1~1ver
形的にはシグモイド関数の値域が-1から1になったようなものです。
数式
$$
\phi(x)=\frac{\mathrm{e}^{2x}-1}{\mathrm{e}^{2x}+1}
$$
実装と描画
def tanh(x):
y=np.tanh(x)
return y
x=np.arange(-5.0,5.0,0.1)
y=tanh(x)
plt.plot(x,y)
plt.ylim(-5.0,5.0)
plt.show()
npにtanhがあるので、わざわざ関数にする必要なかったと思いますが、大目に見てください。
ソフトマックス関数:多クラスに分類したいとき
多クラス分類の出力層に使います。
以前、何故ソフトマックス関数が多クラス分類の出力層に使われるかをまとめたので、よかったらこちらもご覧ください。
数式
$$
\phi(x)=\frac{\exp(x_i)}{ \displaystyle\sum_{i=1}^{n}\exp(x_i)}
$$
他の関数と違うところは、自分以外のノードの入力も関わってくるところです。
実装
def softmax(x):
exp_x=np.exp(x)
sum_exp_x=np.sum(exp_x,axis=0)
y=exp_x/sum_exp_x
return y
描画はしませんが、各出力が、各クラスに属す確率としてみなすことができます。
終わりに
代表的な活性化関数の理論と実装を説明してきました。
どのような変換が行われているかを理解すれば、ニューラルネットの出力の気持ちを少しでも理解できるのはないかと思いまとめてみました。
読んでいただきありがとうございました!
参考
オイラリージャパン:『ゼロから作るDeep Learning Pythonで学ぶディープラーニングの理論と実装』著:斎藤康毅