diff options
| author | tslil <tslil@posteo.de> | 2021-01-08 00:54:07 -0500 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-08-28 19:37:41 +0100 |
| commit | e8315ed893157a87c8f2c3935667ffcc97b2c95e (patch) | |
| tree | 241b278b206e36683707921d609b08516c5295f6 | |
| parent | 27c0576e25226dc75636c372aff3c0818af03201 (diff) | |
Closing in on something reasonable for roads
| -rwxr-xr-x | extract.sh | 2 | ||||
| -rw-r--r-- | src/pptdb.c | 69 | ||||
| -rw-r--r-- | src/train5.py | 84 |
3 files changed, 100 insertions, 55 deletions
@@ -47,4 +47,4 @@ fi make pptdb -process 5000 +process 20000 diff --git a/src/pptdb.c b/src/pptdb.c index 5e49c26..92155b5 100644 --- a/src/pptdb.c +++ b/src/pptdb.c @@ -9,38 +9,61 @@ uint64_t heights[16]; int result, generate; FILE *training_fh = NULL; +const int max_depth = 8; + static void write_input(void) { // Whose turn is it? /* fprintf(training_fh,"%d,",current_colour == C_BLACK); */ + // Two numbers for flats remaining /* fprintf(training_fh,"%.6f,%.6f,", */ /* (float)(white_count & 127)/max_flats, */ /* (float)(black_count & 127)/max_flats); */ // Two data points for each square - float t; uint16_t mask; + /* float t; uint16_t mask; */ + + float val; + uint16_t mask = 1; + for (int k = 0; k < board_size * board_size; k++) { + val = 0; + if (COUNT_AT(k)>0) { + if (STONE_AT(k) == STONE_STANDING) { + val = (colours[k] & mask) ? +0.25 : -0.25; + } else if (STONE_AT(k) == STONE_CAPSTONE) { + val = (colours[k] & mask) ? +1.00 : -1.00; + } else { + val = (colours[k] & mask) ? +0.50 : -0.50; + } + } + fprintf(training_fh,"%.2f,", val); + } + + for (int depth = 1; depth < max_depth; depth++) { + for (int k = 0; k < board_size * board_size; k++) { + val = 0; + if (COUNT_AT(k)>depth) val = (colours[k] & mask) ? +0.50 : -0.50; + fprintf(training_fh,"%.2f,", val); + } + mask <<= 1; + } + + /* + float t; for (int k = 0; k < board_size * board_size; k++) { - const int h = COUNT_AT(k); // stacks encoded as balanced ternary + const int h = COUNT_AT(k); t = 0; - mask = 1<<(h-1); - for (int j = 0; j < h; j++) { + mask = 1<<h; + for (int j = 1; j < h; j++) { t += (colours[k] & mask) ? +1 : -1; - t /= 3; + t /= 3.0; mask >>=1; } - // top stone in [-1, +1] ordered as |standing| < |flat| < |cap| - /* val = 0; */ - /* if (COUNT_AT(k)) { */ - /* if (STONE_AT(k) == STONE_STANDING) val = (colours[k] & 1) ? +1/4 : -1/4; */ - /* else if (STONE_AT(k) == STONE_CAPSTONE) val = (colours[k] & 1) ? +1.0 : -1.0; */ - /* else val = (colours[k] & 1) ? +1/2 : -1/2; */ - /* } */ - fprintf(training_fh,"%.8f,", - t*2); - /* (h > 0) ? ((colours[k] & 2) ? +2/3 : -2/3) : 0.0, */ - /* val */ + fprintf(training_fh,"%.8f,",2*t); } + */ + } // Warning: performs _no_ checks on input whatsoever @@ -99,7 +122,7 @@ parse_line(const char *pt, const ssize_t read) { } } // Generate training data, not too early in the game - if (generate && ply > 10) { + if (generate && current_colour == C_BLACK && ply > 15) { write_input(); fprintf(training_fh,"%d,%d\n", result, 1-result); } @@ -140,9 +163,19 @@ main(int argc, char **argv) { if (training_fh == NULL) exit(EXIT_FAILURE); // Write header /* fputs("\"Player\",\"White flats\",\"Black flats\",",training_fh); */ + + for (int depth = 0; depth < max_depth; depth++) { + for (int k = 0; k < size*size; k++) { + fprintf(training_fh,"\"Stack %d %d\",",depth,k); + } + } + + /* for (int k = 0; k < size*size; k++) { - fprintf(training_fh,"\"Stack %d\",",k); + fprintf(training_fh,"\"BT %d\",",k); } + */ + fputs("\"White win\",\"Black win\"\n",training_fh); } else generate=0; diff --git a/src/train5.py b/src/train5.py index 3718fd0..ea25e5e 100644 --- a/src/train5.py +++ b/src/train5.py @@ -1,53 +1,65 @@ -import tensorflow as tf import pandas as pd import numpy as np +from tensorflow.keras.regularizers import l1 +from tensorflow.keras.regularizers import l2 + +import tensorflow.keras.losses + from tensorflow.keras.models import Sequential -from tensorflow.keras.layers import BatchNormalization -from tensorflow.keras.layers import Conv2D -from tensorflow.keras.layers import MaxPooling2D -from tensorflow.keras.layers import Activation -from tensorflow.keras.layers import Flatten from tensorflow.keras.layers import Dropout +from tensorflow.keras.layers import Input from tensorflow.keras.layers import Dense +from tensorflow.keras.layers import Convolution2D +from tensorflow.keras.layers import MaxPooling2D +from tensorflow.keras.layers import Flatten +from tensorflow.keras.layers import Activation +from tensorflow.keras.layers import BatchNormalization + +# 30 10(11) 5 +# 27 17 4 + +shape = (-1, 5, 5, 8) model = Sequential([ - # Conv2D(5, kernel_size=5, padding='same', input_shape=(5, 5, 2)), - # MaxPooling2D(pool_size=2, strides=2), - # Activation("relu"), - # Flatten(), - # Dense(25, activation="relu"), - # Dense(10, activation="relu"), - # Dense(1, activation="sigmoid") - - Dense(30, activation="relu", input_shape=(52,)), # 30 - Dense(10, activation="relu"), # 10 - Dense(8, activation="relu"), # 8 - Dense(1, activation="sigmoid") + Input(shape[1:]), + Convolution2D(1, kernel_size=3, strides=(1, 1), + padding='same', + activation="relu", use_bias=True), + # Dropout(0.2), + Flatten(), + Dense(10, activation="relu", use_bias=True), + # Dropout(0.2), + # Dense(10, activation="relu", use_bias=False), + # Dropout(0.2), + Dense(2, activation="softmax") ]) -model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) + # bias_regularizer=l2(0.001), + # kernel_regularizer=l1(0.001)), -model.summary() +model.compile(loss='categorical_crossentropy', + optimizer='adam', + metrics=['accuracy']) -csv = pd.read_csv("data/train5.csv") +model.summary() -training_data = csv.copy().head(40000) -training_outcome = training_data.pop('Outcome') +csv = pd.read_csv("training-5.csv") -training_input = training_data.copy() -# training_input = training_input.drop(columns=training_data.keys()[0:2]) -train = np.array(training_input) -# train = train.reshape((training_input.shape[0], 5, 5, 2)) +training_data = csv.head(100000).copy() +training_input = np.array(training_data.iloc[:, :-2]).reshape(shape) +training_outcome = training_data.iloc[:, -2:] -model.fit(train, training_outcome, epochs=100) +test_data = csv.tail(20000).copy() +test_input = np.array(test_data.iloc[:, :-2]).reshape(shape) +test_outcome = test_data.iloc[:, -2:] -test_data = csv.copy().tail(50000) -# test_data = test_data.drop(columns=test_data.keys()[0:2]) -test_outcome = test_data.pop('Outcome') -test_input = np.array(test_data) -# test_input = test_input.reshape((test_data.shape[0], 5, 5, 2)) -test_loss, test_acc = model.evaluate(test_input, test_outcome, verbose=2) -print('\nTest accuracy:', test_acc) +results = [] +for i in range(0, 1): + print("Iteration ", i) + history = model.fit(training_input, training_outcome, epochs=10, + validation_data=(test_input, test_outcome)) + loss, accuracy = model.evaluate(test_input, test_outcome) + results += [(i, loss, accuracy)] -# Test accuracy: 0.67448 +print("\n\nResults: ", results) |
