UNISIA-SE Tech Blog

気まぐれお勉強日記

[Python] [4] 活性化関数の実装サンプルまとめ (ステップ / シグモイド / ReLU / 恒等関数 /ソフトマックス関数)

1. 前提条件


このページでは、活性化関数である ステップ / シグモイド / ReLU / 恒等関数 / ソフトマックス関数の実装サンプルについて記載する。

以下、必要な前提知識。

▼ 下記ページを理解していること。
[Python] [3] ニューラルネットワークの活性化関数と実装サンプル

▼ Python3.6、NumPyがインストールされていること。
このページでは、venvの仮想環境(Python3.6)上にNumPyをインストールした環境で、Python対話モード(Pythonインタプリタ)にて実装サンプルを記載している。

※ Python対話モード、NumPy、Matplotlibについては下記を参考。
Python対話モード:[Python] 対話モード (インタプリタ) の使用方法
NumPy:[Python] [NumPy] インストールとnumpy.ndarrayの使用方法
Matplotlib:[Python] [Matplotlib] インストールとmatplotlib.pyplot の使用方法

2. ステップ関数


前ページでも触れた ステップ関数 で、線形の 活性化関数階段関数とも呼ばれる。

▼ 定義
\(x\) が \(0\) より大きければ、\(1\) を出力し、\(0\) 以下であれば \(0\) を出力する。
\[ {\normalsize h(x) = \begin{cases} 0 \hspace{5pt}\text{if}\hspace{5pt}x \leqq 0 \\ 1 \hspace{5pt}\text{if}\hspace{5pt}x > 0 \end{cases} } \]
▼ 実装

$ python
 >>> import numpy as np
 >>> import matplotlib.pylab as plt
 >>> def step_func(x):    # ステップ関数の定義
 ...    return np.array(x > 0, dtype=np.int)
 ...

▼ グラフ出力 「b_id41_1.png」

  >>> x = np.arange(-5.0, 5.0, 0.1)    # 区間を-5~5 まで、描画制度を 0.1 刻みに設定
  >>> y = step_func(x)    # ステップ関数をコール
  >>> plt.title("step_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y")    # グラフタイトルを設定
  Text(0.5, 1.0, 'step_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y')
  >>> plt.ylim(-0.1, 1.1)    # y軸の範囲を設定
  (-0.1, 1.1)
  >>> plt.xlabel("x")    # x軸のラベルを設定
  Text(0.5, 0, 'x')
  >>> plt.ylabel("y")    # y軸のラベルを設定
  Text(0, 0.5, 'y')
  >>> plt.plot(x, y)    # グラフの描画
  [<matplotlib.lines.Line2D object at 0x7fc13041e278>]
  >>> plt.savefig('/var/www/vops/ops/macuos/static/macuos/img/b_id41_1.png'))    # グラフの出力

3. シグモイド関数


前ページでも触れた シグモイド関数 で、非線形の 活性化関数 に分類される。

▼ 定義
出力値は、 \(x\) が小さいほど \(0\) になく近づき、\(x\) が大きいほど \(1\) に限りなく近づく。
\[ h(x) = \frac{1}{1+e^{-x}} \]
▼ 実装

$ python
 >>> import numpy as np
 >>> import matplotlib.pylab as plt
 >>> def sigmoid_func(x):    # シグモイド関数の定義
 ...     return 1 / (1 + np.exp(-x))    # 自然対数の低 (e) の -x 乗
 ...

▼ グラフ出力 「b_id41_2.png」

 >>> x = np.arange(-5.0, 5.0, 0.1)    # 区間を-5~5 まで、描画制度を 0.1 刻みに設定
 >>> y = sigmoid_func(x)    # シグモイド関数をコール
 >>> plt.title("sigmoid_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y")    # グラフタイトルを設定
 Text(0.5, 1.0, 'sigmoid_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y')
 >>> plt.ylim(-0.1, 1.1)    # y軸の範囲を設定
 (-0.1, 1.1)
 >>> plt.xlabel("x")    # x軸のラベルを設定
 Text(0.5, 0, 'x')
 >>> plt.ylabel("y")    # y軸のラベルを設定
 Text(0, 0.5, 'y')
 >>> plt.plot(x, y)
 [<matplotlib.lines.Line2D object at 0x7f727fbc1be0>]
 >>> plt.savefig('/var/www/vops/ops/macuos/static/macuos/img/b_id41_2.png')    # グラフの出力

4. ReLU関数


ReLU(Rectified Linear Unit:ランプ関数、正規化線形関数) と呼ばれ、非線形の 活性化関数 に分類される。

※ 最近では、ニューラルネットワークにおいて、シグモイド関数 より、ReLU関数 が多く用いられるようになった。

▼ 定義
\(x\) が \(0\) より大きい場合、\(x\) を出力し、\(0\) 以下である場合、\(0\) を出力する。
\[ {\normalsize h(x) = \begin{cases} x \hspace{5pt}\text{if}\hspace{5pt}x > 0 \\ 0 \hspace{5pt}\text{if}\hspace{5pt}x \leqq 0 \end{cases} } \]
▼ 実装

$ python
>>> import numpy as np
>>> import matplotlib.pylab as plt
>>> def relu_func(x):    # ReLU関数の定義
...     return np.maximum(0, x)
...

▼ グラフ出力 「b_id41_3.png」

 >>> x = np.arange(-5.0, 5.0, 0.1)    # 区間を-5~5 まで、描画制度を 0.1 刻みに設定
 >>> y = relu_func(x)    # ReLU関数をコール
 >>> plt.title("relu_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y")    # グラフタイトルを設定
 Text(0.5, 1.0, 'relu_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y')
 >>> plt.xlabel("x")    # x軸のラベルを設定
 Text(0.5, 0, 'x')
 >>> plt.ylabel("y")    # y軸のラベルを設定
 Text(0, 0.5, 'y')
 >>> plt.plot(x, y)
 [<matplotlib.lines.Line2D object at 0x7fbf1cfeecc0>]
 >>> plt.savefig('/var/www/vops/ops/macuos/static/macuos/img/b_id41_3.png')
 >>>

5. 恒等関数


出力層 で使われる線形の 活性化関数 に分類される。

▼ 定義
\(x\) をそのまま出力する。
\[ {\normalsize h(x) = x } \]
▼ 実装

$ python
 >>> import numpy as np
 >>> import matplotlib.pylab as plt
 >>> def koutou_func(x):    # 恒等関数の定義
 ...     return x
 ...

▼ グラフ出力 「b_id41_4.png」

 >>> x = np.arange(-5.0, 5.0, 0.1)    # 区間を-5~5 まで、描画制度を 0.1 刻みに設定
 >>> y = koutou_func(x)    # 恒等関数をコール
 >>> plt.title("koutou_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y")    # グラフタイトルを設定
 Text(0.5, 1.0, 'koutou_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y')
 >>> plt.xlabel("x")    # x軸のラベルを設定
 Text(0.5, 0, 'x')
 >>> plt.ylabel("y")    # y軸のラベルを設定
 Text(0, 0.5, 'y')
 >>> plt.plot(x, y)
 [<matplotlib.lines.Line2D object at 0x7fba4d928f60>]
 >>> plt.savefig('/var/www/vops/ops/macuos/static/macuos/img/b_id41_4.png')
 >>>

6. ソフトマックス関数


分類問題 で使われる非線形の 活性化関数 に分類される。

▼ 定義
\(n \leqq k\) の時、\(k\) 番目の出力 \(h(x_{k})\) を表す。
\[ {\normalsize h(x_{k}) = \frac{e^{x_{k}}}{\sum_{i=1}^{n} e^{x_{i}}} } \]
▼ 実装

$ python
 >>> def softmax_func(x):    # ソフトマックス関数の定義
 ...     exp_x = np.exp(x)
 ...     sum_exp_x = np.sum(exp_x)
 ...     y = exp_x / sum_exp_x
 ...     return y
 ...    

▼ グラフ出力 「b_id41_5.png」

 >>> x = np.arange(-5.0, 5.0, 0.1)    # 区間を-5~5 まで、描画制度を 0.1 刻みに設定
 >>> y = koutou_func(x)    # ソフトマックス関数をコール
 >>> plt.title("softmax_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y")    # グラフタイトルを設定
 Text(0.5, 1.0, 'softmax_func\n# arange:-5.0, 5.0, 0.1, xlabel:x, ylabel:y')
 >>> plt.xlabel("x")    # x軸のラベルを設定
 Text(0.5, 0, 'x')
 >>> plt.ylabel("y")    # y軸のラベルを設定
 Text(0, 0.5, 'y')
 >>> plt.plot(x, y)
 [<matplotlib.lines.Line2D object at 0x7ff04a9c4d68>]
 >>> plt.savefig('/var/www/vops/ops/macuos/static/macuos/img/b_id41_5.png')
 >>>


以上。


【参考文献】
斎藤 康毅 (2018) 『ゼロから作るDeep Learning - Pythonで学ぶディープラーニングの理論と実装』株式会社オライリー・ジャパン


Copyright UNISIA-SE All Rights Reserved.
s-hama@unisia-se.jp