ReNom 内にある活性化関数

このチュートリアルではReNom内に搭載されている活性化関数を紹介します。

以前のチュートリアルにも掲載されたように、ニューラルネットワークとは複数のニューロンで構成されている関数であり、各ニューロン内に活性化関数が存在します。非線形な活性化関数を用いることにより、非線形なシステムを学習することが可能です。

このチュートリアルではReNom内にある活性化関数を紹介します。また、各活性化関数の理解を深めるためにグラフを提示します。入力範囲は−3から3とします。functionalモデル、またはsequential モデルに応じて使用できる活性化関数が異なります。本チュートリアルではfunctional モデル用活性化関数を使用します。

必要なライブラリー

In [1]:
import renom as rm
import numpy as np
import matplotlib.pyplot as plt

入力データの生成

In [6]:
data=[x/100 for x in range(-300,300)]
input1=np.array(data)

#for confirmation
print(input1[0:5])
[-3.   -2.99 -2.98 -2.97 -2.96]

グラフ生成関数の定義

グラフ生成を数回実施するため、ここでは関数を定義します。

In [12]:
def plt_act(x,ymin=-3,ymax=3):
    plt.grid()
    plt.plot(input1,x)
    plt.xlim(-3,3)
    plt.ylim(ymin,ymax)
    plt.xlabel('input')
    plt.ylabel('output')
    plt.show()

Sigmoid関数

0から1の値を出力する関数です。連続な勾配を持つ関数です。中心点は0.5にあるため、バックプロパゲーション時に0付近で大きく変化します。左のグラフはy軸範囲が-3から3の間を表し、右のグラフは0から1の間を表す。

f(x) = \frac{1}{1 + \exp(-x)}
In [14]:
output1=rm.sigmoid(input1) # Sequential ->rm.Sigmoid()
plt_act(output1,0,1) ## for easy view
../../../_images/notebooks_basic_algorithm_activation_types_notebook_9_0.png

Tanh関数

−1から1の値を出力する関数です。連続な勾配を持つ関数です。中心点は0にあるため、バックプロパゲーション時に0付近での大きな変化は抑制できます。

f(x) = \tanh(x)
In [17]:
output2=rm.tanh(input1) # Sequential ->rm.Tanh()
plt_act(output2)
../../../_images/notebooks_basic_algorithm_activation_types_notebook_11_0.png

Relu関数

入力が正の時に入力と同じ値を、入力が負の時に0を出力する関数です。勾配は不連続だが、一定の値を持つ関数です。入力が負の時に勾配は0です。

f(x)=\max(x, 0)
In [20]:
output3=rm.relu(input1) # Sequential ->rm.Relu()
plt_act(output3)
../../../_images/notebooks_basic_algorithm_activation_types_notebook_13_0.png

Leaky Relu関数

入力が正の時に入力と同じ値を、入力が負の時に定数倍して出力する関数です。通常は入力が負の時に、低い値を出力します。勾配は不連続だが、正負ともに一定の値を持つ関数です。負の勾配(slope)のデフォルト値は0.01です。

\begin{split}f(x)=\begin{cases} x&(x>0)\\ 0&(x\leq0) \end{cases}\\ \Leftrightarrow f(x)=\max(x, 0)+\min(slope*x, 0)\end{split}
In [22]:
output4=rm.leaky_relu(input1) # Sequential ->rm.Leaky_Relu()
plt_act(output4)
../../../_images/notebooks_basic_algorithm_activation_types_notebook_15_0.png

入力が負のときの定数倍は変更可能です。下記は負の勾配が0.5の時です。

In [29]:
output5=rm.leaky_relu(input1,0.5)
plt_act(output5)
../../../_images/notebooks_basic_algorithm_activation_types_notebook_17_0.png

[1] Andrew L. Maas, Awni Y. Hannun, Andrew Y. Ng (2014). Rectifier Nonlinearities Improve Neural Network Acoustic Models

Elu関数

入力が正の時に入力と同じ値を、入力が負の時に-1以上の負の値を出力する関数です。負の方向は指数関数を含んだ関数が適用し、-1に収束します。勾配は不連続だが、正の入力時は一定であり、また負の入力時は出力値を用いることができます。負の定数のデフォルト値は0.01です。

\begin{split}f(x)=\begin{cases} x&(x>0)\\ \alpha(\exp(x)-1)&(x\leq0) \end{cases}\\ \Leftrightarrow f(x)=\max(x, 0) + \alpha*\min(\exp(x)-1, 0)\end{split}
In [24]:
output6=rm.elu(input1) # Sequential ->rm.Elu()
plt_act(output6)
../../../_images/notebooks_basic_algorithm_activation_types_notebook_20_0.png

入力が負のときの定数は変更可能です。下記は負の勾配係数が0.5の時です。

In [26]:
output7=rm.elu(input1,0.5)
plt_act(output7)
../../../_images/notebooks_basic_algorithm_activation_types_notebook_22_0.png

[2] Djork-Arné Clevert, Thomas Unterthiner, Sepp Hochreiter (2015). Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs). Published as a conference paper at ICLR 2016

Selu関数

入力が正の時λ倍の入力を、入力が負の時に-λα以上の負の値を出力する関数です。負の方向は指数関数を含んだ関数が適用し、-λαに収束します。勾配は不連続だが、正の入力時は一定であり、また負の入力時は出力値を用いることができます。Eluと違うところは、正負共にλ倍していることと、定数が決まっているところです。

\begin{split}f(x)=\lambda \begin{cases} x&(x>0)\\ \alpha(\exp(x)-1)&(x\leq0) \end{cases}\\ \Leftrightarrow f(x)=\lambda\{\max(x, 0) + \alpha*\min(\exp(x)-1, 0)\}\end{split}
\begin{split}\alpha=1.6732632423543772848170429916717\\\lambda=1.0507009873554804934193349852946\end{split}
In [30]:
output8=rm.selu(input1) # Sequential ->rm.Selu()
plt_act(output8)
../../../_images/notebooks_basic_algorithm_activation_types_notebook_25_0.png

[3] Günter Klambauer, Thomas Unterthiner, Andreas Mayr, Sepp Hochreiter. Self-Normalizing Neural Networks. Learning (cs.LG); Machine Learning

Softmax関数

これまでの活性化関数では総和を取ってから、各変数に対して計算する関数です。各変数を指数関数に入力し、各計算結果の総和を分母に標準化している関数です。

f(x_j)=\frac{\exp(x_j)}{\sum_{i}\exp(x_i)}
In [34]:
x = np.random.rand(1, 3)
z = rm.softmax(x) # Sequential ->rm.Softmax()
print("The inputs are: ",x)
print("The outputs are: ",z)
The inputs are:  [[0.84523073 0.47026356 0.54554521]]
The outputs are:  [[0.41180003 0.28303504 0.30516493]]