シグモイド関数

シグモイド関数

シグモイド関数

シグモイド関数の定義

 シグモイド関数 (Sigmoid function)
 
\[f(x)=\frac{1}{1+e^{-ax}}\quad (a\gt 0)\]
によって定義され、ニューラルネットワークにおいてニューロンの特性を表す関数として登場します。Matplotlib と NumPy を使って $a$ を変化させながらグラフを描いてみます。

# リストSGD_01
# シグモイド関数のグラフを描画

# NumPyとMatplotlibをインポート
import numpy as np
import matplotlib.pyplot as plt

# シグモイド関数を定義
def sigmoid(x, a):
    return 1 / (1 + np.exp(-a * x))

# フィギュアを設定
fig = plt.figure()

# グラフ描画領域を追加
ax = fig.add_subplot(111)

# グリッド線を表示
ax.grid(linestyle = "--")

# グラフタイトルを設定
ax.set_title("Sigmoid Function", fontsize = 16)

# x軸, y軸のラベルを設定
ax.set_xlabel("x", fontsize = 16)
ax.set_ylabel("y", fontsize = 16)

# -10~10,256分割の点
x = np.linspace(-10, 10, 256)

# シグモイド関数をプロット
a = [0.5, 1, 4]
for k in range(3):
    y = sigmoid(x, a[k])
    ax.plot(x, y, label = "a = {}".format(a[k]))

# 凡例を表示
ax.legend()

plt.show()

 Python シグモイド関数グラフ
 

シグモイド関数の微分方程式

 シグモイド という名称は、曲線の形がギリシャ文字の $\varsigma$ (シグマ) に似ていることに由来します。$a$ はゲイン (gain) とよばれるパラメータです。図にあるように、$a$ が大きくなるほど原点付近の傾斜は大きくなって階段関数に近づいていきます。特にゲイン $a$ が $1$ のときは標準シグモイド関数とよばれます。シグモイド関数は微分方程式
 
\[\frac{dy}{dx}=ay(1-y)\]
を $y(0)=1/2$ の初期条件で解いて得られます。シグモイド関数を微分してみれば、この方程式を満たしていることはすぐにわかりますが、ここでは微分方程式を解いて一般解も確認しておきましょう。上式を変数分離すると
 
\[\frac{dy}{y(1-y)}=adx\]
となります。左辺を分解すると
 
\[\left(\frac{1}{y}+\frac{1}{1-y}\right)dy=adx\]
 両辺を積分すると
 
\[\begin{align*}
\log|y|-\log|1-y|&=ax+C\\[6pt]
\log\left|\frac{y}{1-y}\right|&=ax+C\\[6pt]
\frac{y}{1-y}&=\pm e^{ax+C}\\[6pt]\end{align*}\]
 $A=\pm e^C$ とおいて式を整理すると、
 
\[y=\frac{A}{A+e^{-ax}}\]
が得られます。初期条件 $y(0)=1/2$ を代入すると $A=1$ が決まるので、
 
\[y=\frac{1}{1+e^{-ax}}\]
となってシグモイド関数が現れます。手作業で微分方程式を解くのが面倒であれば、以下のように SymPyパッケージをインポートして解く方法もあります(微分方程式の解き方についてはこちらの記事を参照してください)。

# リストSGD_02
# Jupyter Notebook用コード

# SymPyをインポート
import sympy

# MathJaxで表示
sympy.init_printing()

# 記号x,y,C1を定義
sympy.var('a x y C1')

# 微分方程式 dy/dx = ay(1 - y)
eq = sympy.Eq(y(x).diff(x), a*y(x)*(1 - y(x)))

# 微分方程式の一般解
ys = sympy.dsolve(eq)

display(ys)
\[y{\left (x \right )} = - \frac{1}{C_{1} e^{-ax} - 1}\]

 

scipy.special.expit()

 SciPyパッケージの scipy.special.expit(x) は $a=1$ のシグモイド関数を計算します。

# リストSGD_03

import numpy as np
from scipy.special import expit

# 配列xを定義
x = np.array([-0.5, 0, 0.5])

# シグモイド関数を計算
s = expit(x)

print(s)
[0.37754067 0.5        0.62245933]

 $a$ の値を指定してシグモイド関数の値を計算したい場合は、以下のような関数を定義します。

# シグモイド関数
def sp_sigmoid(a, x):
    return expit(a*x)

# a=2を指定してシグモイド関数を計算
s = sp_sigmoid(2, x)

print(s)
[0.26894142 0.5        0.73105858]