summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ct1975.c (renamed from include/ct1973.c)22
-rw-r--r--include/ct1975.h (renamed from include/ct1973.h)1
-rw-r--r--include/weights.h7
-rw-r--r--src/ctaklm.c2
-rw-r--r--src/train5.py91
5 files changed, 71 insertions, 52 deletions
diff --git a/include/ct1973.c b/include/ct1975.c
index 592b0b1..760fcd1 100644
--- a/include/ct1973.c
+++ b/include/ct1975.c
@@ -1,9 +1,8 @@
-#include "ct1973.h"
+#include "ct1975.h"
float flattened[CONV_NUM+2];
float dense1[DENSE1_NUM];
float dense2[DENSE2_NUM];
-float output[OUTPUT_NUM];
#define RELU(x) ((x) = ((x)<0)?0:(x))
@@ -76,14 +75,15 @@ evaluate_black_win(void) {
/* ------------- *
* Output layer *
* ------------- */
- float norm = 0;
- for (uint8_t out = 0; out < OUTPUT_NUM; out++) {
- output[out] = output_biases[out];
- for (uint8_t d2 = 0; d2 < DENSE2_NUM; d2++) {
- output[out] += dense2[d2]*output_weights[out][d2];
- }
- output[out] = exp(output[out]);
- norm += output[out];
+ float output = output_bias;
+ for (uint8_t d2 = 0; d2 < DENSE2_NUM; d2++) {
+ output += dense2[d2]*output_weights[d2];
}
- return output[1]/norm;
+
+ // Truncated Pade approximant of logistic function
+ output = (12.0+output+50.0*output/(output*output+10.0))/24.0;
+ if (output > 1.0) return 1.0;
+ else if (output < 0.0) return 0.0;
+
+ return output;
}
diff --git a/include/ct1973.h b/include/ct1975.h
index 6350ff3..79c20d2 100644
--- a/include/ct1973.h
+++ b/include/ct1975.h
@@ -1,5 +1,4 @@
#include <stdint.h>
-#include <math.h>
#include "tak.h"
#include "weights.h"
diff --git a/include/weights.h b/include/weights.h
index 3c83010..18079ba 100644
--- a/include/weights.h
+++ b/include/weights.h
@@ -5,8 +5,7 @@
#define CONV_NUM (KERN_NUM * KERN_OSIZE * KERN_OSIZE) // 108
#define DENSE1_NUM 9
-#define DENSE2_NUM 8
-#define OUTPUT_NUM 2
+#define DENSE2_NUM 9
extern const float conv2d_weights[KERN_NUM][KERN_SIZE][KERN_SIZE][KERN_CHAN];
extern const float conv2d_biases[KERN_NUM];
@@ -14,5 +13,5 @@ extern const float dense1_weights[DENSE1_NUM][CONV_NUM+2];
extern const float dense1_biases[DENSE1_NUM];
extern const float dense2_weights[DENSE2_NUM][DENSE1_NUM];
extern const float dense2_biases[DENSE2_NUM];
-extern const float output_weights[OUTPUT_NUM][DENSE2_NUM];
-extern const float output_biases[2];
+extern const float output_weights[DENSE2_NUM];
+extern const float output_bias;
diff --git a/src/ctaklm.c b/src/ctaklm.c
index a5bfe05..5df23c9 100644
--- a/src/ctaklm.c
+++ b/src/ctaklm.c
@@ -4,7 +4,7 @@
#include <linenoise.h>
#include <tak.h>
-#include <ct1973.h>
+#include <ct1975.h>
const char *blk = "\033[41m", *wht = "\033[44m";
const char *rev = "\033[7m", *und = "\033[4m", *rst = "\033[0m";
diff --git a/src/train5.py b/src/train5.py
index 03e9669..214ad88 100644
--- a/src/train5.py
+++ b/src/train5.py
@@ -1,10 +1,19 @@
-# 30 10(11) 5 # 27 17 4
+# Loading data
import pandas as pd
import numpy as np
+# Output of weights
+import re
from tensorflow import transpose
+# Custom activation function
+from tensorflow import constant as k
+from tensorflow.math import add, divide, maximum, minimum, multiply, square
+
+# Computing size
from tensorflow.keras.backend import get_value
+
+# Building models
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Concatenate
from tensorflow.keras.layers import Input
@@ -13,28 +22,16 @@ from tensorflow.keras.layers import Convolution2D
from tensorflow.keras.layers import Flatten
-def load_data(size):
- shape = (-1, size, size, 8)
-
- tr_fn = "training-"+str(size)+".csv"
- training_csv = pd.read_csv(tr_fn) # .head(80000)
- training_data = training_csv
- training_stack_input = np.array(training_data.iloc[:, 2:-2]).reshape(shape, order='F')
- training_flats_input = np.array(training_data.iloc[:, 0:2])
- training_input = [training_stack_input, training_flats_input]
- training_outcome = training_data.iloc[:, -2:]
-
- val_fn = "validation-"+str(size)+".csv"
- val_data = pd.read_csv(val_fn).tail(20000)
- val_stack_input = np.array(val_data.iloc[:, 2:-2]).reshape(shape, order='F')
- val_flats_input = np.array(val_data.iloc[:, 0:2])
- val_input = [val_stack_input, val_flats_input]
- val_outcome = val_data.iloc[:, -2:]
-
- return [(training_input, training_outcome), (val_input, val_outcome)]
-
+# 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
+# as it would otherwise exceed this range at +- 4.6 or so
+def truncated_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))))
-def make_model(size, magic=[9, 18, 9]):
+def make_model(size, magic=[12, 9, 9]):
# Our model for the stacks, a small CNN
stack_shape = (size, size, 8)
stack_input = Input(shape=stack_shape)
@@ -43,25 +40,43 @@ def make_model(size, magic=[9, 18, 9]):
use_bias=True)(stack_input)
stack_model = Flatten()(stack_model)
stack_model = Model(inputs=stack_input, outputs=stack_model)
-
# The overall model
flats_input = Input(shape=(2,))
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(2, activation="softmax", use_bias=True)(model)
+ model = Dense(1, activation=truncated_pade_logistic, use_bias=True)(model)
model = Model(inputs=[stack_model.input, flats_input], outputs=model)
-
model.compile(optimizer='adam',
- loss='binary_crossentropy',
+ # loss='binary_crossentropy',
# loss='categorical_crossentropy',
- # loss='mean_squared_error',
+ loss='mean_squared_error',
+ # loss='mean_absolute_error',
metrics=['accuracy'])
-
model.summary()
return model
+def load_data(size):
+ shape = (-1, size, size, 8)
+
+ tr_fn = "training-"+str(size)+".csv"
+ training_csv = pd.read_csv(tr_fn) #.head(100000)
+ training_data = training_csv
+ training_stack_input = np.array(training_data.iloc[:, 2:-1]).reshape(shape, order='F')
+ training_flats_input = np.array(training_data.iloc[:, 0:2])
+ training_input = [training_stack_input, training_flats_input]
+ training_outcome = training_data.iloc[:, -1:]
+
+ val_fn = "validation-"+str(size)+".csv"
+ val_data = pd.read_csv(val_fn).tail(20000)
+ val_stack_input = np.array(val_data.iloc[:, 2:-1]).reshape(shape, order='F')
+ val_flats_input = np.array(val_data.iloc[:, 0:2])
+ val_input = [val_stack_input, val_flats_input]
+ val_outcome = val_data.iloc[:, -1:]
+
+ return [(training_input, training_outcome), (val_input, val_outcome)]
+
def train(size, model, data, iterations=1, epochs=10):
(training_input, training_outcome), (val_input, val_outcome) = data
results = []
@@ -84,21 +99,26 @@ def model_size(model):
def magic_search(data):
results = []
- for width in range(10, 16):
+ for width in range(12, 16):
for dense1 in range(8, 24):
for dense2 in range(6, dense1+1):
m = make_model(5, [width, dense1, dense2])
if model_size(m) <= 2000:
results += [([width, dense1, dense2],
- train(5, m, data, iterations=1, epochs=10))]
+ train(5, m, data, iterations=1, epochs=20))]
print("\nSummary")
for r in results:
- print("Parameters {0}: {1}".format(r[0], r[1][-1:][0]))
+ print("Parameters {0}: {1}".format(r[0], r[1][0][-1:][0]))
+ return results
def write_weights(model):
def fix(string):
- return string.replace("[", "{").replace("]", "}")
+ 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
f = open("weights.txt", "w")
conv2d_weights = np.array(transpose(model.trainable_variables[0], perm=[3, 1, 0, 2]))
conv2d_biases = np.array(model.trainable_variables[1])
@@ -112,16 +132,17 @@ def write_weights(model):
dense1_weights, dense1_biases,
dense2_weights, dense2_biases,
output_weights, output_biases]:
- f.write(fix(str(v))+"\n")
+ f.write(fix(str(v))+"\n\n")
f.close()
data = load_data(5)
-model = make_model(5, [12, 9, 8])
+model = make_model(5, [12, 9, 9])
results, model = train(5, model, data, iterations=10, epochs=20)
print("\nScores")
for i in range(len(results)):
print("Iteration {0}: {1}".format(i+1, results[i]))
+
write_weights(model)
-# magic_search(data)
+#results = magic_search(data)