この連載は、E資格の勉強中に学んだ内容を記事としてまとめるものです。 E資格を受験される方のおさらいや、E資格に興味のある方の参考となれば幸いです。
前回(第2回目)は、ニューラルネットワークの基本要素となるパーセプトロンについて取り上げました。第3回目の今回は、隠れユニットの活性化関数についてのまとめです。
第1回目の記事:E資格の勉強内容まとめDay1「ディープラーニングの概要」
第2回目の記事:E資格の勉強内容まとめDay2「パーセプトロン」
ニューラルネットワーク
まずは前回のおさらいです。
ニューラルネットワークを図で表すと下のようになります。

〇で表したものをノード(ニューロン)、ノードの列を層といいます。
また、一番左の層を入力層、一番右の層を出力層、そして間の層を中間層(または隠れ層)と呼びます。
ニューラルネットワークに入力されたデータは左の層から右の層へ伝搬されます。
この処理を順伝搬といいます。
それでは、ニューラルネットワークで基本となるデータ処理として全結合層のアフィン変換について復習します。
データが次の層へ伝搬されるとき、隣接する層のノード間すべてが結合しているものを「全結合層」と呼ばれます。
この全結合層では前の層のデータをアフィン変換して次の層へと伝えます。
全結合層の例を示します。

全結合層での出力\( \mathbf{y} \)は入力\( \mathbf{x} \)と重み\( \mathbf{W} \)の行列の積とバイアス\( \mathbf{b} \)の和によって計算されます。
(この処理がアフィン変換です。)
数式で次のように表します。
$$ \Large \pmatrix{ y_1 & y_2 & y_3} = \pmatrix{ x_1 & x_2 } \pmatrix{ w_{11} & w_{12} & w_{13} \cr w_{21} & w_{22} & w_{23} } + \pmatrix{ b_1 & b_2 &b_3 } $$
$$ \Large \mathbf{y} = \mathbf{x W} + \mathbf{b} $$
ちなみに、上の式では、\( \mathbf{x, y} \) を行ベクトルとして扱った表記です。
\( \mathbf{x, y} \) を列ベクトルで扱うと次の式で表されます。
$$ \Large \pmatrix{ y_1 \cr y_2 \cr y_3} = \pmatrix{ w_{11} & w_{21} \cr w_{12} & w_{22} \cr w_{13} & w_{23} } \pmatrix{ x_1 \cr x_2 } + \pmatrix{ b_1 \cr b_2 \cr b_3 } $$
$$ \Large \mathbf{y} = \mathbf{W^T x} + \mathbf{b} $$
行ベクトルで扱うか列ベクトルで扱うかの違いで式の表現は異なりますが計算していることは同じです。(E資格ではこちらの表記で問われることも多いようです。)
これで全結合層の処理を構成できました。
しかし、ここでひとつ問題があります。
一般的にディープラーニングではニューラルネットワークの中間層を深くすることで表現力を増やすことができます。
(表現力が増えることで複雑なタスクをこなせるようになります!)
それでは上記の全結合層をたくさん繋げばニューラルネットワークは表現力が増えるのでしょうか?
答えはNoです。
アフィン変換は何回繰り返しても、結局は一度のアフィン変換を行っているものと変わりません。(アフィン変換は線形変換であり、線形変換の線形変換は線形変換です。)
つまり、単純にアフィン変換を繰り返すだけではネットワークの表現力は変わりません。
そこで登場するのが、非線形な変換を行う活性化関数です。
活性化関数
活性化関数は隠れユニットで適用されます。(隠れユニットとは、中間層(隠れ層)のノードのことです。)
下の図はアフィン変換+活性化関数の構成の例を示したものです。

前の層の\( \mathbf{x} \) をアフィン変換で\( \mathbf{a} \)に変換したのち、活性化関数 \( \phi \)にて \( \mathbf{h} \) に変換することで次の層へ伝搬しています。
アフィン変換に加えて、活性化関数による非線形な変換により表現力の高いニューラルネットワークを構成することができます。
この処理を式で表すと次のようになります。
$$ \Large \mathbf{h} = \phi ( \mathbf{W^T x} + \mathbf{b} ) $$
活性化関数にはいくつか種類があります。
現在ではReLUを使うことが一般的となっています。
それでは代表的な活性化関数をいくつか紹介します。
ステップ関数
ステップ関数は初期のパーセプトロンに用いられてた古典的な関数です。
入力が0を超えたら1を出力し、それ以外は0を出力します。
$$ \Large \begin{eqnarray} \phi(x) = \begin{cases} 1 & ( x \gt 0 ) \\ 0 & ( x \leq 0 ) \end{cases} \end{eqnarray} $$
単純な関数ですが、微分した際に勾配が0となるため学習時に勾配消失問題というものが起こります。
そのため、現在ではほぼ使われることはありません。
(勾配消失問題については追々紹介していきます。)
pythonでステップ関数を実装してみます。

関数として実装することで簡単に呼び出して使用できます。
(他の活性化関数も関数として実装していきます。)
グラフ化すると階段のステップのように変化しています。
(参考にグラフ化のコードも記載しています。)

シグモイド関数
シグモイド関数はロジスティクスシグモイドとも呼ばれます。
入力(負から正の実数)を0から1までの滑らかな出力へと変換します。
$$ \Large \sigma(x) = \frac{1}{1+e^{-x}} $$
シグモイド関数も勾配消失問題が起こるため、隠れユニットではあまり使用されません。
(出力ユニットでは2クラス分類として使用されます。詳細は追々紹介していきます。)
pythonでシグモイド関数を実装してみます。

グラフは次のようになります。

tanh(ハイパボリックタンジェント)関数
tanh(ハイパボリックタンジェント)関数はシグモイド関数よりも勾配消失しにくい関数です。
(ReLUが登場するまでは最も有用な活性化関数でした。)
入力(負から正の実数)を-1から1までの滑らかな出力へと変換します。
$$ \Large tanh(x) = \frac{e^x - e^{-x}}{ e^x +e^{-x}} $$
勾配消失が起きにくくなったとはいえ、勾配消失問題は起こります。現在ではあまり使用されていません。
pythonでtanh関数を実装してみます。

グラフは次のようになります。

ReLU関数
tanh関数の代わりに、現在最も使用されている活性化関数がReLU(Rectified Linear Unit)関数です。
入力が正の時はそのまま通して負の場合は0を出力します。
$$ \Large \begin{eqnarray} ReLU(x) = \begin{cases} x & ( x \gt 0 ) \\ 0 & ( x \leq 0 ) \end{cases} \end{eqnarray} $$
勾配消失が起こりにくい、計算が容易といった特徴があります。
pythonでReLUを実装してみます。

グラフは次のようになります。

おわりに
第3回目は、活性化関数と代表的なステップ関数、シグモイド関数、tanh関数、ReLU関数について説明しました。次回は、活性化関数の続きとして「ReLUの一般化」からまとめようと思います。
今回も最後までお読みいただきありがとうございました!