ニューラルネットワークの中には、〜またはさらにその集まりで構成されるような大変複雑な物があります。(例: Google のInception-v4モデル https://research.google.com/pubs/pub45169.html) Chainerでは、GoFのデザインパターンの一つであるCompositeパターンを利用して、このような複雑なニューラルネットワークも柔軟に表現できるようになっています。
chainer.Linkは「入力に対して出力を出す」という共通のインターフェースを提供しており、そのサブクラスであるchainer.Chainも同様です。例えば、Linkオブジェクト l1
, l2
と Chainオブジェクト c1
があった時に、
l1(l2(c1)
のように出力を次のオブジェクトの入力として数珠つなぎにしていくことが出来ます。
これだけでは一般の関数と同じですが、ChainクラスはさらにLinkオブジェクトを子要素として保持するインターフェース(chainer.Chain.add_link)を持っています。ChainはLinkでもある(サブクラス)わけですから、結果としてChainはLinkとChainの両方を子要素として含むことが出来ます。結果として、任意の深さの階層を持った計算要素のまとまりを表現することが出来ます。
これは身近な例としてはファイルシステムにおけるファイルとディレクトリに似ています(Compositeパターンの説明において頻出する例のひとつです)。この場合Linkをファイル、Chainをディレクトリと見ると分かりやすいでしょう。Chain(ディレクトリ)は複数のLink(ファイル)やChain(サブディレクトリ)を含み、含まれたChainはまた複数のLinkやChainを含む。というわけです。
このように基本的な計算要素としてのLink、それを子要素とするChainでCompositeパターンを構成することで、例えば3層のパーセプトロンをさらに組み合わせたニューラルネットワークの表現などが柔軟にできるようになっています。