public EvalControlTestForm() { InitializeComponent(); seed = Environment.TickCount; type = EvaluationGraphType.TrigonometricSigmoid; reverse = false; evaldata = new EvaluationGraphData { data_array = new[] { new GameEvaluationData() { values = new List <EvalValue>() }, new GameEvaluationData() { values = new List <EvalValue>() }, }, selectedIndex = -1, maxIndex = 0, type = type, reverse = reverse, }; }
/// <summary> /// 評価値から[-1,+1]のy軸値に変換する関数の取得 /// EvalValue.NoValue の時は float.NaN を返す /// </summary> public static System.Func <EvalValue, float> MakeEval2VertFunc(EvaluationGraphType type, bool reverse) { switch (type) { case EvaluationGraphType.Normal: // 普通の // reverse == false, 返り値が { -1, -0.5, 0, +0.5, +1 } の場合、それぞれ評価値 { -3000以下, -1500, 0, +1500, +3000以上 } に相当 return((EvalValue v) => v == EvalValue.NoValue ? float.NaN : (reverse ? -1 : +1) * System.Math.Min(System.Math.Max((float)v / 3000f, -1f), +1f)); case EvaluationGraphType.TrigonometricSigmoid: // ShogiGUIの非線形 // 途中の定数は ±1000 の入力で ±0.5 を返す値 // reverse == false, 返り値が { -1, -0.5, 0, +0.5, +1 } の場合、それぞれ評価値 { -∞, -1000, 0, +1000, +∞ } に相当 return((EvalValue v) => v == EvalValue.NoValue ? float.NaN : (reverse ? -1 : +1) * (float)(System.Math.Asin(System.Math.Atan((double)v * 0.00201798867190979486291580478906) * 2 / System.Math.PI) * 2 / System.Math.PI)); case EvaluationGraphType.WinningRate: // 勝率 // reverse == false, 返り値が { -1, -0.5, 0, +0.5, +1 } の場合、それぞれ勝率 { 0%, 25%, 50%, 75%, 100% } に相当 return((EvalValue v) => v == EvalValue.NoValue ? float.NaN : (reverse ? -1 : +1) * (float)(System.Math.Tanh((double)v / 1200.0))); default: // 未定義 // とりあえず 0 か NaN を返す return((EvalValue v) => v == EvalValue.NoValue ? float.NaN : 0f); } }
private void WinRateUpdate_Click(object sender, EventArgs e) { evaldata.type = type = EvaluationGraphType.WinningRate; EvalUpdate(evaldata); }
private void NonlinearUpdate_Click(object sender, EventArgs e) { evaldata.type = type = EvaluationGraphType.TrigonometricSigmoid; EvalUpdate(evaldata); }
private void LinearUpdate_Click(object sender, EventArgs e) { evaldata.type = type = EvaluationGraphType.Normal; EvalUpdate(evaldata); }
/// <summary> /// 評価値グラフ用データ生成 /// </summary> public EvaluationGraphData GetEvaluationGraphDataCommand(EvaluationGraphType evalType = EvaluationGraphType.TrigonometricSigmoid, bool reverse = false) { var dataList = new System.Collections.Generic.List <GameEvaluationData> { new GameEvaluationData { values = new System.Collections.Generic.List <EvalValue>() }, new GameEvaluationData { values = new System.Collections.Generic.List <EvalValue>() }, }; var ply = kifuManager.Tree.gamePly - 1; var n = kifuManager.Tree.currentNode; var endIndex = -1; while (true) { if (n.evalList != null) { while (n.evalList.Count > dataList.Count) { dataList.Add(new GameEvaluationData { values = new System.Collections.Generic.List <EvalValue>() }); } for (var p = 0; p < n.evalList.Count; ++p) { while (ply >= dataList[p].values.Count) { dataList[p].values.Add(EvalValue.NoValue); } dataList[p].values[ply] = n.evalList[p].Eval; endIndex = System.Math.Max(endIndex, ply); } } if (n.prevNode == null) { break; } n = n.prevNode; --ply; } for (n = kifuManager.Tree.currentNode, ply = kifuManager.Tree.gamePly; n.moves.Count > 0; ++ply) { n = n.moves[0].nextNode; if (n == null) { break; } if (n.evalList == null) { continue; } while (n.evalList.Count > dataList.Count) { dataList.Add(new GameEvaluationData { values = new System.Collections.Generic.List <EvalValue>() }); } for (var p = 0; p < n.evalList.Count; ++p) { while (ply >= dataList[p].values.Count) { dataList[p].values.Add(EvalValue.NoValue); } dataList[p].values[ply] = n.evalList[p].Eval; endIndex = System.Math.Max(endIndex, ply); } } foreach (var data in dataList) { while (data.values.Count <= endIndex) { data.values.Add(EvalValue.NoValue); } } return(new EvaluationGraphData { data_array = dataList.ToArray(), maxIndex = endIndex + 1, selectedIndex = kifuManager.Tree.gamePly - 1, type = evalType, reverse = reverse, }); }