rank model
This commit is contained in:
1 parent
32074d6616
commit
f4f8f61084
6 files changed
+108
-16
No files matched your search
@@ -76,13 +76,18 @@ on the board, or not output details for them in SGFs,you can do so under 'Config
|
||||
|
||||
This section describes the available AIs, with strength based on their current OGS rankings using the default settings.
|
||||
|
||||
In the 'AI settings', settings with calibration are at the top and have a lighter color, changing these will show an estimate of rank.
|
||||
This estimate is reasonably accurate as long as you have not changed the other settings.
|
||||
|
||||
* Recommended options for serious play include:
|
||||
* **[9p+]** **KataGo** is full KataGo, above professional level. The analysis and feedback given is always based on this full strength KataGo AI.
|
||||
* **[15k - 3d]** **Calibrated Rank Bot** was calibrated on various bots (e.g. GnuGo and Pachi at different strength settings) to play a balanced game from the opening to the endgame without making serious (DDK) blunders. Further discussion can be found on [this](https://github.com/sanderland/katrain/issues/44) thread.
|
||||
* **[15k - 3d]** **Calibrated Rank Bot** was calibrated on various bots (e.g. GnuGo and Pachi at different strength settings) to play a balanced
|
||||
game from the opening to the endgame without making serious (DDK) blunders. Further discussion can be found
|
||||
[here](https://github.com/sanderland/katrain/issues/44) and [here](https://github.com/sanderland/katrain/issues/74).
|
||||
* **[~5k]** **ScoreLoss** is KataGo analyzing as usual, but
|
||||
choosing from potential moves depending on the expected score loss, leading to a varied style with mostly small mistakes.
|
||||
* **[~4d]** **Policy** uses the top move from the policy network (it's 'shape sense' without reading).
|
||||
* **[~4k]** **Policy Weighted** picks a random move weighted by the policy, leading to a varied style with mostly small mistakes, and occasional blunders due to a lack of reading.
|
||||
* **[~5d]** **Policy** uses the top move from the policy network (it's 'shape sense' without reading).
|
||||
* **[12k - 2d]** **Policy Weighted** picks a random move weighted by the policy, leading to a varied style with mostly small mistakes, and occasional blunders due to a lack of reading.
|
||||
* **[~8k]** **Blinded Policy** picks a number of moves at random and play the best move among them, being effectively 'blind' to part of the board each turn.
|
||||
* Options that are more on the 'fun and experimental' side include:
|
||||
* Variants of **Blinded Policy**, which use the same basic strategy, but with a twist.:
|
||||
|
||||
@@ -242,6 +242,7 @@ class KaTrainGui(Screen, KaTrainBase):
|
||||
self.message_queue.put([self.game.game_id, message, args, kwargs])
|
||||
|
||||
def _do_new_game(self, move_tree=None, analyze_fast=False):
|
||||
self.idle_analysis = False
|
||||
mode = self.play_analyze_mode
|
||||
if (move_tree is not None and mode == MODE_PLAY) or (move_tree is None and mode == MODE_ANALYZE):
|
||||
self.play_mode.switch_ui_mode() # for new game, go to play, for loaded, analyze
|
||||
|
||||
+39
-8
@@ -25,17 +25,39 @@ from katrain.core.constants import (
|
||||
OUTPUT_INFO,
|
||||
AI_WEIGHTED_ELO,
|
||||
CALIBRATED_RANK_ELO,
|
||||
AI_LOCAL_ELO_GRID,
|
||||
AI_TENUKI_ELO_GRID,
|
||||
AI_TERRITORY_ELO_GRID,
|
||||
AI_INFLUENCE_ELO_GRID,
|
||||
)
|
||||
from katrain.core.game import Game, GameNode, Move
|
||||
from katrain.core.utils import var_to_grid
|
||||
|
||||
|
||||
def interp1d(x, lookup):
|
||||
def interp_ix(lst, x):
|
||||
i = 0
|
||||
while i + 1 < len(lookup) - 1 and lookup[i + 1][0] < x:
|
||||
while i + 1 < len(lst) - 1 and lst[i + 1] < x:
|
||||
i += 1
|
||||
t = max(0, min(1, (x - lookup[i][0]) / (lookup[i + 1][0] - lookup[i][0])))
|
||||
return (1 - t) * lookup[i][1] + t * lookup[i + 1][1]
|
||||
t = max(0, min(1, (x - lst[i]) / (lst[i + 1] - lst[i])))
|
||||
return i, t
|
||||
|
||||
|
||||
def interp1d(lst, x):
|
||||
xs, ys = zip(*lst)
|
||||
i, t = interp_ix(xs, x)
|
||||
return (1 - t) * ys[i] + t * ys[i + 1]
|
||||
|
||||
|
||||
def interp2d(gridspec, x, y):
|
||||
xs, ys, matrix = gridspec
|
||||
i, t = interp_ix(xs, x)
|
||||
j, s = interp_ix(ys, y)
|
||||
return (
|
||||
matrix[j][i] * (1 - t) * (1 - s)
|
||||
+ matrix[j][i + 1] * t * (1 - s)
|
||||
+ matrix[j + 1][i] * (1 - t) * s
|
||||
+ matrix[j + 1][i + 1] * t * s
|
||||
)
|
||||
|
||||
|
||||
def ai_rank_estimation(strategy, settings) -> Tuple[int, bool]:
|
||||
@@ -43,10 +65,19 @@ def ai_rank_estimation(strategy, settings) -> Tuple[int, bool]:
|
||||
return 9, True
|
||||
if strategy == AI_RANK:
|
||||
return 1 - settings["kyu_rank"], True
|
||||
if strategy in [AI_WEIGHTED]:
|
||||
if strategy in [AI_WEIGHTED, AI_LOCAL, AI_TENUKI, AI_TERRITORY, AI_INFLUENCE]:
|
||||
if strategy == AI_WEIGHTED:
|
||||
elo = interp1d(settings["weaken_fac"], AI_WEIGHTED_ELO)
|
||||
kyu = interp1d(elo, CALIBRATED_RANK_ELO)
|
||||
elo = interp1d(AI_WEIGHTED_ELO, settings["weaken_fac"])
|
||||
if strategy == AI_LOCAL:
|
||||
elo = interp2d(AI_LOCAL_ELO_GRID, settings["pick_frac"], settings["pick_n"])
|
||||
if strategy == AI_TENUKI:
|
||||
elo = interp2d(AI_TENUKI_ELO_GRID, settings["pick_frac"], settings["pick_n"])
|
||||
if strategy == AI_TERRITORY:
|
||||
elo = interp2d(AI_TERRITORY_ELO_GRID, settings["pick_frac"], settings["pick_n"])
|
||||
if strategy == AI_INFLUENCE:
|
||||
elo = interp2d(AI_INFLUENCE_ELO_GRID, settings["pick_frac"], settings["pick_n"])
|
||||
|
||||
kyu = interp1d(CALIBRATED_RANK_ELO, elo)
|
||||
return 1 - kyu, True
|
||||
else:
|
||||
return AI_STRENGTH[strategy], False
|
||||
@@ -250,7 +281,7 @@ def generate_ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move,
|
||||
x_ai_thoughts = (
|
||||
f"Generated equal weights as move number >= {ai_settings['endgame'] * size[0] * size[1]}. "
|
||||
)
|
||||
n_moves = int(max(n_moves, 0.5 * len(legal_policy_moves)))
|
||||
n_moves = int(max(n_moves, len(legal_policy_moves) // 2))
|
||||
elif ai_mode in [AI_INFLUENCE, AI_TERRITORY]:
|
||||
weighted_coords, x_ai_thoughts = generate_influence_territory_weights(
|
||||
ai_mode, ai_settings, policy_grid, size
|
||||
|
||||
@@ -76,7 +76,7 @@ AI_OPTION_VALUES = {
|
||||
"opening_moves": range(0, 51),
|
||||
"pick_override": [0, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9, 0.95, 0.99, 1],
|
||||
"lower_bound": [(v, f"{v:.2%}") for v in [0, 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05]],
|
||||
"weaken_fac": [x/20 for x in range(10,3*20+1)],
|
||||
"weaken_fac": [x / 20 for x in range(10, 3 * 20 + 1)],
|
||||
"endgame": [x / 100 for x in range(10, 80, 5)],
|
||||
"pick_frac": [x / 100 for x in range(0, 101, 5)],
|
||||
"pick_n": range(0, 26),
|
||||
@@ -88,7 +88,8 @@ AI_OPTION_VALUES = {
|
||||
}
|
||||
AI_KEY_PROPERTIES = {"kyu_rank", "strength", "weaken_fac", "pick_frac", "pick_n", "automatic"}
|
||||
|
||||
CALIBRATED_RANK_ELO =[(39.36921298625589, 18),
|
||||
CALIBRATED_RANK_ELO = [
|
||||
(39.36921298625589, 18),
|
||||
(96.95581072853861, 17),
|
||||
(154.54240847082144, 16),
|
||||
(212.12900621310428, 15),
|
||||
@@ -109,7 +110,8 @@ CALIBRATED_RANK_ELO =[(39.36921298625589, 18),
|
||||
(1075.9279723473464, 0),
|
||||
(1133.5145700896292, -1),
|
||||
(1191.101167831912, -2),
|
||||
(1700,-4)]
|
||||
(1700, -4),
|
||||
]
|
||||
AI_WEIGHTED_ELO = [
|
||||
(0.5, 1591.4486833932992),
|
||||
(1.0, 1266.2591850212696),
|
||||
@@ -120,3 +122,55 @@ AI_WEIGHTED_ELO = [
|
||||
(2.5, 516.8371296455036),
|
||||
(3.0, 359.9621037249864),
|
||||
]
|
||||
|
||||
AI_LOCAL_ELO_GRID = [
|
||||
[0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0],
|
||||
[0, 5, 10, 15, 25, 50],
|
||||
[
|
||||
[200.0, 806.21655824, 1293.32037587, 1392.29465619, 1423.34086023, 1475.35678018, 1631.70997963, 1700.0],
|
||||
[271.88274382, 1177.38904493, 1357.48028947, 1427.89588231, 1471.76588449, 1531.66834985, 1700.0, 1700.0],
|
||||
[725.2189244, 1233.32342855, 1392.46449871, 1443.99394784, 1415.66026743, 1490.09450071, 1700.0, 1700.0],
|
||||
[986.18843485, 1315.19341299, 1423.36540576, 1438.78299774, 1499.2278826, 1570.46885902, 1700.0, 1700.0],
|
||||
[1334.16982939, 1401.31972528, 1430.66495587, 1450.4662417, 1510.77588056, 1575.68586904, 1700.0, 1700.0],
|
||||
[1388.06911342, 1451.04383633, 1391.07099726, 1500.84987644, 1520.43287013, 1700.0, 1700.0, 1700.0],
|
||||
],
|
||||
]
|
||||
|
||||
AI_TENUKI_ELO_GRID = [
|
||||
[0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0],
|
||||
[0, 5, 10, 15, 25, 50],
|
||||
[
|
||||
[100, 381.67199019, 614.9022033, 807.74726571, 972.75719068, 1081.59259337, 1280.81772836, 1700.0],
|
||||
[302.05524257, 447.16707419, 634.67443071, 847.73134951, 980.06971493, 1100.47221165, 1424.97514319, 1700.0],
|
||||
[395.99120046, 565.59284207, 707.35509522, 883.39067276, 997.20744208, 1125.50994832, 1392.10412559, 1700.0],
|
||||
[468.10121071, 660.65479606, 774.42716944, 862.84933335, 1010.69484968, 1156.68204921, 1436.80030417, 1700.0],
|
||||
[652.8285294, 753.57925069, 797.59399585, 898.99936585, 1042.96870256, 1222.48814041, 1470.92773923, 1700.0],
|
||||
[901.40390178, 910.28781658, 958.0281189, 1126.63475026, 1203.75546167, 1352.13779312, 1493.13435049, 1700.0],
|
||||
],
|
||||
]
|
||||
|
||||
AI_TERRITORY_ELO_GRID = [
|
||||
[0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0],
|
||||
[0, 5, 10, 15, 25, 50],
|
||||
[
|
||||
[0, 491.99354617, 652.54536499, 827.56438866, 997.07978087, 1207.47161931, 1461.93571907, 1700.0],
|
||||
[119.03096728, 554.30545095, 747.74695281, 852.1114908, 1049.58656646, 1250.72046036, 1475.72706895, 1700.0],
|
||||
[348.45765825, 589.16893663, 775.81559273, 909.21125406, 1073.92675377, 1300.11842657, 1485.95667768, 1700.0],
|
||||
[538.88999479, 676.21745434, 821.27037414, 950.58649838, 1126.1274156, 1358.9290967, 1500.00471917, 1700.0],
|
||||
[597.90794583, 741.3513872, 884.73016339, 972.54025369, 1150.30545203, 1430.55449307, 1566.81074945, 1700.0],
|
||||
[826.03134794, 997.58427811, 1093.54942758, 1214.9588177, 1336.40285376, 1485.32581091, 1700.0, 1700.0],
|
||||
],
|
||||
]
|
||||
|
||||
AI_INFLUENCE_ELO_GRID = [
|
||||
[0.0, 0.05, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0],
|
||||
[0, 5, 10, 15, 25, 50],
|
||||
[
|
||||
[75.9591829, 483.922460, 703.633297, 898.804165, 1041.90611, 1180.64701, 1500.22844, 1510.60242,],
|
||||
[285.94611, 598.87800, 673.848093, 866.826392, 1032.48205, 1334.284716, 1510.55098, 1520.774582,],
|
||||
[478.37028, 643.868326, 837.7348868, 945.3233087, 1093.119452, 1350.0936572, 1515.4939758, 1530.1492031,],
|
||||
[570.841325, 689.7079695, 848.3192009, 1021.7089457, 1143.3090057, 1371.453538, 1520.4852553, 1540.64105,],
|
||||
[749.495401, 771.144054, 865.13815, 1019.895054, 1107.959449, 1383.373536, 1525.298316, 1549.8151732,],
|
||||
[882.96911, 902.885106, 1057.305618, 1178.3968159, 1369.4749768, 1518.303563, 1530.772607, 1550.508035,],
|
||||
],
|
||||
]
|
||||
@@ -83,7 +83,7 @@ def rank_label(rank):
|
||||
if rank is None:
|
||||
return "??k"
|
||||
|
||||
if rank > 0:
|
||||
if rank >= 0.5:
|
||||
return f"{rank:.0f}{i18n._('strength:dan')}"
|
||||
else:
|
||||
return f"{1-rank:.0f}{i18n._('strength:kyu')}"
|
||||
@@ -6,7 +6,7 @@ from kivymd.uix.selectioncontrol import Thumb
|
||||
|
||||
|
||||
class SelectionSlider(Widget):
|
||||
__events__ = ["on_select","on_change"]
|
||||
__events__ = ["on_select", "on_change"]
|
||||
active = BooleanProperty(False)
|
||||
hint = BooleanProperty(True)
|
||||
|
||||
@@ -78,6 +78,7 @@ class SelectionSlider(Widget):
|
||||
def on_change(self, value):
|
||||
pass
|
||||
|
||||
|
||||
KV = """
|
||||
#:import i18n katrain.core.lang.i18n
|
||||
<SelectionSlider>:
|
||||
|
||||
Reference in new issue
Block a user