【コード付き】6種類の活性化関数の特徴を徹底解説【ニューラルネットワーク入門】

 
・活性化関数とは何か知りたい
・活性化関数の代表例を知りたい
・これから機械学習を勉強したい

こんにちは、るい(@CenotenBlog)です。

この記事では、上記の悩みにお答えします。内容は以下の通りです。

✔︎本記事の内容

・活性化関数とは

・ステップ関数

・シグモイド関数

・Tanh関数

・ReLU関数

・恒等関数

・Softmax関数

ちなみに、この記事を書いている僕は、国立研究機関にて、人工知能に関する研究を行っています。

本記事は『ゼロから作るDeep Learning』を参考にしています。

本題に入る前に一点。
活性化関数について理解するには、パーセプトロンと呼ばれるアルゴリズムを知っておく必要があります。

パーセプロトンが何かわからない人向けに、下記の記事で解説しています。
参考までにどうぞ。

関連記事

[mathjax]   ・パーセプトロンとは何か知りたい・パーセプトロンをわかりやすく理解したい・これからニューラルネットワークを勉強したい こんにちは、るい(@CenotenBlog)です。 この記事では、上記の悩[…]

活性化関数とは何か

では早速、活性化関数とは何かから。

活性化関数を一言でまとめると、ニューロンがどのように発火するのかを決定するもの」と言えます。

ニューロンの発火とは、ニューロンの入力信号がある閾値(\(\theta\))を超えた時のことを指していました。

つまり、閾値(\(\theta\))を決定したり、入力情報の処理方法を決定する役割を担っているのが、活性化関数ということです。

ニューロンの発火についてよくわからない方は、下記の記事を参考にしてみてください。

関連記事

[mathjax]   ・パーセプトロンとは何か知りたい・パーセプトロンをわかりやすく理解したい・これからニューラルネットワークを勉強したい こんにちは、るい(@CenotenBlog)です。 この記事では、上記の悩[…]

活性化関数は、下図の様に、\(h()\)で表すのが一般的です。

\(h()\)は、入力値の総和\(a\)を引数として受け取り、出力値\(y\)を返します。

のちに出てきますが、出力層で使用される活性化関数は、あえて\(\sigma()\)で表すのが慣例です。

代表的な活性化関数には、次の5つがあります。
それぞれ順番に解説していきます。

✔︎活性化関数の代表例

・ステップ関数

・シグモイド関数

・Tanh関数

・ReLU関数

・恒等関数

・Softmax関数

ステップ関数

ステップ関数は、入力値がある閾値を超えた場合は1を出力し、それ以外は0を出力する関数です。

一般的な数式は下記の通り。
\(a\)は入力の総和を表します。

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

$$a=w_{1}x_{1}+w_{2}x_{2}+b$$

実装は、条件式を用いるだけで良さそうですね。

次に、ステップ関数のモデル図を作ってみます。

ステップ関数のモデル図

モデルは、理解しやすいように、入力値は1つで、バイアスと重みを0とします。
条件をまとめると下記の通り。

$$-5.0 \leq x \leq 5.0\\w_{1}=1\\b=0\\\theta=0$$

ステップ関数の可視化

直感的に理解できるように、ステップ関数を可視化してみます。
下に関数をプロットしたグラフと実装用のコードを示します。
条件はこんな感じ。

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

import numpy as np
import matplotlib.pylab as plt

def step_function (x):   #ステップ関数
   return np.array(x>0, dtype=np.int)   # x > 0 の時、1 を返す

x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)
plt.ylim(-0.1,1.1)
plt.ylabel('h(a)', fontsize=18)
plt.xlabel('x', fontsize=18)
plt.tick_params(labelsize=18)
plt.tight_layout()
plt.plot(x,y)
plt.show()

グラフが階段みたいになることから、「階段関数」とも言うみたいです

以上がステップ関数でした。

シグモイド関数

次に、シグモイド関数についてです。

ステップ関数は、0か1の2値の出力が返ってくるのに対し、シグモイド関数は、入力値の大きさに比例して0~1の間の値が出力されます

一般的な数式は下記の通り。
\(a\)は入力の総和を表します。

$$y=h(a)=\frac{1}{1+e^{-a}}$$

$$a=w_{1}x_{1}+w_{2}x_{2}+b$$

つまり、シグモイド関数は、入力値に比例して出力値が変化するということ。

直感的に理解できるように、シグモイド関数も可視化します。
(モデル図は\(h()\)の中身が変化しただけで、ステップ関数と同じです。)

シグモイド関数の可視化

ステップ関数と同様に、入力値は1つ、バイアスと重みは0とします。
条件をまとめると下記の通り。

$$-5.0 \leq x \leq 5.0\\w_{1}=1\\b=0\\\theta=0$$

import numpy as np
import matplotlib.pylab as plt

def sigmoid_function (x):   #シグモイド関数
    return 1 / (1 + np.exp(-x))

x = np.arange(-5, 5, 0.1)
y = sigmoid_function(x)
plt.ylabel('h(a)', fontsize=18)
plt.xlabel('x', fontsize=18)
plt.ylim(-0.1,1.1)
plt.tick_params(labelsize=18)
plt.tight_layout()
plt.plot(x,y)
plt.show()

グラフを見てわかるように、シグモイド関数は、連続的な実数値を返します。

出力値が0から1の間になる点は、ステップ関数との共通点ですね。

Tanh関数

シグモイド関数に似た関数に、Tanh関数があります。

シグモイド関数は、入力値の大きさに比例して0~1の間の値が出力されるのに対し、Tanh関数は、1~1の間の値を返します。

一般的な数式は下記の通り。
\(a\)は入力の総和を表します。

$$y=h(a)=\frac{e^{a}-e^{-a}}{e^{a}+e^{-a}}$$

$$a=w_{1}x_{1}+w_{2}x_{2}+b$$

シグモイド関数に比べ、出力値の幅があるため、入力値の大小関係を表現しやすいですね。

では、 Tanh関数の可視化をしてみます。
(モデル図は\(h()\)の中身が変化しただけで、ステップ関数と同じです。)

Tanh関数の可視化

条件は下記の通り。

$$-5.0 \leq x \leq 5.0\\w_{1}=1\\b=0\\\theta=0$$

import numpy as np
import matplotlib.pylab as plt

def tanh(x):    #Tanh関数
  return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))

x = np.arange(-5.0, 5.0, 0.1)
y = tanh(x)
plt.ylabel('h(a)', fontsize=18)
plt.xlabel('x', fontsize=18)
plt.ylim(-1.1, 1.1)
plt.tick_params(labelsize=18)
plt.tight_layout()
plt.plot(x,y)
plt.show()

出力値の幅が変化しただけで、グラフの見た目はシグモイド関数と一緒ですね。

これまで出てきた、ステップ関数、シグモイド関数、Tanh関数は非線形関数に分類されます。

次に線形な関数に分類される、活性化関数を見てみましょう。

ReLU関数

線形の活性化関数の代表例は、ReLU関数です。

ReLU関数は入力の値が0以下の時は0を返し、それ以外は入力の値をそのまま出力します。

一般的な数式は下記の通り。
\(a\)は入力の総和を表します。

$$y=h(a)=\begin{cases}
a & (a>0)\\
0 & (a\leq0)
\end{cases}
$$

$$a=w_{1}x_{1}+w_{2}x_{2}+b$$

では、 ReLU関数の可視化をしてみます。
(モデル図は\(h()\)の中身が変化しただけで、ステップ関数と同じです。)

import numpy as np
import matplotlib.pylab as plt

def relu(x):   #ReLU関数
    return np.maximum(0, x)

x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)
plt.ylabel('h(a)', fontsize=18)
plt.xlabel('x', fontsize=18)
plt.ylim(-1.0, 5.5)
plt.tick_params(labelsize=18)
plt.tight_layout()
plt.plot(x,y)
plt.show()

関数自体は非常にシンプルで、実装もとても簡単です。

ちなみに、最近のニューラルネットワークでは、主にReLU関数が用いられます。

次にニューラルネットワークの出力層に用いられる、活性化関数について解説します。

恒等関数

恒等関数は入力値をそのまま出力する関数です。
数式で表すと下記の通り。

$$y=a$$

$$a=w_{1}x_{1}+w_{2}x_{2}+b$$

恒等関数のモデル図も作ってみます。

恒等関数のモデル図

モデルは、理解しやすいように、3つの入力値を出力値として返すものとします。

ちなみに、出力層の活性化関数は\(\sigma()\)で表します。

入力値をそのまま出力だけなので、モデル図は下記の通り。

直感的に理解できるように、恒等関数も可視化します。

恒等関数の可視化

import numpy as np
import matplotlib.pylab as plt

def identity(x):   #恒等関数
  return x

x = np.arange(-5.0, 5.0, 0.1)
y = identity(x)
plt.ylabel('h(a)', fontsize=18)
plt.xlabel('x', fontsize=18)
plt.tick_params(labelsize=18)
plt.tight_layout()
plt.plot(x,y)
plt.show()

Softmax関数

分類問題でよく用いられる活性化関数にSoftmax関数があります。
数式は下記の通り。

$$y_{k}=\frac{e^{a_{k}}}{\sum^{n}_{i=1}e^{a_{i}}}$$

上式の指数関数(\(y=e^{a}\))は単調増加する関数なので、入力値の大小関係を保ったまま、出力値を返します。また、出力値は0から1.0の間の実数になります。

Softmax関数のモデル図も作ってみます。

Softmax関数のモデル図

def softmax(a):   #Softmax関数
   exp_a = np.exp(a)
   sum_exp_a = np.sum(exp_a)
   y = exp_a / sum_exp_a

   return y

Softmax関数の重要な性質として、出力の総和が1になる点があります。

この性質のおかげで、Softmax関数の出力を「確率」として解釈することができるのです。

たとえば、出力値が\(y[0]=0.18 , y[1]=0.32, y[2]=0.50\)となった場合、分類問題の答えは確率の最も高い\(y[2](50\%)\)と見なすことができます。

また確率的に、18%の確率で\(y[0]\)、32%の確率で\(y[1]\)、50%の確率で\(y[2]\)となると考えることもできますね。

今回はここまでにしようと思います。
何かわからないことがあれば、いつでもご連絡ください。

参考文献⇩

最新情報をチェックしよう!