Skip to content

use winning_percentage_wdl in learn#36

Merged
nodchip merged 3 commits intonodchip:masterfrom
tttak:WDL_20200703b
Jul 3, 2020
Merged

use winning_percentage_wdl in learn#36
nodchip merged 3 commits intonodchip:masterfrom
tttak:WDL_20200703b

Conversation

@tttak
Copy link

@tttak tttak commented Jul 3, 2020

こんばんは。
評価関数の学習時にWDLを使うオプションを追加してみました。
learn use_wdl 1 ... のように指定すると、sigmoidを使うwinning_percentage()の代わりにWDLを用いた勝率を使うようになります。

単純に、以下のような実装にしてみました。

double winning_percentage_wdl(Value value, int ply)
{
	double wdl_w = UCI::win_rate_model( value, ply);
	double wdl_l = UCI::win_rate_model(-value, ply);
	double wdl_d = 1000.0 - wdl_w - wdl_l;

	return (wdl_w + wdl_d / 2.0) / 1000.0;
}

valueだけではなくgamePlyを使うところが通常と異なります。

ただ、手元で少し学習させてみましたところ、あまり効果がないようでした。(というより、逆効果でした)
ですので、このプルリクエスト自体はマージして頂かなくても問題ありません。
将来的には学習でWDLを活用できれば面白いかと思い、プルリクエストという形で提起させて頂きました次第です。

@nodchip nodchip merged commit 3b535b5 into nodchip:master Jul 3, 2020
@nodchip
Copy link
Owner

nodchip commented Jul 3, 2020

Thank you for the pull request. I merged it.

@nodchip
Copy link
Owner

nodchip commented Jul 5, 2020

@tttak さん
本件レビュー中に見落としがあったこと気にづきました。
calc_grad()は勾配を計算する関数でwinning_percentage()の計算式を微分したものとなっております。use_wdlが0の場合には、もとのwinning_percentage()が使用されるよう修正をお願いできますでしょうか?また、use_wdlが1の場合は、winning_percentage_wdl()の計算式を微分したものが返るよう、修正をお願いできますでしょうか?
修正が難しい場合はRevertしたほうが良いかもしれません。

@tttak
Copy link
Author

tttak commented Jul 5, 2020

@nodchip さん
ご指摘ありがとうございます。
修正したいと思いますが、修正するにあたりいくつかご教示ください。

use_wdlが0の場合には、もとのwinning_percentage()が使用されるよう修正をお願いできますでしょうか?

こちらについては、現在の実装でもそのようになっているつもりでした。
winning_percentage(Value value, int ply) の中でuse_wdlの値に応じて
winning_percentage_wdl(Value value, int ply) と、もとの winning_percentage(double value) を呼び分けています。
もし私の思い違いのようでしたらご指摘お願いします。

また、use_wdlが1の場合は、winning_percentage_wdl()の計算式を微分したものが返るよう、修正をお願いできますでしょうか?

現在主に使われているのは LOSS_FUNCTION_IS_ELMO_METHOD の calc_grad() かと思います。
この calc_grad() では lambda * (q - p) + (1.0 - lambda) * (q - t) を返していますが、
特に微分は使用していないように思いましたが、いかがでしょうか?
(LOSS_FUNCTION_IS_WINNING_PERCENTAGE の calc_grad() では微分を使っているように思いますが、
 今回のご指摘は LOSS_FUNCTION_IS_WINNING_PERCENTAGE の場合に関するものでしたでしょうか?)

@nodchip
Copy link
Owner

nodchip commented Jul 5, 2020

こちらについては、現在の実装でもそのようになっているつもりでした。
winning_percentage(Value value, int ply) の中でuse_wdlの値に応じて
winning_percentage_wdl(Value value, int ply) と、もとの winning_percentage(double value) を呼び分けています。
もし私の思い違いのようでしたらご指摘お願いします。

大変失礼いたしました。記述が誤っておりました。
use_wdlが0の場合には、LOSS_FUNCTION_IS_ELMO_METHODのcalc_grad()の中で、勝率の推定にwinning_percentage_wdl()を用い、勝率のクロスエントロピーの式を微分したもの、に修正をお願いしできればと思います。
元の関数は、シグモイド関数の微分σ'(x)=σ(x)σ(1-x)を用いて式変形を行い、
lambda * (q - p) + (1.0 - lambda) * (q - t)
というシンプルな実装にできていますが、UCI::win_rate_model()を見る限り、シグモイド関数の入力に進行度mに対する3次式が含まれており、上記の式より複雑になるのではないかと思います。
また、LOSS_FUNCTION_IS_ELMO_METHOD以外のcalc_grad()についても、今一度計算式の見直しをお願いできればと思います。

よろしくお願いいたします。

@tttak
Copy link
Author

tttak commented Jul 5, 2020

なるほど。q - p というのは単純に勝率の差を取っているのではなく、
勝率のクロスエントロピーの式を微分した結果得られたもので、
その過程でシグモイド関数の σ'(x)=(1-σ(x))σ(x) という性質が使われていたのですね。
よく見ると、最近のやねさんの記事にも書かれていましたね...
WDL版のcalc_grad()の算出、私の数学力では心許ないので、@qhapaq-49さんあたりにご登場願いたいところです...

@nodchip
Copy link
Owner

nodchip commented Jul 6, 2020

ご理解いただきありがとうございます。
次のバイナリのリリースに向け、一旦use_wdlに関する変更をRevertさせていただいてもよろしいでしょうか?

@tttak
Copy link
Author

tttak commented Jul 6, 2020

はい。一旦Revertして頂いて問題ございません。
お手数をお掛けしますが、よろしくお願いいたします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants