!7 cmodule PerceptronSpike > DynPrintLogAndEnabled { sclass Example { double[] inputs; int answer; *() {} *(double x, double y, int a) { inputs = new double[] {x, y, 1}; answer = a; } } switchable int nExamples = 200; L examples; switchable double c = 1; switchable bool randomizeC = false; switchable bool startWithRandomWeights = true; transient double[] weights; transient double error; start-thread { if (l(examples) != nExamples) setField(examples := repF(nExamples, () -> { int x = rand(640), y = rand(360); ret new Example(x, y, y < f(x) ? -1 : 1); })); int n = l(first(examples).inputs); print(+n); weights = new double[n]; if (startWithRandomWeights) for i over weights: weights[i] = random(-1.0, 1.0); double lastError = -1; long round = 0; while ping (lastError != 0) { if (!enabled) continue with sleepSeconds(1); ++round; double error = train(); if (error != lastError) { print("Error: " + error + ", round " + round + ", weights: " + sfu(weights)); lastError = error; } } } double train() { double error = 0; for (Example e : examples) error += abs(train(e)); ret error/l(examples); } // function to be learned private double f(double x) { ret x * 0.7 + 40; } int feedForward(double[] inputs) { double sum = 0; for i over weights: sum += inputs[i] * weights[i]; ret activate(sum); } int activate(double s) { return s > 0 ? 1 : -1; } double train(Example e) { int guess = feedForward(e.inputs); double error = e.answer - guess; double cc = c/nExamples; for i over weights: weights[i] += (randomizeC ? rand(cc) : cc) * error * e.inputs[i]; ret error; } }