teacher
This commit is contained in:
1 parent
b188f233f2
commit
1b36710eda
8 files changed
+129
-26
No files matched your search
@@ -58,7 +58,9 @@ def ai_move(game: Game, ai_mode: str, ai_settings: Dict) -> Tuple[Move, GameNode
|
|||||||
weighted_coords = [(policy_grid[y][x], policy_grid[y][x], x, y) for x in range(size[0]) for y in range(size[1]) if policy_grid[y][x] > 0]
|
weighted_coords = [(policy_grid[y][x], policy_grid[y][x], x, y) for x in range(size[0]) for y in range(size[1]) if policy_grid[y][x] > 0]
|
||||||
best = weighted_selection_without_replacement(weighted_coords, 1)[0]
|
best = weighted_selection_without_replacement(weighted_coords, 1)[0]
|
||||||
aimove = Move(best[2:], player=cn.next_player) # just take a random move by policy w/o noise
|
aimove = Move(best[2:], player=cn.next_player) # just take a random move by policy w/o noise
|
||||||
ai_thoughts += f"Playing policy-weighted random move {aimove.gtp()} ({best[0]:.1%})" + (" because one of them is pass." if top_5_pass else " because strategy is weighted.")
|
ai_thoughts += f"Playing policy-weighted random move {aimove.gtp()} ({best[0]:.1%})" + (
|
||||||
|
" because one of them is pass." if top_5_pass else " because strategy is weighted."
|
||||||
|
)
|
||||||
elif "noise" in ai_mode:
|
elif "noise" in ai_mode:
|
||||||
noise_str = ai_settings["noise_strength"]
|
noise_str = ai_settings["noise_strength"]
|
||||||
d_noise = dirichlet_noise(len(legal_policy_moves))
|
d_noise = dirichlet_noise(len(legal_policy_moves))
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ while not game.ended:
|
|||||||
logger.log(f"Setting komi {game.root.properties}", OUTPUT_ERROR)
|
logger.log(f"Setting komi {game.root.properties}", OUTPUT_ERROR)
|
||||||
elif "genmove" in line:
|
elif "genmove" in line:
|
||||||
game.current_node.analyze(engine)
|
game.current_node.analyze(engine)
|
||||||
game.root.add_property(f"P{game.current_node.next_player}", f"KaTrain {ai_strategy}")
|
game.root.properties[f"P{game.current_node.next_player}"] = [f"KaTrain {ai_strategy}"]
|
||||||
move, node = ai_move(game, ai_strategy, ai_settings)
|
move, node = ai_move(game, ai_strategy, ai_settings)
|
||||||
logger.log(f"SENT TO GTP: = {move.gtp()}", OUTPUT_ERROR)
|
logger.log(f"SENT TO GTP: = {move.gtp()}", OUTPUT_ERROR)
|
||||||
print(f"= {move.gtp()}\n")
|
print(f"= {move.gtp()}\n")
|
||||||
|
|||||||
+9
-7
@@ -25,6 +25,7 @@
|
|||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
0.5,
|
0.5,
|
||||||
|
0,
|
||||||
0
|
0
|
||||||
],
|
],
|
||||||
"eval_thresholds": [
|
"eval_thresholds": [
|
||||||
@@ -32,7 +33,8 @@
|
|||||||
6,
|
6,
|
||||||
3,
|
3,
|
||||||
1.5,
|
1.5,
|
||||||
0.5
|
0.5,
|
||||||
|
0
|
||||||
],
|
],
|
||||||
"eval_off_show_last": 3,
|
"eval_off_show_last": 3,
|
||||||
"eval_show_ai": false
|
"eval_show_ai": false
|
||||||
@@ -112,32 +114,32 @@
|
|||||||
[
|
[
|
||||||
0.447,
|
0.447,
|
||||||
0.129,
|
0.129,
|
||||||
0.42
|
0.42,1
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
0.8,
|
0.8,
|
||||||
0,
|
0,
|
||||||
0
|
0,1
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
0.9,
|
0.9,
|
||||||
0.4,
|
0.4,
|
||||||
0.1
|
0.1,1
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
0.85,
|
0.85,
|
||||||
0.89,
|
0.89,
|
||||||
0.3
|
0.3,1
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
0.67,
|
0.67,
|
||||||
0.9,
|
0.9,
|
||||||
0.18
|
0.18,1
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
0.117,
|
0.117,
|
||||||
0.588,
|
0.588,
|
||||||
0
|
0,1
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"line_color": [
|
"line_color": [
|
||||||
|
|||||||
+7
-1
@@ -3,7 +3,7 @@ from kivy.graphics.vertex_instructions import Line, SmoothLine
|
|||||||
from kivy.uix.boxlayout import BoxLayout
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
from kivy.uix.popup import Popup
|
from kivy.uix.popup import Popup
|
||||||
|
|
||||||
from gui.popups import ConfigAIPopup
|
from gui.popups import ConfigAIPopup, ConfigTeacherPopup
|
||||||
|
|
||||||
|
|
||||||
class Controls(BoxLayout):
|
class Controls(BoxLayout):
|
||||||
@@ -79,3 +79,9 @@ class Controls(BoxLayout):
|
|||||||
popup_contents = ConfigAIPopup(self.katrain, config_popup, {self.ai_mode("B"), self.ai_mode("W")})
|
popup_contents = ConfigAIPopup(self.katrain, config_popup, {self.ai_mode("B"), self.ai_mode("W")})
|
||||||
config_popup.add_widget(popup_contents)
|
config_popup.add_widget(popup_contents)
|
||||||
config_popup.open()
|
config_popup.open()
|
||||||
|
|
||||||
|
def configure_teacher(self):
|
||||||
|
config_popup = Popup(title="Edit Teacher Settings", size_hint=(0.6, 0.8))
|
||||||
|
popup_contents = ConfigTeacherPopup(self.katrain, config_popup)
|
||||||
|
config_popup.add_widget(popup_contents)
|
||||||
|
config_popup.open()
|
||||||
@@ -15,6 +15,7 @@ from kivy.uix.gridlayout import GridLayout
|
|||||||
from kivy.uix.label import Label
|
from kivy.uix.label import Label
|
||||||
from kivy.uix.spinner import Spinner
|
from kivy.uix.spinner import Spinner
|
||||||
from kivy.uix.textinput import TextInput
|
from kivy.uix.textinput import TextInput
|
||||||
|
from kivy.uix.widget import Widget
|
||||||
|
|
||||||
|
|
||||||
class DarkLabel(Label):
|
class DarkLabel(Label):
|
||||||
@@ -29,6 +30,14 @@ class LightHelpLabel(ScaledLightLabel):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BackgroundColor(Widget):
|
||||||
|
background = ListProperty([1, 1, 1, 0])
|
||||||
|
|
||||||
|
|
||||||
|
class BackgroundLabel(Label, BackgroundColor):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class StyledButton(Button):
|
class StyledButton(Button):
|
||||||
button_color = ListProperty([])
|
button_color = ListProperty([])
|
||||||
button_color_down = ListProperty([])
|
button_color_down = ListProperty([])
|
||||||
|
|||||||
+82
-5
@@ -9,15 +9,16 @@ from common import OUTPUT_DEBUG, OUTPUT_ERROR
|
|||||||
from engine import KataGoEngine
|
from engine import KataGoEngine
|
||||||
from game import Game, GameNode
|
from game import Game, GameNode
|
||||||
from gui.kivyutils import (
|
from gui.kivyutils import (
|
||||||
|
BackgroundLabel,
|
||||||
LabelledCheckBox,
|
LabelledCheckBox,
|
||||||
LabelledFloatInput,
|
LabelledFloatInput,
|
||||||
LabelledIntInput,
|
LabelledIntInput,
|
||||||
LabelledObjectInputArea,
|
LabelledObjectInputArea,
|
||||||
LabelledSpinner,
|
LabelledSpinner,
|
||||||
LabelledTextInput,
|
LabelledTextInput,
|
||||||
|
LightHelpLabel,
|
||||||
ScaledLightLabel,
|
ScaledLightLabel,
|
||||||
StyledButton,
|
StyledButton,
|
||||||
LightHelpLabel,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -171,15 +172,15 @@ class ConfigPopup(QuickConfigGui):
|
|||||||
|
|
||||||
class ConfigAIPopup(QuickConfigGui):
|
class ConfigAIPopup(QuickConfigGui):
|
||||||
def __init__(self, katrain, popup, ai_modes, **kwargs):
|
def __init__(self, katrain, popup, ai_modes, **kwargs):
|
||||||
super().__init__(katrain, popup, katrain.ai_settings, **kwargs)
|
self.settings = self.katrain.config("ai")
|
||||||
self.settings = self.katrain.ai_settings
|
super().__init__(katrain, popup, self.settings, **kwargs)
|
||||||
self.ai_modes = ai_modes
|
self.ai_modes = ai_modes
|
||||||
Clock.schedule_once(self._build, 0)
|
Clock.schedule_once(self._build, 0)
|
||||||
self.orientation = "vertical"
|
self.orientation = "vertical"
|
||||||
|
|
||||||
def _build(self, _dt):
|
def _build(self, _dt):
|
||||||
colbox = BoxLayout(spacing=5)
|
colbox = BoxLayout(spacing=5)
|
||||||
for mode in self.ai_modes:
|
for i, mode in enumerate(self.ai_modes):
|
||||||
mode_settings = self.settings[mode]
|
mode_settings = self.settings[mode]
|
||||||
num_rows = len(mode_settings) - 2
|
num_rows = len(mode_settings) - 2
|
||||||
column = GridLayout(cols=2, rows=max(num_rows, 4) + 3, spacing=1, padding=3)
|
column = GridLayout(cols=2, rows=max(num_rows, 4) + 3, spacing=1, padding=3)
|
||||||
@@ -195,9 +196,14 @@ class ConfigAIPopup(QuickConfigGui):
|
|||||||
column.add_widget(ScaledLightLabel(text=f""))
|
column.add_widget(ScaledLightLabel(text=f""))
|
||||||
column.add_widget(ScaledLightLabel(text=f""))
|
column.add_widget(ScaledLightLabel(text=f""))
|
||||||
colbox.add_widget(column)
|
colbox.add_widget(column)
|
||||||
|
if i == 0:
|
||||||
|
colbox.add_widget(BackgroundLabel(text=f"", size_hint=(0.02, 1), background=(1, 1, 1, 1)))
|
||||||
|
|
||||||
if len(self.ai_modes) == 1:
|
if len(self.ai_modes) == 1:
|
||||||
colbox.add_widget(ScaledLightLabel(text=f""))
|
colbox.add_widget(ScaledLightLabel(text=f""))
|
||||||
|
self.info_label = Label()
|
||||||
bl = BoxLayout(size_hint=(1, 0.2), spacing=2)
|
bl = BoxLayout(size_hint=(1, 0.2), spacing=2)
|
||||||
|
bl.add_widget(self.info_label)
|
||||||
bl.add_widget(StyledButton(text=f"Apply", on_press=lambda _: self.update_config(False)))
|
bl.add_widget(StyledButton(text=f"Apply", on_press=lambda _: self.update_config(False)))
|
||||||
bl.add_widget(StyledButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True)))
|
bl.add_widget(StyledButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True)))
|
||||||
self.add_widget(colbox)
|
self.add_widget(colbox)
|
||||||
@@ -207,10 +213,81 @@ class ConfigAIPopup(QuickConfigGui):
|
|||||||
try:
|
try:
|
||||||
for k, v in self.collect_properties(self).items():
|
for k, v in self.collect_properties(self).items():
|
||||||
k1, k2 = k.split("/")
|
k1, k2 = k.split("/")
|
||||||
print(k1, k2, v, self.settings[k1][k2])
|
self.settings[k1][k2] = v
|
||||||
if self.settings[k1][k2] != v:
|
if self.settings[k1][k2] != v:
|
||||||
self.katrain.log(f"Updating setting {k} = {v}", OUTPUT_DEBUG)
|
self.katrain.log(f"Updating setting {k} = {v}", OUTPUT_DEBUG)
|
||||||
|
if save_to_file:
|
||||||
|
self.katrain.save_config()
|
||||||
|
self.popup.dismiss()
|
||||||
|
except InputParseError as e:
|
||||||
|
self.info_label.text = str(e)
|
||||||
|
self.katrain.log(e, OUTPUT_ERROR)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.popup.dismiss()
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigTeacherPopup(QuickConfigGui):
|
||||||
|
def __init__(self, katrain, popup, **kwargs):
|
||||||
|
self.settings = katrain.config("trainer")
|
||||||
|
self.ui_settings = katrain.config("board_ui")
|
||||||
|
super().__init__(katrain, popup, self.settings, **kwargs)
|
||||||
|
Clock.schedule_once(self._build, 0)
|
||||||
|
self.orientation = "vertical"
|
||||||
|
self.spacing = 2
|
||||||
|
|
||||||
|
def _build(self, _dt):
|
||||||
|
thresholds = self.settings["eval_thresholds"]
|
||||||
|
undos = self.settings["num_undo_prompts"]
|
||||||
|
colors = self.ui_settings["eval_colors"]
|
||||||
|
thrbox = GridLayout(spacing=1, padding=2, cols=4, rows=len(thresholds) + 1)
|
||||||
|
thrbox.add_widget(ScaledLightLabel(text="Point loss greater than", bold=True))
|
||||||
|
thrbox.add_widget(ScaledLightLabel(text="Gives this many undos", bold=True))
|
||||||
|
thrbox.add_widget(ScaledLightLabel(text="Color (fixed)", bold=True))
|
||||||
|
thrbox.add_widget(ScaledLightLabel(text="Visibility (0=hidden)", bold=True))
|
||||||
|
|
||||||
|
for i, (thr, undos, color) in enumerate(zip(thresholds, undos, colors)):
|
||||||
|
thrbox.add_widget(LabelledFloatInput(text=str(thr), input_property=f"threshold::{i}"))
|
||||||
|
thrbox.add_widget(LabelledFloatInput(text=str(undos), input_property=f"undo::{i}"))
|
||||||
|
thrbox.add_widget(BackgroundLabel(background=color[:3]))
|
||||||
|
thrbox.add_widget(LabelledFloatInput(text=str(color[3]), input_property=f"alpha::{i}"))
|
||||||
|
|
||||||
|
self.add_widget(thrbox)
|
||||||
|
|
||||||
|
xsettings = BoxLayout(size_hint=(1, 0.15), spacing=2)
|
||||||
|
xsettings.add_widget(ScaledLightLabel(text="Show last <n> dots"))
|
||||||
|
xsettings.add_widget(LabelledIntInput(size_hint=(0.5,1), text=str(self.settings['eval_off_show_last']),input_property = "eval_off_show_last" ))
|
||||||
|
self.add_widget(xsettings)
|
||||||
|
xsettings = BoxLayout(size_hint=(1, 0.15), spacing=2)
|
||||||
|
xsettings.add_widget(ScaledLightLabel(text="Show dots for AI players"))
|
||||||
|
xsettings.add_widget(LabelledCheckBox(size_hint=(0.5,1), text=str(self.settings['eval_show_ai']),input_property = "eval_show_ai" ))
|
||||||
|
self.add_widget(xsettings)
|
||||||
|
|
||||||
|
bl = BoxLayout(size_hint=(1, 0.2), spacing=2)
|
||||||
|
bl.add_widget(StyledButton(text=f"Apply", on_press=lambda _: self.update_config(False)))
|
||||||
|
bl.add_widget(StyledButton(text=f"Apply and Save", on_press=lambda _: self.update_config(True)))
|
||||||
|
self.add_widget(bl)
|
||||||
|
|
||||||
|
def update_config(self, save_to_file=False):
|
||||||
|
try:
|
||||||
|
for k, v in self.collect_properties(self).items():
|
||||||
|
if '::' in k:
|
||||||
|
k1, i = k.split("::")
|
||||||
|
i=int(i)
|
||||||
|
if 'alpha' not in k1:
|
||||||
|
if self.settings[k1][i] != v:
|
||||||
|
self.settings[k1][i] = v
|
||||||
|
self.katrain.log(f"Updating setting {k1}[{i}] = {v}", OUTPUT_DEBUG)
|
||||||
|
else:
|
||||||
|
if self.ui_settings['eval_colors'][i][3] != v:
|
||||||
|
self.katrain.log(f"Updating alpha {i} = {v}", OUTPUT_DEBUG)
|
||||||
|
self.ui_settings['eval_colors'][i][3] = v
|
||||||
|
else:
|
||||||
|
if self.settings[k] != v:
|
||||||
|
self.settings[k] = v
|
||||||
|
self.katrain.log(f"Updating setting {k} = {v}", OUTPUT_DEBUG)
|
||||||
|
if save_to_file:
|
||||||
|
pass
|
||||||
self.popup.dismiss()
|
self.popup.dismiss()
|
||||||
except InputParseError as e:
|
except InputParseError as e:
|
||||||
self.info_label.text = str(e)
|
self.info_label.text = str(e)
|
||||||
|
|||||||
+15
-7
@@ -11,6 +11,16 @@
|
|||||||
#:set WHITE [0.95,0.95,0.95,1]
|
#:set WHITE [0.95,0.95,0.95,1]
|
||||||
#:set GREY [0.5,0.5,0.5,1]
|
#:set GREY [0.5,0.5,0.5,1]
|
||||||
|
|
||||||
|
|
||||||
|
<BackgroundColor>:
|
||||||
|
canvas.before:
|
||||||
|
Color:
|
||||||
|
rgb: root.background
|
||||||
|
Rectangle:
|
||||||
|
pos: self.pos
|
||||||
|
size: self.size
|
||||||
|
|
||||||
|
|
||||||
<StyledButton>:
|
<StyledButton>:
|
||||||
color: WHITE
|
color: WHITE
|
||||||
font_size: self.size[1] * 0.45
|
font_size: self.size[1] * 0.45
|
||||||
@@ -475,17 +485,15 @@
|
|||||||
on_text: if W_player_mode.children: W_player_mode.children[0].trigger_action(duration=0)
|
on_text: if W_player_mode.children: W_player_mode.children[0].trigger_action(duration=0)
|
||||||
BoxLayout:
|
BoxLayout:
|
||||||
size_hint: 1,0.05
|
size_hint: 1,0.05
|
||||||
padding: 1
|
padding: 5,0
|
||||||
spacing: 1
|
spacing: 1
|
||||||
Label:
|
StyledButton:
|
||||||
size_hint: 0.55,1
|
text: 'Configure Teacher'
|
||||||
|
on_press: root.configure_teacher()
|
||||||
|
size_hint: 1.33, 1
|
||||||
StyledButton:
|
StyledButton:
|
||||||
text: 'Configure AIs'
|
text: 'Configure AIs'
|
||||||
on_press: root.configure_ais()
|
on_press: root.configure_ais()
|
||||||
size_hint: 0.44,1
|
|
||||||
Label:
|
|
||||||
size_hint: None,1
|
|
||||||
width: 3
|
|
||||||
LargeLabel:
|
LargeLabel:
|
||||||
text: ''
|
text: ''
|
||||||
size_hint: 1,0.2
|
size_hint: 1,0.2
|
||||||
|
|||||||
+3
-4
@@ -38,8 +38,7 @@ class KaTrainGui(BoxLayout):
|
|||||||
self._load_config()
|
self._load_config()
|
||||||
|
|
||||||
self.debug_level = self.config("debug/level", OUTPUT_INFO)
|
self.debug_level = self.config("debug/level", OUTPUT_INFO)
|
||||||
self.ai_settings = self.config("ai")
|
self.controls.ai_mode_groups["W"].values = self.controls.ai_mode_groups["B"].values = self.config("ai").keys()
|
||||||
self.controls.ai_mode_groups["W"].values = self.controls.ai_mode_groups["B"].values = self.ai_settings.keys()
|
|
||||||
self.message_queue = Queue()
|
self.message_queue = Queue()
|
||||||
|
|
||||||
self._keyboard = Window.request_keyboard(None, self, "")
|
self._keyboard = Window.request_keyboard(None, self, "")
|
||||||
@@ -145,7 +144,7 @@ class KaTrainGui(BoxLayout):
|
|||||||
def _do_ai_move(self, node=None):
|
def _do_ai_move(self, node=None):
|
||||||
if node is None or self.game.current_node == node:
|
if node is None or self.game.current_node == node:
|
||||||
mode = self.controls.ai_mode(self.game.current_node.next_player)
|
mode = self.controls.ai_mode(self.game.current_node.next_player)
|
||||||
settings = self.ai_settings[mode]
|
settings = self.config("ai/mode")
|
||||||
if settings:
|
if settings:
|
||||||
ai_move(self.game, mode, settings)
|
ai_move(self.game, mode, settings)
|
||||||
|
|
||||||
@@ -193,7 +192,7 @@ class KaTrainGui(BoxLayout):
|
|||||||
|
|
||||||
def _do_config_popup(self):
|
def _do_config_popup(self):
|
||||||
config_popup = Popup(title="Edit Settings", size_hint=(0.9, 0.9))
|
config_popup = Popup(title="Edit Settings", size_hint=(0.9, 0.9))
|
||||||
popup_contents = ConfigPopup(self, config_popup, dict(self._config), ignore_cats=("board_ui", "ai"))
|
popup_contents = ConfigPopup(self, config_popup, dict(self._config), ignore_cats=("trainer", "ai"))
|
||||||
config_popup.add_widget(popup_contents)
|
config_popup.add_widget(popup_contents)
|
||||||
config_popup.open()
|
config_popup.open()
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user