xxxxxxxxxx
126
let weights = [];
let width = 1200;
let height = 600;
let t = 0;
let ab = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
//Creating a training set consisting of the first five letters of the latin alphabet
let training = [
[0, 0, 1, 0, 0,
0, 1, 0, 1, 0,
0, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1],
[1, 1, 1, 0, 0,
1, 0, 0, 1, 0,
1, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 1, 1, 1, 0],
[0, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 0,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0],
[1, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 0],
[1, 1, 1, 1, 1,
1, 0, 0, 0, 0,
1, 1, 1, 0, 0,
1, 0, 0, 0, 0,
1, 1, 1, 1, 1],
];
let output;
let input = [];
//let b = 0.1; //Bias
let n = 25; //Number of pixels
let N = 10000; //Training iterations
let η = 0.25; //Learning rate
function setup() {
createCanvas(width, height);
for (let i = 0; i < 26; i++) {
let temp = [];
for (let j = 0; j < n; j++) {
temp.push(1 / n);
}
weights.push(temp);
}
for (let i = 0; i < 25; i++) {
input.push(0);
}
gButton = createButton("Guess");
gButton.mousePressed(guess);
//Training for N iterations
for (let i = 0; i < N; i++) {
train();
}
}
function draw() {
background(220);
//This creates the drawn image
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
fill(input[i + 5 * j] * 255);
rect(
(i * width) / 10,
(j * height) / sqrt(n),
width / 10,
height / sqrt(n)
);
}
}
//This draws the machine's guess
for (let i = 0; i < 26; i++) {
fill(output[i] * 255);
rect(((i + 5) * width) / 10, 0, width / 10, height / sqrt(n));
fill(0);
text(ab[i], ((i + 5.5) * width) / 10, (0.5 * height) / sqrt(n));
}
}
//This trains the machine and adjusts the weights on a random training image
function train() {
//Here I create a new random training image
t = random([0, 1, 2, 3, 4]);
output = matMul(weights, training[t]);
//Here I adjust the weights according to the output and the expected output(training)
for (let i = 0; i < weights.length; i++) {
for (let j = 0; j < weights[i].length; j++) {
weights[i][j] +=
(int(t == i) - output[i]) * output[j] * (1 - output[j]) * (j == t) * η;
}
}
}
function guess() {
output = matMul(weights, input);
}
//This is the scalar product to calculate each pixel of the output picture
function dot(v, w) {
let S = 0;
for (let i = 0; i < v.length; i++) {
S += v[i] * w[i];
}
return S;
}
//This performs all the scalar products, takes the sigmoid on the result and produces the total image
function matMul(A, x) {
let S = [];
for (let i = 0; i < A.length; i++) {
S.push(sigmoid(dot(A[i], x)));
}
return S;
}
//The sigmoid function makes sure our values are between 0 and 1
function sigmoid(x) {
return 1 / (1 + exp(-x));
}
//Clicking a pixel on the left flips that pixel to the opposite colour
function mousePressed() {
input[floor((10 * mouseX) / width) + 5 * floor((5 * mouseY) / height)] = int(
!input[floor((10 * mouseX) / width) + 5 * floor((5 * mouseY) / height)]
);
print(input[floor(width / mouseX / 10) + 5 * floor(height / mouseY / 5)]);
}