diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ctaklm.c | 2 | ||||
| -rw-r--r-- | src/pptdb.c | 2 | ||||
| -rw-r--r-- | src/train5.py | 60 |
3 files changed, 23 insertions, 41 deletions
diff --git a/src/ctaklm.c b/src/ctaklm.c index 3792cfa..68441c0 100644 --- a/src/ctaklm.c +++ b/src/ctaklm.c @@ -406,8 +406,6 @@ main(int argc, char **argv) { human = 0; new_game(5); - while (ct1986_turn(4) == 0); - char *line; for (int playing = 1; playing;) { while((human == 0) && (line = linenoise("ctaklm> ")) != NULL) { diff --git a/src/pptdb.c b/src/pptdb.c index 5358885..b1d91ce 100644 --- a/src/pptdb.c +++ b/src/pptdb.c @@ -105,7 +105,7 @@ parse_line(const char *pt, const ssize_t read) { } } // Generate training data, not too early in the game - if (generate && ply + 6 >= total_plies) { + if (generate && ply + 4 >= total_plies) { write_input(); fprintf(training_fh,"%d\n", outcome_black); } diff --git a/src/train5.py b/src/train5.py index c3fec82..5c45564 100644 --- a/src/train5.py +++ b/src/train5.py @@ -8,7 +8,8 @@ from tensorflow import transpose # Custom activation function from tensorflow import constant as k -from tensorflow.math import add, divide, maximum, minimum, multiply, square +from tensorflow import clip_by_value +from tensorflow.math import add, divide, multiply, square # Computing size from tensorflow.keras.backend import get_value @@ -23,28 +24,18 @@ from tensorflow.keras.layers import Flatten # We need something that's close to logistic, but cheaper to compute. -# (12.0+x+50.0*x/(x*x+10.0))/24.0, clamped between 0 and 1 +# (12.0+x+50.0*x/(x*x+10.0))/24.0, clipped between 0 and 1 # as it would otherwise exceed this range at +- 4.6 or so -def truncated_pade_logistic(x): +def clipped_pade_logistic(x): val = add(k(12.0), add(x, multiply(k(50.0), divide(x, add(square(x), k(10.0)))))) - return minimum(k(1.0), maximum(k(0.0), divide(val, k(24.0)))) - - -# A cheaper version of tanh, x/6+25*x/(6*(2*x*x+5)), -# clamped between -1 and 1. -def truncated_pade_tanh(x): - val = add(divide(x, k(6.0)), - multiply(k(25.0), - divide(x, multiply(k(6.0), add(k(5.0), - multiply(k(2.0), square(x))))))) - return minimum(k(1.0), maximum(k(-1.0), val)) + return clip_by_value(divide(val, k(24.0)), 0.0, 1.0) def make_model(size, magic=[12, 9, 9]): # Our model for the stacks, a small CNN - stack_shape = (size, size, 8) + stack_shape = (size, size, 6) stack_input = Input(shape=stack_shape) stack_model = Convolution2D(magic[0], kernel_size=(3, 3), strides=(1, 1), padding='valid', activation="relu", @@ -56,20 +47,17 @@ def make_model(size, magic=[12, 9, 9]): combn_input = Concatenate()([stack_model.output, flats_input]) model = Dense(magic[1], activation="relu", use_bias=True)(combn_input) model = Dense(magic[2], activation="relu", use_bias=True)(model) - model = Dense(1, activation=truncated_pade_logistic, use_bias=True)(model) + model = Dense(1, activation=clipped_pade_logistic, use_bias=True)(model) model = Model(inputs=[stack_model.input, flats_input], outputs=model) model.compile(optimizer='adam', - # loss='binary_crossentropy', - # loss='categorical_crossentropy', loss='mean_squared_error', - # loss='mean_absolute_error', metrics=['accuracy']) model.summary() return model def load_data(size): - shape = (-1, size, size, 8) + shape = (-1, size, size, 6) # Load training data tr_fn = "training-"+str(size)+".csv" training_csv = pd.read_csv(tr_fn) #.head(100000) @@ -96,11 +84,11 @@ def train(size, model, data, iterations=1, epochs=10): validation_data=(val_input, val_outcome), verbose=True) v_loss, v_accuracy = model.evaluate(val_input, val_outcome, - verbose=False) + verbose=False, batch_size=32) t_loss, t_accuracy = model.evaluate(training_input, training_outcome, - verbose=False) + verbose=False, batch_size=32) results += [((v_loss, t_loss), (v_accuracy, t_accuracy))] - return (results, model) + return results def model_size(model): @@ -109,25 +97,23 @@ def model_size(model): def magic_search(data): results = [] - for width in range(12, 16): - for dense1 in range(8, 24): - for dense2 in range(6, dense1+1): + for width in range(9, 18): + for dense1 in range(9, 16): + for dense2 in range(9, max(32, dense1*2)): m = make_model(5, [width, dense1, dense2]) - if model_size(m) <= 2000: + if model_size(m) < 1990: results += [([width, dense1, dense2], train(5, m, data, iterations=1, epochs=20))] print("\nSummary") for r in results: - print("Parameters {0}: {1}".format(r[0], r[1][0][-1:][0])) + print("Parameters {0}: {1}".format(r[0], r[1][0])) return results def write_weights(model): - def fix(string): + def fix(val): + string = str(val.tolist()) string = string.replace("[", "{").replace("]", "}") - string = re.sub(r'}\n', '},\n', string) - string = re.sub(r'([0-9]+)\n', r'\1,\n', string) - string = re.sub(r'([0-9]+) ', r'\1, ', string) return string # Prepare everything in a sane memory order conv2d_weights = np.array(transpose(model.trainable_variables[0], perm=[3, 1, 0, 2])) @@ -152,20 +138,18 @@ def write_weights(model): dense2_weights, dense2_biases, output_weights, output_bias] # Write to file - f = open("weights.c", "w") + f = open("weights.txt", "w") f.write("#include \"weights.h\"\n\n") for (name, val) in zip(names, variables): - f.write("const float "+name+" =\n"+fix(str(val))+";\n\n") + f.write("const float "+name+" =\n"+fix(val)+";\n\n") f.close() data = load_data(5) model = make_model(5, [12, 9, 10]) -results, model = train(5, model, data, iterations=1, epochs=10) +results = train(5, model, data, iterations=20, epochs=10) print("\nScores") for i in range(len(results)): - print("Iteration {0}: {1}".format(i+1, results[i])) + print("Iteration {0}: {1}".format(i+1, results[i])) write_weights(model) - -#results = magic_search(data) |
