こんにちは!けーじです
最近E資格の取得に向けて勉強しているので、そのアウトプットのために記事にしていこうと思います。詳しくは解説していないので、雰囲気だけつかみたい方にお勧めしたいです。
今回は(中間層の)活性化関数についてまとめてみようと思います。
活性化関数とは
ディープラーニングでは行列の積算が行われています。このような演算は基本的には線形的な結果しか得られません。現実の課題を解決しようと思うと、線形的に解けるような問題ばかりではないため工夫が必要です。そこで活性化関数というものが用いられます。行列積を計算した直後に活性化関数の演算を挟むことで、非線形の出力を得ることができるようになります。
勾配とは
代表的な関数を説明していきたいところですが、ここで重要な要素である勾配について簡単に説明しておきます。ディープラーニングは、文字通りモデルの学習が不可欠な技術です。その学習の際に用いられるのが誤差逆伝播法(バックプロパゲーション)です。ここでは詳細な解説は省きますが、この過程で関数の微分が必要となる、という点だけ覚えておいてください。その微分によって計算される、関数の傾きや変化の割合を示す値を勾配と呼びます。この勾配をいかに扱うかに重点を置いて、活性化関数の開発に工夫が詰まっていたりします。
代表的な活性化関数
それでは代表的な活性化関数についてみていきましょう
シグモイド関数
$$ f(x) = \frac{1}{1+e^{-x}},~~~f'(x)=\frac{e^{-x}}{(1+e^{-x})^2}=f(x)(1~-~f(x)) $$


ディープラーニングの勉強をしていて最初に出てくる活性化関数でしょう。このシグモイド関数は出力を確率として解釈する際にも用いられるので、直感的にも理解しやすいものなのかなと思います。 デメリットとしては少々計算コストが高い(後のRELUは計算コスト低い)ことや、出力がすべて正になり収束が遅いことなとが挙げられます。また、次のtanhの時にまとめて説明しますが、勾配消失問題の影響を受けやすいです。
tanh(ハイパボリックタンジェント)
$$tanh(x) = \frac{e^{x}-e^{-x}}{e^{x}+e^{-x}}, ~~~tanh'(x) = \frac{4}{(e^{x}+e^{-x})^2} = 1~-~tanh^2(x)$$


グラフの形はシグモイド関数と似ていますが、0付近の傾き(微分した値)が大きいのと、-1から1までの値をとるところが違います。このような特徴は、シグモイド関数のデメリットであった収束が遅いという欠点を緩和できます。 シグモイド関数も同様ですが、tanhは勾配消失問題というものを抱えています。これは微分した関数の形を見ていただくと、入力値が0から離れていくと勾配の値も0に近づいていきます。ディープラーニングで学習を行う際は、この勾配の値と学習率と呼ばれる定数をかけた値を用いて重みを更新していくのですが、勾配が0になってしまうとかけた値が0になり、なかなか重みが更新されなくなります。tanhはシグモイド関数よりもこの勾配消失問題が起きにくくなっていますが、一般的には次のRELUなどから大きく改善したとされています。
ReLU(Rectified Linear Unit)
$$f(x) = \max(0, x), ~~~ f'(x) = \begin{cases}
~0 & (x \le 0) \\
~1 & (0 < x)
\end{cases} $$


ここから大きく関数の形が変わります。入力値が正の範囲では値をそのまま返し、0以下では0を返すようになっています。このようにしておくと入力値が正である限りは勾配として1が必ず得られます。これが勾配消失問題に有効なようです。 デメリットとしては入力値が0以下の時は勾配が0になることです。Dying ReLU問題などとも呼ばれるようですが、値が0の入力値が現れるとそれ以降学習に必要な勾配が伝播されなくなるため学習ができなくなります。この問題を解決しているのが以降の活性化関数になります。
Leaky ReLU
$$f(x) = \max(\alpha x, x), ~~~ f'(x) = \begin{cases}
~\alpha & (x \le 0) \\
~1 & (0 < x)
\end{cases} $$


ReLUと比べると、値が0以下の時に傾きを持っている点が異なります。このようにすると0以下の値でもバックプロバゲーションにより学習できます。 $\alpha$は通常ごく小さい正の定数で、0.01などが使用されるそうです。(上のグラフは見やすいように0.05で作成しています。)
parameric ReLU
$$f(x) = \max(\alpha_i x, x), ~~~ f'(x) = \begin{cases}
~\alpha_i & (x \le 0) \\
~1 & (0 < x)
\end{cases} $$
式の形はLeaky ReLUとほとんど変わっていません。違いは学習時に個々のノードに適切な傾き $\alpha_i$を与えてあげるところになります。parametric ReLUを使用する場合にはこの $\alpha_i$も学習対象にして学習させることになります。(Leaky ReLUはあらかじめ \alphaを定めておく=ハイパーパラメータ)

GELU(Gaussian Error Linear Unit)
$$GELU(x) = x・\Phi(x) = x・\frac{1}{2} \left[ 1+\text{erf}\left(\frac{x}{\sqrt{2}}\right) \right]$$
$$GELU'(x) = \Phi(x) + x・\phi(x) = \frac{1}{2} \left[ 1+\text{erf}\left(\frac{x}{\sqrt{2}}\right) \right] + x・\frac{1}{\sqrt{2\pi}}e^{-\frac{x^2}{2}}$$


GELUはReLUを改良したとしてよく登場する活性化関数です。詳細なところまでは理解できていませんが、ReLUのように特別な場合分けがなく記述することができ、どの値であっても微分可能な形をしています。 Transformerのモデルなどでよく利用されるようですので、近年注目を集めるのもうなずけます。実際の計算をする際には近似式を用いる場合もあるようです(最近はその必要もなくなっている?ような見向きもあるようです)。
まとめ
いかがでしたでしょうか?今回はアウトプットするためのメモ書きのようになってしまいましたが、同じようにディープラーニングの技術習得に励んでいる方の参考になれば幸いです。今後も習得すべき単元があればアウトプットもかねてこのような記事にしていきたいと考えています。