shogi686の学習について その2

評価ベクトルは、メモリ上では対称性で容量節約とか一切してない。2駒関係の▲88玉▲78銀と同じ値の▲78銀▲88玉や▲28玉▲38銀、符号が反対の△22玉△23銀も全部入っている。2駒関係だけでそんなに大きくないし、冗長だが差分計算を簡単に書くためこうしている。スピードも、KPPはこのほうが速いらしいし、どうせキャッシュに乗らないと思えば冗長でもいいだろう。
学習時も同じ形式にしている(2駒相対用のデータ構造などは用意していないという意味)。時間がかかるのはPVを求めるところだけで、メモリも今の規模の学習なら足りているので、わかりやすさ優先。上記のような対称性があるので、例えば▲88玉▲78銀と▲78銀▲88玉には同じ値が付いている必要がある。そこで、同じ値が付く場所をいっぺんに処理する。左右対称・先後入替(符号反転)・2駒入替の3つを考慮する。
この考え方は、2駒相対でも使える。2駒を含む最小の(升に沿った)長方形を計算して、それを盤面内で動かす。2駒相対の意味で同じ値になる要素をまとめて処理する。ラムダ式を使うと、勾配をかき集めて足してみんなに書き戻すとか、更新後の値を1ヶ所で計算して同じ値を書き込むとかできる。スピードはよくわからないが、特に速さが求められる場所ではない。
次元下げは2駒相対のみ。金と成銀・成桂・成香・と金の同一視(駒割のみ違う)もしているが、結局同一視したままで次元上げしてない。2駒絶対の勾配と2駒相対の勾配を単に足しているので、駒同士が近い関係では相対が強く出ているかもしれない(これは補正もできそうだが、そもそももっといい方法がありそう)。持ち駒は、相対では自分自身の関係のみ(先手の3枚目の歩と3枚目の歩の関係が3枚目の歩の価値)とし、絶対では勾配は1/40(40は将棋の駒の数)にしている。それを足すことでまあまあのバランスになるんじゃないかと。
玉と玉以外の駒の関係では、周囲4升の値の平均を基準にペナルティをかけている。なんかバグある気がするし、そもそも玉から離れた場合のみとかにしなくていいんだろうか。意図は、玉から離れた値が滑らかになってほしいというもの。2駒関係は思ったよりは構造が単純なイメージで、こういう手法がはまれば少ない棋譜でもけっこう強くなりそうな気がする。
ペナルティの大きさは、評価ベクトルの各値(からペナルティの基準値引いてねえ)の絶対値の対数に定数をかけている。勾配が1なら3、勾配が2なら30、勾配が3なら300くらいの値が付いてもいい、みたいな意図。信頼できない棋譜が少量あるという状況で、普通のL1やL2はうまくいかなかった(が、L1をちゃんとやればうまくいくパティーンだよねこれ)。
ペナルティで値の絶対値が減るとき、例えば10が16減って-6になるのはおかしいので、そういうときは0になるようにしている。
さて、棋譜が少ないとどうしても値がまばらにしか付かない。そこで、玉を含まない関係では、周囲25升以外を全て0にしている(そこは明らかに過学習なので)。玉を含む場合は、周囲25升以遠では遠くなるほど駒の価値が下がるという縛りを入れている。この25升の判定は、利きが前方に偏っている桂香では、ずらしてある。
遠くなるほど価値が下がるというのは、ある程度玉と駒が離れた領域では正しいと思う。周囲25升以遠に対する具体的な処理は次の3つ。(1)チェス盤距離で4以上離れていたら周囲9升の平均をその升の値とする。(2)玉の後方にある駒は一つ上の駒を見る(対になる処理として、駒の前方にある玉からも一つ下の玉を見る)。(3)横位置が3以上離れていたら一つ横の駒を見る。最後に、(1)〜(3)の最小値から距離と駒割に応じた小さな値を引く(複雑なことをやっているようだが、全部適当である)。
周囲9升の平均にしちゃうのが見ての通り暴挙で、もう少しなんとかしたい。しかし、よほどいい代わりの方法が見つからない限り、値が滑らかになるメリットのほうが大きいと思っている。評価関数の歪みを少しでも減らすことが、強さにつながる。強さとは、弱くないことだ。選手権に向けての学習部のプログラミングは、弱さを減らす戦いだった。
これをした上で(上述したように)ペナルティの基準値も変えている。どのくらい効くのかは調べていないが、まあ悪くはないのだろうと思う(思ってるだけで怪しい)。計算コストは無視できる程度なので、特にやめる動機もない(問題が見つかる可能性は高いので、そうなったら対応する)。
あと、値の更新について書いてなかった。勾配(ペナルティ含む)の符号を見て、決められた幅だけ動かす。値の変動幅は要素毎に記録してある。最初は50くらい(評価値は2駒関係の和を1/32して使うのでこれは大きな値ではない)から始めて、3連続で同じ方向へ動くなら変動幅を増やす。前回と違う方向へ動いたら減らす。やりすぎると不健全な感じになるのでほどほどに。最後は変動幅の最大を2とかに制限して仕上げる。この辺りは、大量の棋譜を使うならもっと高速化・自動化する必要がある。
終わり。