ニューラルネットワークの表現力を確かめる
こちらで、「ニューラルネットワークは普遍性定理により任意の関数を表現できる」ということに触れました。今回は、実際に複雑な非線形の関数をニューラルネットワークに学習させ、表現力を確認したいと思います。
確認のために作成したプログラムはGithubに置きます。フレームワークはchainerを利用しています(chainerはメジャーアップデートが終了してしまいましたね。勉強目的で使っているので気にしないことにします^^;)。
ronron-gh / neural-regress-sinc
■普遍性定理について
以下のリンクで直感的にイメージできる形で説明されています(「ニューラルネットワークと深層学習」というオンライン書籍の翻訳のようです)。
ニューラルネットワークが任意の関数を表現できることの視覚的証明
普遍性定理により、中間層が1層あればあらゆる関数を近似できるとされています。層がディープだから何でも近似できるのだと思っていたので、ちょっと衝撃です(^^;
ニューラルネットワークに学習させる関数は次のグラフに示すsinc関数とします。
中間層1層の場合
まずは、普遍性定理を確認するために、中間層を1層としました。中間層のニューロン数は500としました。ソースコードはリポジトリのnn_regress_sinc.pyを参照ください。
学習結果は次のグラフの通りです。やや歪ですが、sinc関数に近い結果が得られました(ニューロン数やエポック数などのハイパーパラメータを調整すれば、もっと良い結果が得られるかもしれませんが、ここで力尽きました^^;)。
中間層2層の場合
次に、中間層を2層に増やして学習させてみました。ニューロン数は1層目2層目共に100としました。ソースコードはリポジトリのnn_regress_sinc_mid2.pyを参照ください。
学習結果は次のグラフの通りです。中間層1層のときよりもニューロン数が少ないにもかかわらず、sinc関数をより忠実に表現できています。
まとめ
中間層が1層しかないニューラルネットワークでも、普遍性定理によりsinc関数のような複雑な関数を表現できることを、実際にプログラムを組んで確認しました。また、中間層を2層に増やすと、1層のときよりも少ないニューロン数でより良い学習結果が得られることを確認しました。