コンピュータ将棋を題材にdeepなニューラルネットを自作して遊んでみた結果得られたノウハウのメモ。
Deep Learningはfeature engineeringしてくれない
まあ当たり前の話ですが、「画像や囲碁にDCNNというモデルがとても効果的だった」+「DCNNへの入力は従来より雑なfeature (ほぼ生の情報やそれ+α)で大丈夫だった」というだけの話で、feature engineeringやネットワークの設計は結局のところ問題に特化して考えないといけないよね、という話。
少なくとも将棋の駒の配置だけを入力にして全結合層をたくさん並べただけでは、現実的な中間層の大きさでは全然予測性能が出ませんでした。
将棋の場合線形性が強いのでdeepである必要はあんまり無さそうに思えます。
全結合よりはDCNNの方がちょっとマシっぽいですが、それにしても3駒に匹敵するようなことにはならなそうです。(速度度外視でも)
それなりにfeature engineeringしてstacking(弱学習機を作ってその結果をDNNに入力する)してみたときにはそこそこ頑張ってくれて、場合によってはXGBoostを超える精度が出ることもありました。
ReLUならdeepでも乱数の初期値から普通に学習できる
ボルツマンマシンやらオートエンコーダーやらは無くても普通に学習できます。
この辺、初学者への罠なんじゃないかという気も…。
バイアス項は重要
面倒だったので最初は入れずにやってみましたが、深いネットワークでバイアス項無しだとだいぶ勾配が伝搬しにくくなるようです。
スケーリングも重要
例えば中間層のユニット数を100倍くらい増やすと、多くの場合、学習率がそのままでは大きすぎて学習できなくなります。入力の数などに応じてスケーリングした方がよいです。
同じネットワーク内で場所によって差が大きい場合なんかはちゃんとスケーリングしないとうまく学習できません。
学習率に限らず初期値も、分散を合計1にするのがよいという話とかがあるようです。
https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%83%E3%82%AF%E3%83%97%E3%83%AD%E3%83%91%E3%82%B2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3
また、中間層はともかく入力は次元数だけでなく値の傾向にもよるので、画像などの場合は正規化などをするのが一般的なようです。将棋の場合は単に適当にスケーリングすれば十分でした。
Batch Normalizationが流行っているのもこの辺の関係だと思います。
Adamすごい
とても収束が早いです。
ネットワーク中のある1つの重みに着目したとき、深いネットワークでは勾配の傾向が徐々に変わったりしそうな気がしますが、その辺を上手く対応してくれている気がします。
逆に単純な線形モデルではAdaGradで十分なのでは、ということでますますAdaGradが好きになったりも。