├── Part1 ├── Load_Data.pde ├── Network.pde ├── Neuron.pde ├── Part1.pde ├── Sigmoid.pde └── data │ ├── HelveticaNeue-Light-15.vlw │ ├── t10k-images-14x14.idx-ubyte │ ├── t10k-images-14x14.idx3-ubyte │ └── t10k-labels.idx1-ubyte ├── Part2 ├── Load_Data.pde ├── Network.pde ├── Neuron.pde ├── Part2.pde ├── Sigmoid.pde ├── data │ ├── HelveticaNeue-Light-15.vlw │ ├── t10k-images-14x14.idx-ubyte │ ├── t10k-images-14x14.idx3-ubyte │ └── t10k-labels.idx1-ubyte └── test.pde ├── Part3 ├── Button.pde ├── Load_Data.pde ├── Network.pde ├── Neuron.pde ├── Part3.pde ├── Sigmoid.pde └── data │ ├── HelveticaNeue-Light-15.vlw │ ├── t10k-images-14x14.idx-ubyte │ ├── t10k-images-14x14.idx3-ubyte │ └── t10k-labels.idx1-ubyte ├── Part4 ├── Button.pde ├── Load_Data.pde ├── Network.pde ├── Neuron.pde ├── Part4.pde ├── Sigmoid.pde └── data │ ├── HelveticaNeue-Light-15.vlw │ ├── t10k-images-14x14.idx-ubyte │ ├── t10k-images-14x14.idx3-ubyte │ └── t10k-labels.idx1-ubyte └── README.md /Part1/Load_Data.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | LOADING DATA 8 | 9 | The data is a list of 10,000 handwritten digits resampled to a grid of 14x14 pixels by Alasdair Turner 10 | The original set can be found here: http://yann.lecun.com/exdb/mnist/ 11 | 12 | */ 13 | 14 | Card [] testing_set; // the set we use to train (2000) 15 | Card [] training_set; // the set we use to train (8000) 16 | 17 | class Card { // This class contains all the functions to format and save the data 18 | 19 | float [] inputs; 20 | float [] outputs; 21 | int output; 22 | 23 | Card() { 24 | inputs = new float [196]; // the images are a grid of 14x14 pixels which makes for a total of 196 25 | outputs = new float[10]; // the number of possible outputs; from 0 to 9 26 | } 27 | 28 | void imageLoad(byte [] images, int offset) { // Images is an array of 1,960,000 bytes, each one representing a pixel (0-255) of the 10,000 * 14x14 (196) images 29 | // We know one image consists of 196 bytes so the location is: offset*196 30 | for (int i = 0; i < 196; i++) { 31 | inputs[i] = int(images[i+offset]) / 128.0 - 1.0; // We then store each pixel in the array inputs[] after converting it from (0 - 255) to (+1 - -1) as they vary on the greyscale 32 | } 33 | } 34 | 35 | void labelLoad(byte [] labels, int offset) { // Labels is an array of 10,000 bytes, each representing the answer of each image 36 | 37 | output = int(labels[offset]); 38 | 39 | for (int i = 0; i < 10; i++) { // We then set the correct index in output[] to +1 if it corresponds to the ouput and -1 if not 40 | if (i == output) { 41 | outputs[i] = 1.0; 42 | } else { 43 | outputs[i] = -1.0; 44 | } 45 | } 46 | } 47 | } 48 | 49 | void loadData() { // In this function we initialise all out data in two seperate arrays, training[] and test[] 50 | 51 | byte [] images = loadBytes("t10k-images-14x14.idx3-ubyte"); 52 | byte [] labels = loadBytes("t10k-labels.idx1-ubyte"); 53 | training_set = new Card [8000]; 54 | int tr_pos = 0; 55 | testing_set = new Card [2000]; 56 | int te_pos = 0; 57 | for (int i = 0; i < 10000; i++) { 58 | if (i % 5 != 0) { 59 | training_set[tr_pos] = new Card(); 60 | training_set[tr_pos].imageLoad(images, 16 + i * 196); // There is an offset of 16 bytes 61 | training_set[tr_pos].labelLoad(labels, 8 + i); // There is an offset of 8 bytes 62 | tr_pos++; 63 | } else { 64 | testing_set[te_pos] = new Card(); 65 | testing_set[te_pos].imageLoad(images, 16 + i * 196); // There is an offset of 16 bytes 66 | testing_set[te_pos].labelLoad(labels, 8 + i); // There is an offset of 8 bytes 67 | te_pos++; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /Part1/Network.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | NEURON 8 | 9 | The data is a list of 10,000 handwritten digits resampled to a grid of 14x14 pixels by Alasdair Turner 10 | The original set can be found here: http://yann.lecun.com/exdb/mnist/ 11 | 12 | */ 13 | 14 | class Network { 15 | 16 | Neuron [] m_input_layer; 17 | 18 | Network(int inputs) { 19 | m_input_layer = new Neuron [inputs]; 20 | for (int i = 0; i < m_input_layer.length; i++) { 21 | m_input_layer[i] = new Neuron(); 22 | } 23 | } 24 | void respond(Card card) { 25 | for (int i = 0; i < m_input_layer.length; i++) { 26 | m_input_layer[i].m_output = card.inputs[i]; 27 | } 28 | } 29 | void display() { 30 | for (int i = 0; i < m_input_layer.length; i++) { 31 | pushMatrix(); 32 | translate((i%14) * height / 20.0 + width * 0.06, (i/14) * height 33 | / 20.0 + height * 0.15); 34 | m_input_layer[i].display(); 35 | popMatrix(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Part1/Neuron.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | NEURON 8 | 9 | The data is a list of 10,000 handwritten digits resampled to a grid of 14x14 pixels by Alasdair Turner 10 | The original set can be found here: http://yann.lecun.com/exdb/mnist/ 11 | 12 | */ 13 | 14 | class Neuron { 15 | 16 | float m_output; 17 | 18 | void display() { 19 | 20 | // Number is inverted then scaled from 0 to 255 21 | fill(128 * (1 - m_output)); 22 | ellipse(0, 0, 16, 16); 23 | } 24 | } -------------------------------------------------------------------------------- /Part1/Part1.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | MAIN TAB 8 | 9 | Original from Alasdair Turner (c) 2009 10 | Free software: you can redistribute this program and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | */ 16 | 17 | 18 | int cardNum = int(random(2000)); 19 | 20 | Network neuralnet; 21 | 22 | void setup() { 23 | 24 | size(1000, 400); 25 | loadData(); 26 | neuralnet = new Network(196); 27 | smooth(); 28 | stroke(150); 29 | } 30 | 31 | void draw() { 32 | 33 | neuralnet.respond(testing_set[cardNum]); 34 | background(255); 35 | neuralnet.display(); 36 | 37 | fill(100); 38 | text("Card number: #" + cardNum, width*0.05, height*0.9); 39 | text("Card label: " + testing_set[cardNum].output, width*0.05, height*0.95); 40 | } 41 | 42 | void mousePressed() { 43 | cardNum = int(random(2000)); 44 | } 45 | -------------------------------------------------------------------------------- /Part1/Sigmoid.pde: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part1/Sigmoid.pde -------------------------------------------------------------------------------- /Part1/data/HelveticaNeue-Light-15.vlw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part1/data/HelveticaNeue-Light-15.vlw -------------------------------------------------------------------------------- /Part1/data/t10k-images-14x14.idx-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part1/data/t10k-images-14x14.idx-ubyte -------------------------------------------------------------------------------- /Part1/data/t10k-images-14x14.idx3-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part1/data/t10k-images-14x14.idx3-ubyte -------------------------------------------------------------------------------- /Part1/data/t10k-labels.idx1-ubyte: -------------------------------------------------------------------------------- 1 | '                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             -------------------------------------------------------------------------------- /Part2/Load_Data.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | LOADING DATA 8 | 9 | The data is a list of 10,000 handwritten digits resampled to a grid of 14x14 pixels by Alasdair Turner 10 | The original set can be found here: http://yann.lecun.com/exdb/mnist/ 11 | 12 | */ 13 | 14 | Card [] testing_set; // the set we use to train (2000) 15 | Card [] training_set; // the set we use to train (8000) 16 | 17 | class Card { // This class contains all the functions to format and save the data 18 | 19 | float [] inputs; 20 | float [] outputs; 21 | int output; 22 | 23 | Card() { 24 | inputs = new float [196]; // the images are a grid of 14x14 pixels which makes for a total of 196 25 | outputs = new float[10]; // the number of possible outputs; from 0 to 9 26 | } 27 | 28 | void imageLoad(byte [] images, int offset) { // Images is an array of 1,960,000 bytes, each one representing a pixel (0-255) of the 10,000 * 14x14 (196) images 29 | // We know one image consists of 196 bytes so the location is: offset*196 30 | for (int i = 0; i < 196; i++) { 31 | inputs[i] = int(images[i+offset]) / 128.0 - 1.0; // We then store each pixel in the array inputs[] after converting it from (0 - 255) to (+1 - -1) as they vary on the greyscale 32 | } 33 | } 34 | 35 | void labelLoad(byte [] labels, int offset) { // Labels is an array of 10,000 bytes, each representing the answer of each image 36 | 37 | output = int(labels[offset]); 38 | 39 | for (int i = 0; i < 10; i++) { // We then set the correct index in output[] to +1 if it corresponds to the ouput and -1 if not 40 | if (i == output) { 41 | outputs[i] = 1.0; 42 | } else { 43 | outputs[i] = -1.0; 44 | } 45 | } 46 | } 47 | 48 | } 49 | 50 | void loadData(){ // In this function we initialise all out data in two seperate arrays, training[] and test[] 51 | 52 | byte [] images = loadBytes("t10k-images-14x14.idx3-ubyte"); 53 | byte [] labels = loadBytes("t10k-labels.idx1-ubyte"); 54 | training_set = new Card [8000]; 55 | int tr_pos = 0; 56 | testing_set = new Card [2000]; 57 | int te_pos = 0; 58 | for (int i = 0; i < 10000; i++) { 59 | if (i % 5 != 0) { 60 | training_set[tr_pos] = new Card(); 61 | training_set[tr_pos].imageLoad(images, 16 + i * 196); // There is an offset of 16 bytes 62 | training_set[tr_pos].labelLoad(labels, 8 + i); // There is an offset of 8 bytes 63 | tr_pos++; 64 | } else { 65 | testing_set[te_pos] = new Card(); 66 | testing_set[te_pos].imageLoad(images, 16 + i * 196); // There is an offset of 16 bytes 67 | testing_set[te_pos].labelLoad(labels, 8 + i); // There is an offset of 8 bytes 68 | te_pos++; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Part2/Network.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | NETWORK 8 | 9 | This class is for the neural network, which is hard coded with three layers: input, hidden and output 10 | 11 | */ 12 | 13 | class Network { 14 | 15 | Neuron [] input_layer; 16 | Neuron [] hidden_layer; 17 | Neuron [] output_layer; 18 | 19 | Network(int inputs, int hidden, int outputs) { 20 | 21 | input_layer = new Neuron [inputs]; 22 | hidden_layer = new Neuron [hidden]; 23 | output_layer = new Neuron [outputs]; 24 | 25 | for (int i = 0; i < input_layer.length; i++) { 26 | input_layer[i] = new Neuron(); 27 | } 28 | 29 | for (int j = 0; j < hidden_layer.length; j++) { 30 | hidden_layer[j] = new Neuron(input_layer); 31 | } 32 | 33 | for (int k = 0; k < output_layer.length; k++) { 34 | output_layer[k] = new Neuron(hidden_layer); 35 | } 36 | } 37 | 38 | void respond(Card card) 39 | { 40 | float [] responses = new float [output_layer.length]; 41 | 42 | for (int i = 0; i < input_layer.length; i++) { 43 | input_layer[i].output = card.inputs[i]; 44 | } 45 | // now feed forward through the hidden layer 46 | for (int j = 0; j < hidden_layer.length; j++) { 47 | hidden_layer[j].respond(); 48 | } 49 | for (int k = 0; k < output_layer.length; k++) { 50 | output_layer[k].respond(); 51 | } 52 | } 53 | 54 | void display() { 55 | 56 | // Draw the input layer 57 | for (int i = 0; i < input_layer.length; i++) { 58 | pushMatrix(); 59 | translate( 60 | (i%14) * height / 20.0 + width * 0.05, 61 | (i/14) * height / 20.0 + height * 0.15); 62 | input_layer[i].display(); 63 | popMatrix(); 64 | } 65 | 66 | // Draw the hidden layer 67 | for (int j = 0; j < hidden_layer.length; j++) { 68 | pushMatrix(); 69 | translate( 70 | (j%7) * height / 20.0 + width * 0.53, 71 | (j/7) * height / 20.0 + height * 0.32); 72 | hidden_layer[j].display(); 73 | popMatrix(); 74 | } 75 | 76 | // Draw the output layer 77 | for (int k = 0; k < output_layer.length; k++) { 78 | pushMatrix(); 79 | translate( 80 | width * 0.9, 81 | ((k+9)%10) * height / 20.0 + height * 0.24); 82 | output_layer[k].display(); 83 | popMatrix(); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Part2/Neuron.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | NEURON 8 | 9 | This class is for the neural network, which is hard coded with three layers: input, hidden and output 10 | 11 | */ 12 | 13 | class Neuron { 14 | 15 | Neuron [] inputs; // Strores the neurons from the previous layer 16 | float [] weights; 17 | float output; 18 | 19 | Neuron() { 20 | } 21 | 22 | Neuron(Neuron [] p_inputs) { 23 | 24 | inputs = new Neuron [p_inputs.length]; 25 | weights = new float [p_inputs.length]; 26 | for (int i = 0; i < inputs.length; i++) { 27 | inputs[i] = p_inputs[i]; 28 | weights[i] = random(-1.0, 1.0); 29 | } 30 | } 31 | 32 | void respond() { 33 | 34 | float input = 0.0; 35 | for (int i = 0; i < inputs.length; i++) { 36 | input += inputs[i].output * weights[i]; 37 | } 38 | output = lookupSigmoid(input); 39 | } 40 | 41 | void display() { 42 | fill(128 * (1 - output)); 43 | ellipse(0, 0, 16, 16); 44 | } 45 | } -------------------------------------------------------------------------------- /Part2/Part2.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | MAIN TAB 8 | 9 | Original from Alasdair Turner (c) 2009 10 | Free software: you can redistribute this program and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | */ 16 | 17 | 18 | int cardNum = int(random(2000)); 19 | 20 | Network neuralnet; 21 | 22 | void setup() { 23 | 24 | size(1000, 400); 25 | setupSigmoid(); 26 | loadData(); 27 | neuralnet = new Network(196, 49, 10); 28 | smooth(); 29 | stroke(150); 30 | } 31 | 32 | void draw() { 33 | 34 | neuralnet.respond(testing_set[cardNum]); 35 | background(255); 36 | neuralnet.display(); 37 | 38 | fill(100); 39 | text("Card number: #" + cardNum, width*0.05, height*0.9); 40 | text("Card label: " + testing_set[cardNum].output, width*0.05, height*0.95); 41 | } 42 | 43 | void mousePressed() { 44 | cardNum = int(random(2000)); 45 | } 46 | -------------------------------------------------------------------------------- /Part2/Sigmoid.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | SIGMOID 8 | Activation function 9 | 10 | A sigmoid function is the neuron's response to inputs the sigmoidal response ranges from -1.0 to 1.0 11 | For example, the weighted sum of inputs might be "2.1" our response would be lookupSigmoid(2.1) = 0.970 12 | This is a look up table for sigmoid (neural response) values which is valid from -5.0 to 5.0 13 | 14 | */ 15 | 16 | float [] g_sigmoid = new float [200]; 17 | 18 | void setupSigmoid() { 19 | 20 | for (int i = 0; i < 200; i++) { 21 | float x = (i / 20.0) - 5.0; 22 | g_sigmoid[i] = 2.0 / (1.0 + exp(-2.0 * x)) - 1.0; 23 | } 24 | } 25 | 26 | // once the sigmoid has been set up, this function accesses it: 27 | float lookupSigmoid(float x) { 28 | 29 | return g_sigmoid[constrain((int) floor((x + 5.0) * 20.0), 0, 199)]; 30 | } -------------------------------------------------------------------------------- /Part2/data/HelveticaNeue-Light-15.vlw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part2/data/HelveticaNeue-Light-15.vlw -------------------------------------------------------------------------------- /Part2/data/t10k-images-14x14.idx-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part2/data/t10k-images-14x14.idx-ubyte -------------------------------------------------------------------------------- /Part2/data/t10k-images-14x14.idx3-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part2/data/t10k-images-14x14.idx3-ubyte -------------------------------------------------------------------------------- /Part2/data/t10k-labels.idx1-ubyte: -------------------------------------------------------------------------------- 1 | '                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             -------------------------------------------------------------------------------- /Part2/test.pde: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part2/test.pde -------------------------------------------------------------------------------- /Part3/Button.pde: -------------------------------------------------------------------------------- 1 | class Button { 2 | 3 | PVector pos; 4 | String name; 5 | int radius = 20; 6 | 7 | Button(float _x, float _y, String _name) { 8 | pos = new PVector(_x, _y); 9 | name = _name; 10 | } 11 | 12 | void display() { 13 | if (hover()) fill(220); 14 | else noFill(); 15 | stroke(150); 16 | ellipse(pos.x, pos.y, radius*2, radius*2); 17 | fill(150); 18 | text(name, pos.x-13, pos.y+4); 19 | } 20 | 21 | boolean hover() { 22 | PVector mouse = new PVector(mouseX, mouseY); 23 | if (mouse.dist(pos) < radius) return true; 24 | else return false; 25 | } 26 | } -------------------------------------------------------------------------------- /Part3/Load_Data.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | LOADING DATA 8 | 9 | The data is a list of 10,000 handwritten digits resampled to a grid of 14x14 pixels by Alasdair Turner 10 | The original set can be found here: http://yann.lecun.com/exdb/mnist/ 11 | 12 | */ 13 | 14 | Card [] testing_set; // the set we use to train (2000) 15 | Card [] training_set; // the set we use to train (8000) 16 | 17 | class Card { // This class contains all the functions to format and save the data 18 | 19 | float [] inputs; 20 | float [] outputs; 21 | int output; 22 | 23 | Card() { 24 | inputs = new float [196]; // the images are a grid of 14x14 pixels which makes for a total of 196 25 | outputs = new float[10]; // the number of possible outputs; from 0 to 9 26 | } 27 | 28 | void imageLoad(byte [] images, int offset) { // Images is an array of 1,960,000 bytes, each one representing a pixel (0-255) of the 10,000 * 14x14 (196) images 29 | // We know one image consists of 196 bytes so the location is: offset*196 30 | for (int i = 0; i < 196; i++) { 31 | inputs[i] = int(images[i+offset]) / 128.0 - 1.0; // We then store each pixel in the array inputs[] after converting it from (0 - 255) to (+1 - -1) as they vary on the greyscale 32 | } 33 | } 34 | 35 | void labelLoad(byte [] labels, int offset) { // Labels is an array of 10,000 bytes, each representing the answer of each image 36 | 37 | output = int(labels[offset]); 38 | 39 | for (int i = 0; i < 10; i++) { // We then set the correct index in output[] to +1 if it corresponds to the ouput and -1 if not 40 | if (i == output) { 41 | outputs[i] = 1.0; 42 | } else { 43 | outputs[i] = -1.0; 44 | } 45 | } 46 | } 47 | 48 | } 49 | 50 | void loadData(){ // In this function we initialise all out data in two seperate arrays, training[] and test[] 51 | 52 | byte [] images = loadBytes("t10k-images-14x14.idx3-ubyte"); 53 | byte [] labels = loadBytes("t10k-labels.idx1-ubyte"); 54 | training_set = new Card [8000]; 55 | int tr_pos = 0; 56 | testing_set = new Card [2000]; 57 | int te_pos = 0; 58 | for (int i = 0; i < 10000; i++) { 59 | if (i % 5 != 0) { 60 | training_set[tr_pos] = new Card(); 61 | training_set[tr_pos].imageLoad(images, 16 + i * 196); // There is an offset of 16 bytes 62 | training_set[tr_pos].labelLoad(labels, 8 + i); // There is an offset of 8 bytes 63 | tr_pos++; 64 | } else { 65 | testing_set[te_pos] = new Card(); 66 | testing_set[te_pos].imageLoad(images, 16 + i * 196); // There is an offset of 16 bytes 67 | testing_set[te_pos].labelLoad(labels, 8 + i); // There is an offset of 8 bytes 68 | te_pos++; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Part3/Network.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | NETWORK 8 | 9 | This class is for the neural network, which is hard coded with three layers: input, hidden and output 10 | 11 | */ 12 | 13 | class Network { 14 | 15 | Neuron [] input_layer; 16 | Neuron [] hidden_layer; 17 | Neuron [] output_layer; 18 | int bestIndex = 0; 19 | 20 | Network(int inputs, int hidden, int outputs) { 21 | 22 | input_layer = new Neuron [inputs]; 23 | hidden_layer = new Neuron [hidden]; 24 | output_layer = new Neuron [outputs]; 25 | 26 | for (int i = 0; i < input_layer.length; i++) { 27 | input_layer[i] = new Neuron(); 28 | } 29 | 30 | for (int j = 0; j < hidden_layer.length; j++) { 31 | hidden_layer[j] = new Neuron(input_layer); 32 | } 33 | 34 | for (int k = 0; k < output_layer.length; k++) { 35 | output_layer[k] = new Neuron(hidden_layer); 36 | } 37 | } 38 | 39 | void respond(Card card) { 40 | 41 | for (int i = 0; i < input_layer.length; i++) { 42 | input_layer[i].output = card.inputs[i]; 43 | } 44 | // now feed forward through the hidden layer 45 | for (int j = 0; j < hidden_layer.length; j++) { 46 | hidden_layer[j].respond(); 47 | } 48 | for (int k = 0; k < output_layer.length; k++) { 49 | output_layer[k].respond(); 50 | } 51 | } 52 | 53 | void display() { 54 | 55 | // Draw the input layer 56 | for (int i = 0; i < input_layer.length; i++) { 57 | pushMatrix(); 58 | translate( 59 | (i%14) * height / 20.0 + width * 0.05, 60 | (i/14) * height / 20.0 + height * 0.13); 61 | input_layer[i].display(); 62 | popMatrix(); 63 | } 64 | 65 | // Draw the hidden layer 66 | for (int j = 0; j < hidden_layer.length; j++) { 67 | pushMatrix(); 68 | translate( 69 | (j%7) * height / 20.0 + width * 0.53, 70 | (j/7) * height / 20.0 + height * 0.32); 71 | hidden_layer[j].display(); 72 | popMatrix(); 73 | } 74 | 75 | // Draw the output layer 76 | float [] resp = new float [output_layer.length]; 77 | float respTotal = 0.0; 78 | for (int k = 0; k < output_layer.length; k++) { 79 | resp[k] = output_layer[k].output; 80 | respTotal += resp[k]+1; 81 | } 82 | 83 | for (int k = 0; k < output_layer.length; k++) { 84 | pushMatrix(); 85 | translate( 86 | width * 0.85, 87 | (k%10) * height / 15.0 + height * 0.2); 88 | output_layer[k].display(); 89 | fill(150); 90 | strokeWeight(sq(output_layer[k].output)/2); 91 | line(12, 0, 25, 0); 92 | text(k%10, 40, 5); 93 | text(nfc(((output_layer[k].output+1)/respTotal)*100, 2) + "%", 55, 5); 94 | popMatrix(); 95 | strokeWeight(1); 96 | } 97 | float best = -1.0; 98 | for(int i =0; i < resp.length; i++){ 99 | if(resp[i]>best){ 100 | best = resp[i]; 101 | bestIndex = i; 102 | } 103 | } 104 | stroke(255, 0, 0); 105 | noFill(); 106 | ellipse( 107 | width * 0.85, (bestIndex%10) * height / 15.0 + height * 0.2, 108 | 25, 25); 109 | } 110 | 111 | void train(float [] outputs) { 112 | // adjust the output layer 113 | for (int k = 0; k < output_layer.length; k++) { 114 | output_layer[k].setError(outputs[k]); 115 | output_layer[k].train(); 116 | } 117 | float best = -1.0; 118 | for (int i = 0; i < output_layer.length; i++) { 119 | if (output_layer[i].output > best) bestIndex = i; 120 | } 121 | // propagate back to the hidden layer 122 | for (int j = 0; j < hidden_layer.length; j++) { 123 | hidden_layer[j].train(); 124 | } 125 | 126 | // The input layer doesn't learn: it is the input and only that 127 | } 128 | } -------------------------------------------------------------------------------- /Part3/Neuron.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | NEURON 8 | 9 | This class is for the neural network, which is hard coded with three layers: input, hidden and output 10 | 11 | */ 12 | 13 | float LEARNING_RATE = 0.01; 14 | 15 | 16 | class Neuron { 17 | 18 | Neuron [] inputs; // Strores the neurons from the previous layer 19 | float [] weights; 20 | float output; 21 | float error; 22 | 23 | Neuron() { 24 | error = 0.0; 25 | } 26 | 27 | Neuron(Neuron [] p_inputs) { 28 | 29 | inputs = new Neuron [p_inputs.length]; 30 | weights = new float [p_inputs.length]; 31 | error = 0.0; 32 | for (int i = 0; i < inputs.length; i++) { 33 | inputs[i] = p_inputs[i]; 34 | weights[i] = random(-1.0, 1.0); 35 | } 36 | } 37 | 38 | void respond() { 39 | 40 | float input = 0.0; 41 | for (int i = 0; i < inputs.length; i++) { 42 | input += inputs[i].output * weights[i]; 43 | } 44 | output = lookupSigmoid(input); 45 | error = 0.0; 46 | } 47 | 48 | void setError(float desired) { 49 | error = desired - output; 50 | } 51 | 52 | void train() { 53 | 54 | float delta =(1.0 - output) * (1.0 + output) * 55 | error * LEARNING_RATE; 56 | for (int i = 0; i < inputs.length; i++) { 57 | inputs[i].error += weights[i] * error; 58 | weights[i] += inputs[i].output * delta; 59 | } 60 | } 61 | 62 | void display() { 63 | stroke(200); 64 | fill(128 * (1 - output)); 65 | ellipse(0, 0, 16, 16); 66 | } 67 | } -------------------------------------------------------------------------------- /Part3/Part3.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | MAIN TAB 8 | 9 | Original from Alasdair Turner (c) 2009 10 | Free software: you can redistribute this program and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | */ 16 | 17 | 18 | int totalTrain = 0; 19 | int totalTest = 0; 20 | int totalRight = 0; 21 | float sucess = 0; 22 | int testCard = 0; 23 | int trainCard = 0; 24 | 25 | Network neuralnet; 26 | Button trainB, testB; 27 | 28 | void setup() { 29 | 30 | size(1000, 400); 31 | setupSigmoid(); 32 | loadData(); 33 | neuralnet = new Network(196, 49, 10); 34 | smooth(); 35 | stroke(150); 36 | 37 | trainB = new Button(width*0.06, height*0.9, "Train"); 38 | testB = new Button(width*0.11, height*0.9, "Test"); 39 | } 40 | 41 | void draw() { 42 | 43 | background(255); 44 | neuralnet.display(); 45 | 46 | fill(100); 47 | text("Test card: #" + testCard, width*0.18, height*0.89); 48 | text("Train card: " + trainCard, width*0.18, height*0.93); 49 | 50 | text("Total train: " + totalTrain, width*0.32, height*0.89); 51 | text("Total test: " + totalTest, width*0.32, height*0.93); 52 | 53 | if(totalTest>0) sucess = float(totalRight)/float(totalTest); 54 | text("Success rate: " + nfc(sucess, 2), width*0.44, height*0.89); 55 | text("Card label: " + testing_set[testCard].output, width*0.44, height*0.93); 56 | 57 | trainB.display(); 58 | testB.display(); 59 | } 60 | 61 | void mousePressed() { 62 | if (trainB.hover()) { 63 | for (int i = 0; i < 500; i++) { 64 | trainCard = (int) floor(random(0, training_set.length)); 65 | neuralnet.respond(training_set[trainCard]); 66 | neuralnet.train(training_set[trainCard].outputs); 67 | totalTrain++; 68 | } 69 | } else if (testB.hover()){ 70 | testCard = (int) floor(random(0, testing_set.length)); 71 | neuralnet.respond(testing_set[testCard]); 72 | neuralnet.display(); 73 | if(neuralnet.bestIndex == testing_set[testCard].output) totalRight ++; 74 | println(testCard + " " + neuralnet.bestIndex + " " + testing_set[testCard].output); 75 | totalTest ++; 76 | } 77 | redraw(); 78 | } 79 | -------------------------------------------------------------------------------- /Part3/Sigmoid.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | SIGMOID 8 | Activation function 9 | 10 | A sigmoid function is the neuron's response to inputs the sigmoidal response ranges from -1.0 to 1.0 11 | For example, the weighted sum of inputs might be "2.1" our response would be lookupSigmoid(2.1) = 0.970 12 | This is a look up table for sigmoid (neural response) values which is valid from -5.0 to 5.0 13 | 14 | */ 15 | 16 | float [] g_sigmoid = new float [200]; 17 | 18 | void setupSigmoid() { 19 | 20 | for (int i = 0; i < 200; i++) { 21 | float x = (i / 20.0) - 5.0; 22 | g_sigmoid[i] = 2.0 / (1.0 + exp(-2.0 * x)) - 1.0; 23 | } 24 | } 25 | 26 | // once the sigmoid has been set up, this function accesses it: 27 | float lookupSigmoid(float x) { 28 | 29 | return g_sigmoid[constrain((int) floor((x + 5.0) * 20.0), 0, 199)]; 30 | } -------------------------------------------------------------------------------- /Part3/data/HelveticaNeue-Light-15.vlw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part3/data/HelveticaNeue-Light-15.vlw -------------------------------------------------------------------------------- /Part3/data/t10k-images-14x14.idx-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part3/data/t10k-images-14x14.idx-ubyte -------------------------------------------------------------------------------- /Part3/data/t10k-images-14x14.idx3-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part3/data/t10k-images-14x14.idx3-ubyte -------------------------------------------------------------------------------- /Part3/data/t10k-labels.idx1-ubyte: -------------------------------------------------------------------------------- 1 | '                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             -------------------------------------------------------------------------------- /Part4/Button.pde: -------------------------------------------------------------------------------- 1 | class Button { 2 | 3 | PVector pos; 4 | String name; 5 | int radius = 20; 6 | 7 | Button(float _x, float _y, String _name) { 8 | pos = new PVector(_x, _y); 9 | name = _name; 10 | } 11 | 12 | void display() { 13 | if (hover()) fill(220); 14 | else noFill(); 15 | stroke(150); 16 | ellipse(pos.x, pos.y, radius*2, radius*2); 17 | fill(150); 18 | text(name, pos.x-13, pos.y+4); 19 | } 20 | 21 | boolean hover() { 22 | PVector mouse = new PVector(mouseX, mouseY); 23 | if (mouse.dist(pos) < radius) return true; 24 | else return false; 25 | } 26 | } -------------------------------------------------------------------------------- /Part4/Load_Data.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | LOADING DATA 8 | 9 | The data is a list of 10,000 handwritten digits resampled to a grid of 14x14 pixels by Alasdair Turner 10 | The original set can be found here: http://yann.lecun.com/exdb/mnist/ 11 | 12 | */ 13 | 14 | Card [] testing_set; // the set we use to train (2000) 15 | Card [] training_set; // the set we use to train (8000) 16 | 17 | class Card { // This class contains all the functions to format and save the data 18 | 19 | float [] inputs; 20 | float [] outputs; 21 | int output; 22 | 23 | Card() { 24 | inputs = new float [196]; // the images are a grid of 14x14 pixels which makes for a total of 196 25 | outputs = new float[10]; // the number of possible outputs; from 0 to 9 26 | } 27 | 28 | void imageLoad(byte [] images, int offset) { // Images is an array of 1,960,000 bytes, each one representing a pixel (0-255) of the 10,000 * 14x14 (196) images 29 | // We know one image consists of 196 bytes so the location is: offset*196 30 | for (int i = 0; i < 196; i++) { 31 | inputs[i] = int(images[i+offset]) / 128.0 - 1.0; // We then store each pixel in the array inputs[] after converting it from (0 - 255) to (+1 - -1) as they vary on the greyscale 32 | } 33 | } 34 | 35 | void labelLoad(byte [] labels, int offset) { // Labels is an array of 10,000 bytes, each representing the answer of each image 36 | 37 | output = int(labels[offset]); 38 | 39 | for (int i = 0; i < 10; i++) { // We then set the correct index in output[] to +1 if it corresponds to the ouput and -1 if not 40 | if (i == output) { 41 | outputs[i] = 1.0; 42 | } else { 43 | outputs[i] = -1.0; 44 | } 45 | } 46 | } 47 | 48 | } 49 | 50 | void loadData(){ // In this function we initialise all out data in two seperate arrays, training[] and test[] 51 | 52 | byte [] images = loadBytes("t10k-images-14x14.idx3-ubyte"); 53 | byte [] labels = loadBytes("t10k-labels.idx1-ubyte"); 54 | training_set = new Card [8000]; 55 | int tr_pos = 0; 56 | testing_set = new Card [2000]; 57 | int te_pos = 0; 58 | for (int i = 0; i < 10000; i++) { 59 | if (i % 5 != 0) { 60 | training_set[tr_pos] = new Card(); 61 | training_set[tr_pos].imageLoad(images, 16 + i * 196); // There is an offset of 16 bytes 62 | training_set[tr_pos].labelLoad(labels, 8 + i); // There is an offset of 8 bytes 63 | tr_pos++; 64 | } else { 65 | testing_set[te_pos] = new Card(); 66 | testing_set[te_pos].imageLoad(images, 16 + i * 196); // There is an offset of 16 bytes 67 | testing_set[te_pos].labelLoad(labels, 8 + i); // There is an offset of 8 bytes 68 | te_pos++; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Part4/Network.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | NETWORK 8 | 9 | This class is for the neural network, which is hard coded with three layers: input, hidden and output 10 | 11 | */ 12 | 13 | 14 | ArrayList connec = new ArrayList(); 15 | ArrayList conStr = new ArrayList(); 16 | 17 | class Network { 18 | 19 | Neuron [] input_layer; 20 | Neuron [] hidden_layer; 21 | Neuron [] output_layer; 22 | int bestIndex = 0; 23 | 24 | Network(int inputs, int hidden, int outputs) { 25 | 26 | input_layer = new Neuron [inputs]; 27 | hidden_layer = new Neuron [hidden]; 28 | output_layer = new Neuron [outputs]; 29 | 30 | for (int i = 0; i < input_layer.length; i++) { 31 | input_layer[i] = new Neuron(); 32 | } 33 | 34 | for (int j = 0; j < hidden_layer.length; j++) { 35 | hidden_layer[j] = new Neuron(input_layer); 36 | } 37 | 38 | for (int k = 0; k < output_layer.length; k++) { 39 | output_layer[k] = new Neuron(hidden_layer); 40 | } 41 | } 42 | 43 | void respond(Card card) { 44 | 45 | for (int i = 0; i < input_layer.length; i++) { 46 | input_layer[i].output = card.inputs[i]; 47 | } 48 | // now feed forward through the hidden layer 49 | for (int j = 0; j < hidden_layer.length; j++) { 50 | hidden_layer[j].respond(); 51 | } 52 | for (int k = 0; k < output_layer.length; k++) { 53 | output_layer[k].respond(); 54 | } 55 | } 56 | 57 | void display() { 58 | 59 | drawCon(); 60 | 61 | // Draw the input layer 62 | for (int i = 0; i < input_layer.length; i++) { 63 | pushMatrix(); 64 | translate( 65 | (i%14) * height / 20.0 + width * 0.05, 66 | (i/14) * height / 20.0 + height * 0.13); 67 | input_layer[i].display(); 68 | popMatrix(); 69 | } 70 | 71 | // Draw the hidden layer 72 | for (int j = 0; j < hidden_layer.length; j++) { 73 | pushMatrix(); 74 | translate( 75 | (j%7) * height / 20.0 + width * 0.53, 76 | (j/7) * height / 20.0 + height * 0.32); 77 | hidden_layer[j].display(); 78 | popMatrix(); 79 | } 80 | 81 | // Draw the output layer 82 | float [] resp = new float [output_layer.length]; 83 | float respTotal = 0.0; 84 | for (int k = 0; k < output_layer.length; k++) { 85 | resp[k] = output_layer[k].output; 86 | respTotal += resp[k]+1; 87 | } 88 | 89 | for (int k = 0; k < output_layer.length; k++) { 90 | pushMatrix(); 91 | translate( 92 | width * 0.85, 93 | (k%10) * height / 15.0 + height * 0.2); 94 | output_layer[k].display(); 95 | fill(150); 96 | strokeWeight(sq(output_layer[k].output)/2); 97 | line(12, 0, 25, 0); 98 | text(k%10, 40, 5); 99 | text(nfc(((output_layer[k].output+1)/respTotal)*100, 2) + "%", 55, 5); 100 | popMatrix(); 101 | strokeWeight(1); 102 | } 103 | float best = -1.0; 104 | for (int i =0; i < resp.length; i++) { 105 | if (resp[i]>best) { 106 | best = resp[i]; 107 | bestIndex = i; 108 | } 109 | } 110 | stroke(255, 0, 0); 111 | noFill(); 112 | ellipse( 113 | width * 0.85, (bestIndex%10) * height / 15.0 + height * 0.2, 114 | 25, 25); 115 | } 116 | 117 | void train(float [] outputs) { 118 | // adjust the output layer 119 | for (int k = 0; k < output_layer.length; k++) { 120 | output_layer[k].setError(outputs[k]); 121 | output_layer[k].train(); 122 | } 123 | float best = -1.0; 124 | for (int i = 0; i < output_layer.length; i++) { 125 | if (output_layer[i].output > best) bestIndex = i; 126 | } 127 | // propagate back to the hidden layer 128 | for (int j = 0; j < hidden_layer.length; j++) { 129 | hidden_layer[j].train(); 130 | } 131 | 132 | // The input layer doesn't learn: it is the input and only that 133 | } 134 | 135 | void drawCon() { 136 | 137 | for (int i = 0; i < hidden_layer.length; i++) { 138 | float [] res = hidden_layer[i].getStrength(); 139 | stroke(200); 140 | strokeWeight(pow(10, res[1])/35); 141 | line( 142 | (i%7) * height / 20.0 + width * 0.53, 143 | (i/7) * height / 20.0 + height * 0.32, 144 | (int(res[0])%14) * height / 20.0 + width * 0.05, 145 | (int(res[0])/14) * height / 20.0 + height * 0.13); 146 | } 147 | 148 | for (int i = 0; i < output_layer.length; i++) { 149 | float [] res = output_layer[i].getStrength(); 150 | stroke(res[1]*200); 151 | strokeWeight(pow(10, res[1])/35); 152 | line( 153 | width * 0.85, 154 | (i%10) * height / 15.0 + height * 0.2, 155 | (res[0]%7) * height / 20.0 + width * 0.53, 156 | (res[0]/7) * height / 20.0 + height * 0.32); 157 | } 158 | strokeWeight(1); 159 | } 160 | } -------------------------------------------------------------------------------- /Part4/Neuron.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #2 6 | 7 | NEURON 8 | 9 | This class is for the neural network, which is hard coded with three layers: input, hidden and output 10 | 11 | */ 12 | 13 | float LEARNING_RATE = 0.01; 14 | 15 | 16 | class Neuron { 17 | 18 | Neuron [] inputs; // Strores the neurons from the previous layer 19 | float [] weights; 20 | float output; 21 | float error; 22 | 23 | Neuron() { 24 | error = 0.0; 25 | } 26 | 27 | Neuron(Neuron [] p_inputs) { 28 | 29 | inputs = new Neuron [p_inputs.length]; 30 | weights = new float [p_inputs.length]; 31 | error = 0.0; 32 | for (int i = 0; i < inputs.length; i++) { 33 | inputs[i] = p_inputs[i]; 34 | weights[i] = random(-1.0, 1.0); 35 | } 36 | } 37 | 38 | void respond() { 39 | 40 | float input = 0.0; 41 | for (int i = 0; i < inputs.length; i++) { 42 | input += inputs[i].output * weights[i]; 43 | } 44 | output = lookupSigmoid(input); 45 | error = 0.0; 46 | } 47 | 48 | void setError(float desired) { 49 | error = desired - output; 50 | } 51 | 52 | void train() { 53 | 54 | float delta =(1.0 - output) * (1.0 + output) * 55 | error * LEARNING_RATE; 56 | for (int i = 0; i < inputs.length; i++) { 57 | inputs[i].error += weights[i] * error; 58 | weights[i] += inputs[i].output * delta; 59 | } 60 | } 61 | 62 | void display() { 63 | stroke(200); 64 | fill(128 * (1 - output)); 65 | ellipse(0, 0, 16, 16); 66 | } 67 | 68 | float [] getStrength() { 69 | float ind = 0.0; 70 | float str = 0.0; 71 | for (int i = 0; i < weights.length; i++) { 72 | if (weights[i] > str) { 73 | ind = i; 74 | str = weights[i]; 75 | } 76 | } 77 | float [] a = {ind, str}; 78 | return a; 79 | } 80 | } -------------------------------------------------------------------------------- /Part4/Part4.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | MAIN TAB 8 | 9 | Original from Alasdair Turner (c) 2009 10 | Free software: you can redistribute this program and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | */ 16 | 17 | 18 | int totalTrain = 0; 19 | int totalTest = 0; 20 | int totalRight = 0; 21 | float sucess = 0; 22 | int testCard = 0; 23 | int trainCard = 0; 24 | 25 | Network neuralnet; 26 | Button trainB, testB; 27 | 28 | void setup() { 29 | 30 | size(1000, 400); 31 | setupSigmoid(); 32 | loadData(); 33 | neuralnet = new Network(196, 49, 10); 34 | smooth(); 35 | stroke(150); 36 | 37 | trainB = new Button(width*0.06, height*0.9, "Train"); 38 | testB = new Button(width*0.11, height*0.9, "Test"); 39 | } 40 | 41 | void draw() { 42 | 43 | background(255); 44 | neuralnet.display(); 45 | 46 | fill(100); 47 | text("Test card: #" + testCard, width*0.18, height*0.89); 48 | text("Train card: " + trainCard, width*0.18, height*0.93); 49 | 50 | text("Total train: " + totalTrain, width*0.32, height*0.89); 51 | text("Total test: " + totalTest, width*0.32, height*0.93); 52 | 53 | if(totalTest>0) sucess = float(totalRight)/float(totalTest); 54 | text("Success rate: " + nfc(sucess, 2), width*0.44, height*0.89); 55 | text("Card label: " + testing_set[testCard].output, width*0.44, height*0.93); 56 | 57 | trainB.display(); 58 | testB.display(); 59 | } 60 | 61 | void mousePressed() { 62 | if (trainB.hover()) { 63 | for (int i = 0; i < 500; i++) { 64 | trainCard = (int) floor(random(0, training_set.length)); 65 | neuralnet.respond(training_set[trainCard]); 66 | neuralnet.train(training_set[trainCard].outputs); 67 | totalTrain++; 68 | } 69 | } else if (testB.hover()){ 70 | testCard = (int) floor(random(0, testing_set.length)); 71 | neuralnet.respond(testing_set[testCard]); 72 | neuralnet.display(); 73 | if(neuralnet.bestIndex == testing_set[testCard].output) totalRight ++; 74 | totalTest ++; 75 | } 76 | redraw(); 77 | } 78 | -------------------------------------------------------------------------------- /Part4/Sigmoid.pde: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Charles Fried - 2017 4 | ANN Tutorial 5 | Part #1 6 | 7 | SIGMOID 8 | Activation function 9 | 10 | A sigmoid function is the neuron's response to inputs the sigmoidal response ranges from -1.0 to 1.0 11 | For example, the weighted sum of inputs might be "2.1" our response would be lookupSigmoid(2.1) = 0.970 12 | This is a look up table for sigmoid (neural response) values which is valid from -5.0 to 5.0 13 | 14 | */ 15 | 16 | float [] g_sigmoid = new float [200]; 17 | 18 | void setupSigmoid() { 19 | 20 | for (int i = 0; i < 200; i++) { 21 | float x = (i / 20.0) - 5.0; 22 | g_sigmoid[i] = 2.0 / (1.0 + exp(-2.0 * x)) - 1.0; 23 | } 24 | } 25 | 26 | // once the sigmoid has been set up, this function accesses it: 27 | float lookupSigmoid(float x) { 28 | 29 | return g_sigmoid[constrain((int) floor((x + 5.0) * 20.0), 0, 199)]; 30 | } -------------------------------------------------------------------------------- /Part4/data/HelveticaNeue-Light-15.vlw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part4/data/HelveticaNeue-Light-15.vlw -------------------------------------------------------------------------------- /Part4/data/t10k-images-14x14.idx-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part4/data/t10k-images-14x14.idx-ubyte -------------------------------------------------------------------------------- /Part4/data/t10k-images-14x14.idx3-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlesFr/ANN_Tutorial/d4972c93d104e344ddb7226d39cbfb8751a8a5a9/Part4/data/t10k-images-14x14.idx3-ubyte -------------------------------------------------------------------------------- /Part4/data/t10k-labels.idx1-ubyte: -------------------------------------------------------------------------------- 1 | '                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ANN_Tutorial 2 | An artificial neural network for creative coders 3 | See the full article on Medium 4 | https://medium.com/typeme/lets-code-a-neural-network-from-scratch-part-1-24f0a30d7d62 5 | 6 | Original from Alasdair Turner (c) 2009 7 | https://en.wikipedia.org/wiki/Alasdair_Turner 8 | Free software: you can redistribute this program and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | --------------------------------------------------------------------------------