motoh's blog

主に趣味の電子工作やプログラミングについて書いていきます

ニューラルネットワークの表現力を確かめる

こちらで、「ニューラルネットワークは普遍性定理により任意の関数を表現できる」ということに触れました。今回は、実際に複雑な非線形の関数をニューラルネットワークに学習させ、表現力を確認したいと思います。

確認のために作成したプログラムはGithubに置きます。フレームワークchainerを利用しています(chainerはメジャーアップデートが終了してしまいましたね。勉強目的で使っているので気にしないことにします^^;)。
ronron-gh / neural-regress-sinc

■普遍性定理について
以下のリンクで直感的にイメージできる形で説明されています(「ニューラルネットワークと深層学習」というオンライン書籍の翻訳のようです)。
ニューラルネットワークが任意の関数を表現できることの視覚的証明

普遍性定理により、中間層が1層あればあらゆる関数を近似できるとされています。層がディープだから何でも近似できるのだと思っていたので、ちょっと衝撃です(^^;

ニューラルネットワークに学習させる関数は次のグラフに示すsinc関数とします。

f:id:mzmlab:20200126235813p:plain

中間層1層の場合

まずは、普遍性定理を確認するために、中間層を1層としました。中間層のニューロン数は500としました。ソースコードリポジトリnn_regress_sinc.pyを参照ください。

f:id:mzmlab:20200126235910p:plain

学習結果は次のグラフの通りです。やや歪ですが、sinc関数に近い結果が得られました(ニューロン数やエポック数などのハイパーパラメータを調整すれば、もっと良い結果が得られるかもしれませんが、ここで力尽きました^^;)。

f:id:mzmlab:20200126235953p:plain

中間層2層の場合

次に、中間層を2層に増やして学習させてみました。ニューロン数は1層目2層目共に100としました。ソースコードリポジトリnn_regress_sinc_mid2.pyを参照ください。

f:id:mzmlab:20200127000034p:plain

学習結果は次のグラフの通りです。中間層1層のときよりもニューロン数が少ないにもかかわらず、sinc関数をより忠実に表現できています。

f:id:mzmlab:20200127000106p:plain

まとめ

中間層が1層しかないニューラルネットワークでも、普遍性定理によりsinc関数のような複雑な関数を表現できることを、実際にプログラムを組んで確認しました。また、中間層を2層に増やすと、1層のときよりも少ないニューロン数でより良い学習結果が得られることを確認しました。