Warning: session_start(): open(/var/lib/php/sessions/sess_5eqgvvtc2bf1347j8rb4sq3qdl, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
// class is persistable
sclass Perceptron implements IPred {
srecord Example(double[] inputs, bool answer) {
double getInput(int i) { ret i < inputs.length ? inputs[i] : 1; }
}
L examples = syncList();
double c = 1;
bool randomizeC = true, startWithRandomWeights = false;
long trainingRound;
double error = -1; // -1 = not trained yet
double[] weights;
*() {}
*(L *examples) {}
ItIt trainingIterator() {
if (empty(examples)) ret emptyItIt();
int n = l(first(examples).inputs)+1;
if (weights == null) {
weights = new double[n];
if (startWithRandomWeights)
for i over weights: weights[i] = random(-1.0, 1.0);
}
ret iff(() -> {
if (error == 0) ret endMarker();
++trainingRound;
double lastError = error;
trainARound();
ret error != lastError ? error : null;
});
}
double trainARound() {
double error = 0;
int n = l(examples);
if (n == 0) ret -1;
for (Example e : concIter(examples)) error += abs(trainAnExample(e));
ret this.error = error/n;
}
int feedForward(double[] inputs) {
double sum = last(weights);
for i over inputs: sum += inputs[i] * weights[i];
ret activate(sum);
}
public Bool get(double[] inputs) {
ret feedForward(inputs) > 0;
}
int activate(double s) {
return s > 0 ? 1 : -1;
}
double recalcError() {
double error = 0;
int n = l(examples);
if (n == 0) ret -1;
for (Example e : concIter(examples))
error += abs(errorForExample(e));
ret this.error = error/n;
}
double errorForExample(Example e) {
int guess = feedForward(e.inputs);
ret (e.answer ? 1 : -1) - guess;
}
double trainAnExample(Example e) {
double error = errorForExample(e);
if (error != 0) {
double cc = c/l(examples);
for i over weights:
weights[i] += (randomizeC ? rand(cc) : cc) * error * e.getInput(i);
}
ret error;
}
void printWithWeights {
print("Error: " + error + ", round " + trainingRound + ", weights: " + sfu(weights));
}
// scaling the weights doesn't make a difference
// returns true if it worked (error did not increase)
bool scaleWeights(double factor) {
for i over weights:
weights[i] *= factor;
double lastError = error;
if (recalcError() > lastError)
ret false with warn("Error increased from \*lastError*/ to \*error*/ during scale weight with factor \*factor*/");
true;
}
void addExample(double[] inputs, bool answer) {
examples.add(new Example(inputs, answer));
}
}