次元下げモジュールのプラグイン化計画

NDFがやったKPPの次元下げ

KPP = 絶対KPP + 絶対PP + 相対KPP + 相対PP

を綺麗にプログラムするための方法について考えてみます。このような次元下げは、KPPを与えるとそれに対応する絶対KPP、絶対PP、相対KPP、相対PPの配列のindexを返すものとして設計すると綺麗に書けます。

すなわち、
int* make_kpp(Square king , BonaPiece p1 , BonaPiece p2);
のように設計することです。この返し値をpとすると、
learn_kpp [ p[0] ] が絶対KPP
learn_kpp [ p[1] ] が絶対PP
learn_kpp [ p[2] ] が相対KPP
learn_kpp [ p[3] ] が相対PP
p[4] = INT_MAX(終端)
のようになります。


もう少し一般化すると、KPPを4個に分解するとは限らず、N個の場合であっても、この設計でうまく動くことがわかります。

また、次元下げをするときにマイナスの意味にしたいところでは、indexをマイナスの値をとるという約束にします。つまり、

if (p[0] < 0)
sum = sum - learn_kpp[-p[0] ];
else
sum = sum + learn_kpp[p[0] ];
のようにマイナスをつけて解釈されるものとします。

私は上記のように設計して、このindexを与えたときにK85S32G45のようにその意味を表示する関数を用意してデバッグしていました。そうすると、自分がやっている次元下げが合理的であるかだとか、(バグがあって)間違ったindexを参照していないかだとか、そういう諸々のチェックにつながるからです。この方法は、お勧めです。


さて、上記手法をさらに一般化すると、次元下げ自体をプラグイン化することが出来ます。(画像ビュアーのJPEGプラグインとか、そういう意味でのプラグイン)

つまり
1) プラグインは、読み込みのときにlearn_kpp配列の大きさを返します。
2) プラグインは、int* make_kpp(Square king , BonaPiece p1 , BonaPiece p2)を実装します。

このようになっていれば、KPPの次元下げを行なうモジュール自体を独立させることが出来ます。
NDF方式やAWAKE方式、deep learning方式など、いろんな次元下げモジュールを組み合わせることが出来るようになります。

次元下げは比較的複数の次元下げと併用することが出来ると私は考えています。合理性のない次元下げである場合、その因子にゼロの値がつくだけであり、よほどでない限りノイズにはならないので複数の次元下げを併用したほうがいい結果につながります。

そこで、次元下げ自体をモジュール化して、複数人で開発し、そしてそのモジュールを自動的に組み合わせて自動的に棋譜からの学習をさせ、自動的に対戦させ、勝率を調べ、自動的に最強の次元下げモジュールの組み合わせを発見するというフレームワークを作ることも出来ます。

まあ…次元下げを複数やるのには結構大きなメモリ空間が必要なので、こういうことをしだすと64GBでは足りなくなってきますが…。

ともかく、次元下げモジュール自体のプラグイン化というテーマについて考えてみました。