E資格に出題される活性化関数について、それぞれの関数の特徴についてまとめてみました。
ステップ関数
ステップ関数は、入力値が0以上の場合は1、入力値が0未満の場合は0を出力する関数です。
この関数は、ニューラルネットワークが登場する前のパーセプトロンで採用されていた活性化関数ですが、現在の誤差逆伝播を行うネットワークにおいては後述のReLU関数に取って代わられています。
def step(x):
return 1.0 * (x >= 0.0)
シグモイド関数
シグモイド関数は、入力値に対して0.0~1.0の値を出力する関数です。
ニューラルネットワークの活性化関数として用いられる場合は、厳密には「標準シグモイド関数」であり、本来のシグモイド関数はオイラー数eの指数に係数であるαが着きます。ニューラルネットワークの活性化関数として登場する場合、この係数αは1として定義され、記載が省略されます。
関数の微分値の最大値は0.25です。
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
勾配消失問題
シグモイド関数を採用したネットワークでは、般化性能を得るために隠れ層を深くしていくと、勾配が消えてしまう勾配消失問題が発生してしまいます。これは、シグモイド関数の微分値が最大でも0.25しかないことに起因しています。シグモイド関数を複数回通ることで勾配の値がどんどん0に近づいてしまい、学習速度の低下に繋がります。
tanh関数
tanh関数は、入力値に対して-1.0~1.0の値を出力する関数です。シグモイド関数を縦に引き伸ばしたような線分です。
関数の微分値の最大値が1.0なので、シグモイド関数と比較して勾配消失が起こりにくいですが、入力値が大きくなる(返却値が1に近づく)と勾配は緩やかになるため、勾配消失問題を解決するものではありません。
def tanh(x):
return np.tanh(x)
ReLU関数
ReLU関数は、入力値が0以上の場合には入力値と同じ値を、入力値が0未満の場合は0を出力する関数です。
順伝播型ニューラルネットワークの隠れ層において、最もポピュラーな関数です。
ReLU関数は、入力値が0以上の場合は微分値が常に1になるため、前述のシグモイド関数やtanh関数の持ってる勾配消失問題が解決されます。
def relu(x):
# 0がxのうち、大きいものを返す
return np.maximum(0, x)
Absolute value rectification
ReLU関数は、入力値の正負のいずれの場合でも、常に入力値の絶対値を返すような関数です。
関数の微分値は入力が正の場合は1.0、負の場合は-1.0となります。
def abs_relu(x):
return np.abs(x)
leaky ReLU
leaky ReLUは、名前の通りReLUに類似する関数で、入力値が0以上の場合ReLU関数と同様に入力値と同じ値を出力し、入力値が0未満の場合は入力値に応じた負数を出力する関数です。
なお、入力値が0未満の場合に出力される値は、係数αに応じた大きさに調整されます。学習の過程で係数αが変更するものは、Parametric ReLUと呼ばれています。
def leaky_relu(x, alpha):
# 0以上であればxを返し、
# 0未満であればxに係数αを掛けたものを返す
return np.where(x => 0, x , alpha * x)