aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/match.c60
-rwxr-xr-xsrc/nn_train.py27
2 files changed, 35 insertions, 52 deletions
diff --git a/src/match.c b/src/match.c
index 94afe48..6ae9fa7 100644
--- a/src/match.c
+++ b/src/match.c
@@ -57,10 +57,6 @@ static inline float six_cand(tak_state_p state) {
static tak_state_p state;
-// ===================================================================
-// negamax progress hook (silent)
-// ===================================================================
-
void negamax_display_progress(const uint8_t cur_depth,
const uint8_t init_depth,
const uint32_t length) {
@@ -116,11 +112,34 @@ static int play_game(const nn_function current_fn, const nn_function cand_fn,
}
}
-// ===================================================================
-// Main
-// ===================================================================
+void do_game(const uint8_t size, const uint8_t random_opening_length, const enum COLOUR current_fn_colour) {
+ state = new_tak_state(size);
+ negamax_init(size);
+
+ const nn_function current_fn =
+ (size == 5) ? &five_nn_fn : &six_nn_fn;
+ const nn_function cand_fn = (size == 5) ? &five_cand : &six_cand;
+
+ const int winner = play_game(current_fn, cand_fn, current_fn_colour, random_opening_length);
-const char *usage =
+ const char *name;
+ if (winner == -1)
+ name = "draw";
+ else if (winner == (int)current_fn_colour)
+ name = "current";
+ else
+ name = "candidate";
+ printf("%s %u\n", name, state->ply);
+
+ negamax_free();
+ free_tak_state(state);
+}
+
+ // ===================================================================
+ // Main
+ // ===================================================================
+
+ const char *usage =
"match, one Tak game of the current weights against the candidate.\n\n\
usage: match <size> <random_opening_length> <depth>\n\n\
This binary is linked with both the include/weight_* files and the include/cand_weight_* files. It plays a single <size>x<size> game, with a random side choice and both sides using <random_opening_length> random moves at the start of the game. The result format is:\n\n\
@@ -147,29 +166,8 @@ int main(int argc, char **argv) {
0x9E3779B97F4A7C15ULL +
0xC0FFEE;
- state = new_tak_state(size);
- negamax_init(size);
-
- const nn_function current_fn =
- (size == 5) ? &five_nn_fn : &six_nn_fn;
- const nn_function cand_fn =
- (size == 5) ? &five_cand
- : &six_cand;
-
- const enum COLOUR current_fn_colour = rand32() % 2 ? C_WHITE : C_BLACK;
- const int winner = play_game(current_fn, cand_fn, current_fn_colour, random_opening_length);
-
- const char *name;
- if (winner == -1)
- name = "draw";
- else if (winner == (int)current_fn_colour)
- name = "current";
- else
- name = "candidate";
- printf("%s %u\n", name, state->ply);
-
- negamax_free();
- free_tak_state(state);
+ do_game(size, random_opening_length, C_BLACK);
+ do_game(size, random_opening_length, C_WHITE);
return EXIT_SUCCESS;
}
diff --git a/src/nn_train.py b/src/nn_train.py
index cde7a98..8f1a73e 100755
--- a/src/nn_train.py
+++ b/src/nn_train.py
@@ -201,8 +201,7 @@ class SelfPlayRecords:
class Net(Module):
def __init__(self, inp_dim: int, hidden: int) -> None:
super().__init__()
- # learned 7-way cell-state embedding (empty, {black, white} x
- # {flat, standing, road}); the slot layout must match nn.c
+ # learned cell-state embedding, see nn.c
self.embedding = Embedding(7, 1)
self.hidden = Linear(inp_dim, hidden, bias=True)
self.output = Linear(hidden, 1, bias=True)
@@ -302,7 +301,7 @@ class Net(Module):
_ = f.write(f"/* {p} */\n")
_ = f.write(f'#include "weights_{size}.h"\n\n')
_ = f.write(
- f"const float {prefix}_embedding[7] =\n"
+ f"const float {prefix}_embedding[{len(E)}] =\n"
f"{{\n{_fmt_flat(E, per_line=7)}\n}};\n\n"
)
_ = f.write(
@@ -548,24 +547,6 @@ def main() -> None:
help="number of previous self-play instances to mix in with current dataset during training",
)
_ = p.add_argument(
- "--eps-start",
- type=float,
- default=0.15,
- help="initial self-play epsilon: in asymmetric self-play one side (chosen at random per game) plays a uniform random move with this probability while the greedy side has its plies recorded",
- )
- _ = p.add_argument(
- "--eps-min",
- type=float,
- default=0.01,
- help="self-play epsilon floor",
- )
- _ = p.add_argument(
- "--eps-decay",
- type=float,
- default=0.9,
- help="per-iteration epsilon decay",
- )
- _ = p.add_argument(
"--td-lambda",
type=float,
default=0.7,
@@ -639,6 +620,10 @@ def main() -> None:
(root / "data").mkdir(exist_ok=True)
champ = setup(size=args.size, root=root)
+
+ num_params = sum(p.numel() for p in champ.parameters() if p.requires_grad)
+ print(f"Number of trainable parameters: {num_params:,}")
+
for iter in range(1, args.iters + 1):
champ = run_step(
batch=args.batch,