「ゼロから作るDeep Learning」を読みながらメモったことなど 2活性化関数について

最近になって調べてみたらこの記事に間違いがありましたので、訂正します。シグモイド関数と恒等関数をかけた関数の名前ですが、GELUではなくSwishと呼ぶそうです。GELUについて調べていて、この記事に来てしまった方がいらっしゃいましたら、お詫び申し上げます。(2020年2月19日)

 

今回は活性化関数についてのメモです。

 

活性化関数

 前回「ゼロから作るDeep Learning」を読みながらメモったことなど - 冬の日 でニューロンをモデル化しました。そのとき、ニューロンから出力される信号は核でなんやかんやの処理が施された結果、発信されたものです。この処理を数式で表現したものを「活性化関数」と呼ぶそうです。

 今回はその活性化関数の中でもよく使われるらしい、シグモイド関数とReLU(ランプ関数とも呼ばれるらしい)についてまとめました。

 あと、本記事ではbをバイアスではなく閾値として取り扱っています。「ゼロから作るDeep Learning」との対応させたい場合は少し注意してください。

 

 

シグモイド関数

f:id:touchP:20181026232024p:plain

シグモイド関数は↑のような関数です。この関数のグラフは↓のようになります。

f:id:touchP:20181026232230p:plain

 このグラフはβ = 1、b = 1のときです。このグラフからも分かる通り、この活性化関数で表現される処理を行うニューロンは、入力信号が閾値b(このグラフでは x = 1 )よりも大きいと発火し1を出します。また、小さいと0つまり発火しません。

 これは実際のニューロンに非常に似ています。シグモイド関数ではb付近で滑らかにグラフが繋がっていますが、実際の細胞ではもっと極端に0or1の反応を示し、その処理はステップ関数で表現されるそうです。

 ですがニューラルネットでは、この “滑らか” であることが重要なようです。どうもニューラルネットの学習では活性化関数の微分が使用されるそうで、グラフが滑らかであれば関数は大体微分できるからです。

 

閾値

 折角bを閾値として活性化関数にぶち込んでいるので、いろいろ変えてプロットしてみました。

・b = 2 のとき

f:id:touchP:20181026233146p:plain

・b = 3 のとき

f:id:touchP:20181026233137p:plain

・b = 4 のとき

f:id:touchP:20181026233143p:plain

・全部重ねてみる

f:id:touchP:20181026234146p:plain

bが大きくなるとグラフがどんどん右にずれていきます。つまりニューロンが発火し難くなっていくのがとても分かりやすいですね。bをバイアスとしてではなく閾値として扱った恩恵です。(と自分のやり方を正当化してみる。)

 関係ないですけど、matplotlibでグラフを書くとカラフルになって綺麗ですね。

 

β

 私が勝手に入れたパラメータとしてβがあります。これはシグモイド関数の傾き部分の傾斜を決定します。グラフで見た方が早いのでプロットしました。(b = 2 としました)

・β = 1 のとき

f:id:touchP:20181026235653p:plain

・β = 2 のとき

f:id:touchP:20181026235812p:plain

・β = 10 のとき

f:id:touchP:20181026235815p:plain

・β = 100 のとき

f:id:touchP:20181026235809p:plain

・全部重ねて

f:id:touchP:20181026235957p:plain

 見て分かるようにβの値が大きくなると傾斜がきつくなっていきます。β = 100 ぐらいになるともうステップ関数のようですね。実際 β = ∞ の極限ではシグモイド関数はヘヴィサイドのステップ関数となります。

 

 

Rectified Linear Unit (ReLU)

f:id:touchP:20181027000725p:plain

 Rectified Linear Unit (ReLU) は最近のニューラルネットで最もよく使用される活性化関数だそうです。そのグラフは↓です。( b = 1 のとき)

f:id:touchP:20181027001249p:plain

 見て分かるように、閾値b(このグラフではx = 1)で不連続に折れ曲がっています。微分可能性とは何だったのか!? なんだか納得いきませんが、この活性化関数を使用するといろいろな場面でうまくいくそうです。納得いきませんが。

 

例によって閾値を変えてプロットしてみました。

・b = 2 のとき

f:id:touchP:20181027001256p:plain

 

・b = 3 のとき

f:id:touchP:20181027001239p:plain

・b = 4 のとき

f:id:touchP:20181027001242p:plain

・全部重ねて

f:id:touchP:20181027001246p:plain

 シグモイドのときと同じく閾値が大きくなればニューロンが発火し難くなっていくのが分かります。

 

 

 

 

ここから訂正です。GELUをSwishと読み替えてください。

参考

Swishが紹介された論文:Prajit Ramachandran, Barret Zoph, Quoc V. Le: Searching for Activation Functions, https://arxiv.org/abs/1710.05941

 

Gaussian Error Linear Unit (GELU)

f:id:touchP:20181027002950p:plain

 ReLUの不連続なグラフが気に入らない為、連続な関数で近似します。定義はシグモイド関数に線形関数を掛けただけです。始め名前が分からなかったのですが、簡単な関数なので絶対誰か使っているはず! と調べたら案の定ありました。GELU(Gaussian Error Linear Unit)と呼ぶそうです。やはり誰しも不連続なグラフを見ると連続な関数で近似したくなるものなのですね。

参考(これはGELUについての参考です)

Bridging Nonlinearities and Stochastic Regularizers with Gaussian Error Linear Units

グラフは↓です。(b = 2 のとき)

f:id:touchP:20181027004604p:plain

 このニューロンは x << b のとき0、x = b のとき0、b << x のとき x-b の信号を発信します。これはReLUのときと非常に似ています。しかし、閾値b付近のふるまいが少し違います。しかし、βの値を調節することでこれを解決できます。

 それを確認するためβの値を変えてプロットしてみました。

・β = 2 のとき

f:id:touchP:20181027005248p:plain

・β = 10 のとき

f:id:touchP:20181027005255p:plain

・β = 100 のとき

f:id:touchP:20181027005259p:plain

・重ねてみる

f:id:touchP:20181027005312p:plain

閾値付近の詳細

f:id:touchP:20181027005306p:plain

 見て頂いた通り、βの値を大きくすることでGELUはReLUへと近づいていきます。実際 β = ∞ でGELUはReLUと一致します。やりましたね! これで微分不可能性の問題を解決できました! 嬉しいですね! 

 皆さんもぜひこのGELUを使ってニューラルネットを構築してみて下さい! 計算に時間が掛かることが分かると思います!・・・!? そう。GELUはReLUに比べて計算コストが大きいのです。・・・式を見れば当然ですね。ですので、計算の時間なんて関係ない!自分は滑らかな関数を愛しているんだ! という方が使ったらいいじゃないでしょうか。

 

 

シグモイド関数に似た関数

私が知っているシグモイド関数に似た関数をまとめておきます。

 

多段の階段関数

f:id:touchP:20181027011304p:plain

 シグモイド関数やステップ関数は、一つのスイッチを表現しています。ですので、シグモイド関数を使って沢山のスイッチを表現したいときは、閾値に関して足し合わせればできます。グラフは↓です。

f:id:touchP:20181027011316p:plain

 

Fermi distribution

f:id:touchP:20181027011512p:plain

フェルミオンが従う統計分布です。グラフは↓です。

f:id:touchP:20181027011626p:plain

シグモイド関数の逆向きになります。

 

Bose distribution

f:id:touchP:20181027011812p:plain

ボソンが従う統計分布です。グラフは↓です。

f:id:touchP:20181027011918p:plain

Fermi distributionと符合が一か所違うだけで全然違うグラフになるのは面白いですね。

 

 

 

 

 

 

 

最後に

 今回は活性化関数についてでおしまいです。現時点で私が納得していることや考えたことはこのぐらいですので。しかし、先はまだまだ長いですね。一歩ずつ進んでいけたらと思います。

 関数をグラフに描くのが面白くて、ついつい沢山描いてしまいました。コンピュータはどんな関数もグラフにしてくれるので便利ですね。

 

 

追記

ちゃんと調べないで書いたのがばればれですね。インターネットに間違った情報を載せてしまった。申し訳ない。

うぅ・・・。恥ずかしい。(2020年2月19日)