LoginSignup
0
2

More than 5 years have passed since last update.

活性化関数についての簡単な説明といくつかの種類

Posted at

まえがき

一応、前回のパーセプトロンの記事を読んでいる前提で説明します。

前回の単純パーセプトロンでは以下のように出力yを計算しました。

 y = \begin{cases}
0 & (b + w_1w_1 + w_2 x_2 \leq 0)\\
1 & (b + w_1w_1 + w_2 x_2 > 0)
\end{cases}

これを以下の3式に書き換えてみましょう。

$$ y = h(a) $$

$$ a = b + w_1x_1 + w_2x_2 $$

 h(a) = \begin{cases}
0 & (a \leq 0)\\
1 & (a > 0)
\end{cases}

3つに分解されただけで、やっていることは現状同じです。

さて、これを図で表してみましょう。
ニューラル.png
汚い図ですね。

とにかくこういう処理で単層の計算を行っているわけです。
ここで肝心なのはaをyに変換するh(a)です。今は

 h(a) = \begin{cases}
0 & (a \leq 0)\\
1 & (a > 0)
\end{cases}

を関数としていますが、これを別の関数に置き換えれば別の出力が得られるはずですね。この種類をいくつか見てみましょう。

どれも$y = ax$みたいな簡単な式(線形関数)ではありません。そもそも線形関数ならわざわざ重ねなくても一回で計算できるし。

ステップ関数

 h(a) = \begin{cases}
0 & (a \leq 0)\\
1 & (a > 0)
\end{cases}

これ。

実装してみよう

単純に条件を入力してみるとこうですね。

def step_function(x):
if x > 0:
  return 1
else:
  return 0

$h(a)$自体はできているんですが、これではnumpy配列を扱えません。
以下のように書いてみます。

import numpy as np
def step_function(x):
    return np.array(x > 0, dtype = int)

これは、$x>0$を満たしていたらTrue,満たしていなかったらFalseの配列を返す…のをさらに、int型に変換することで$x > 0$なら1、満たしていないなら0、という配列に変換しています。
グラフで表してみます。

import numpy as np
import matplotlib.pylab as plt

def step_function(x):
    return np.array(x > 0, dtype = int)

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()

Figure_1.png
できました。

シグモイド関数

以下の式で表します。

$$ h(x) = {1\over {1 + \mathrm{exp}(-x)}} $$

特徴として、$\infty > x > -\infty$の範囲で$1 > y > 0$の範囲をとること。$x = 0$で$y = 0.5$。

実装してみよう

import numpy as np
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

これでシグモイド関数をあらわすことができます。
グラフにしてみましょう。

import numpy as np
import matplotlib.pylab as plt

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

x = np.arange(-10.0, 10.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()

Figure_1.png

こんな感じです。すごくおおざっぱに言えば、なめらかなステップ関数といったような形をしています。

LeRu関数

以下の式で表します。

h(x) = \begin{cases}
x & (x > 0)\\
0 & (x \leq 0)
\end{cases}

ステップ関数で1だった所がxになってます。

実装してみよう

import numpy as np
def relu(x):
    return np.maximum(0, x) # 0かxか大きい方を返す

ではグラフにしてみます。

import numpy as np
import matplotlib.pylab as plt

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.show()

Figure_1.png

こうなりました。

ソフトマックス関数

主に出力層に用いります。
これは複数のaを利用してyを求める関数です。

$$ h(a_ k) ={ \mathrm{exp}(a_k)\over \sum^n _ {i = 1}\mathrm{exp}(a_i)}$$

証明は省略しますが、このように変形できます。
$$ y_ k ={ \mathrm{exp}(a_k + C)\over \sum^n _ {i = 1}\mathrm{exp}(a_i + C) }$$
これは数値範囲をオーバーしないためにする変形です。aに10000とか入っててもオーバーフローしないためにこの変形をする必要がある。

実装してみよう

import numpy as np
def softmax(a):
  c = np.max(a)
  exp_a = np.exp(a - c) # これで必ずa-c <= 0。オーバーフローしなくなる。
  sum_exp_a = np.sum(exp_a)
  y = exp_a / sum_exp_a

  return y

出力してみましょう。

a = np.array([0.3, 2.9, 4.0])
y = softmax(a)
print(y) # [0.01821127 0.24519181 0.73659691]

はいここで出力yに注目してください。
[0.01821127 0.24519181 0.73659691]の三つ。合計すると1になります。

つまりこれは与えられた三つの数字の大きさを比較し、「確率」に変換する関数といえます。

恒等関数

h(a) = a

つまりそのまま。これも出力に用います。ソフトマックス関数使わずにこれでもそんなに問題ない。

実装してみよう

いる?

まとめ

多数のxの入力をまとめてaを作り、それを活性化関数$h(a)$で変換する。これを繰り返して目的の出力を得るのがニューラルネットワークです。$h(a)$にはいろいろ種類があります。ここで触れた以外にもたくさんあります。
最後の二つのソフトマックス関数、恒等関数はどちらかというと出力用の関数。ちょっとジャンルが違います。

『ゼロから作るDeepLearning - Pythonで学ぶディープラーニングの理論と実装』を参考にしました。
前回:パーセプトロン

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2