Skip to content
This repository was archived by the owner on Jun 30, 2022. It is now read-only.

Commit d0b8c3f

Browse files
authored
Minor fixes
Fixed weight initialization Changed activation function output to 0 or 1
1 parent 67ceab3 commit d0b8c3f

File tree

5 files changed

+190
-34
lines changed

5 files changed

+190
-34
lines changed

Color_Perceptron/Color_Perceptron.ino

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
3+
Perceptron example
4+
5+
Hardware: Arduino Nano BLE Sense
6+
7+
Usage: Follow the prompts in the Serial Monitor and show two objects of different colors to the color sensor onboard the Arduino.
8+
The sketch will train a perceptron using these examples, and then classify objects you show it in the future.
9+
10+
*/
11+
12+
#include <Arduino_APDS9960.h>
13+
#include <Arduino_Perceptron.h>
14+
15+
const int NUM_INPUTS = 3; // Classifier input is color sensor data; red, green and blue levels
16+
const int CLASSES = 2; // The perceptron only has 2 possible classes
17+
const int EXAMPLES = 30; // Number of samples for each object
18+
const int MAX_EPOCHS = 100; // Maximum training iterations
19+
const float LEARNING_RATE = 0.001; // Perceptron learning rate
20+
const int THRESHOLD = 5; // Color sensor light threshold
21+
22+
float color[NUM_INPUTS];
23+
String label[CLASSES] = {"object A", "object B"};
24+
25+
Perceptron perceptron(NUM_INPUTS, LEARNING_RATE);
26+
27+
void setup() {
28+
Serial.begin(9600);
29+
while (!Serial);
30+
31+
if (!APDS.begin()) {
32+
Serial.println("Failled to initialized APDS!");
33+
while (1);
34+
}
35+
36+
Serial.println("Arduino perceptron");
37+
38+
// Get color samples for our two objects
39+
// -------------------------------------
40+
for (int output = 0; output < 2; output ++) {
41+
42+
Serial.print("Show me ");
43+
Serial.println(label[output]);
44+
45+
// Wait for the object to move away again
46+
while (!APDS.proximityAvailable() || APDS.readProximity() == 0) {}
47+
48+
for (int n = 0; n < EXAMPLES; n++) {
49+
50+
// Sample object color - perceptron input
51+
readColor(color);
52+
53+
// Add example color to the perceptron training set
54+
perceptron.addExample(color, output);
55+
}
56+
}
57+
58+
// Train the perceptron
59+
// --------------------
60+
Serial.println("\nTraining perceptron");
61+
int epoch = 0;
62+
float accuracy = 0;
63+
64+
Serial.print("Start weights:");
65+
printWeights();
66+
67+
while (epoch < MAX_EPOCHS && accuracy < 0.99) {
68+
accuracy = perceptron.train();
69+
epoch++;
70+
Serial.print("Accuracy: ");
71+
Serial.println(accuracy);
72+
}
73+
74+
Serial.print("End weights:");
75+
printWeights();
76+
77+
78+
Serial.println("Training complete\n");
79+
}
80+
81+
82+
// Classify objects shown
83+
// ----------------------
84+
void loop() {
85+
86+
int output;
87+
88+
// Wait for the object to move away again
89+
while (!APDS.proximityAvailable() || APDS.readProximity() == 0) {}
90+
91+
Serial.println("Let me guess your object");
92+
93+
// Wait for an object then read its color
94+
readColor(color);
95+
96+
// CLassify the object using the perceptron
97+
output = perceptron.classify(color);
98+
99+
Serial.print("You showed me ");
100+
Serial.println(label[output]);
101+
}
102+
103+
104+
void printWeights() {
105+
float weights[NUM_INPUTS];
106+
perceptron.getWeights(weights);
107+
108+
Serial.print(weights[0]);
109+
Serial.print(",");
110+
Serial.print(weights[1]);
111+
Serial.print(",");
112+
Serial.println(weights[2]);
113+
}
114+
115+
void readColor(float color[]) {
116+
int red, green, blue, proximity, colorTotal = 0;
117+
118+
// Wait until we have a color bright enough
119+
while (colorTotal < THRESHOLD) {
120+
121+
// Sample if color is available and object is close
122+
if (APDS.colorAvailable() && APDS.proximityAvailable() && APDS.readProximity() == 0) {
123+
124+
// Read color and proximity
125+
APDS.readColor(red, green, blue);
126+
colorTotal = (red + green + blue);
127+
}
128+
}
129+
130+
// Normalise the color sample data and put it in the classifier input array
131+
color[0] = (float)red / colorTotal;
132+
color[1] = (float)green / colorTotal;
133+
color[2] = (float)blue / colorTotal;
134+
135+
// Print the red, green and blue values
136+
Serial.print(color[0]);
137+
Serial.print(",");
138+
Serial.print(color[1]);
139+
Serial.print(",");
140+
Serial.println(color[2]);
141+
}

examples/Color_Perceptron/Color_Perceptron.ino

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
11
/*
22
3-
Color_Perceptron.ino
3+
Perceptron example
44
5-
Perceptron color classification example
5+
Hardware: Arduino Nano BLE Sense
66
7-
Hardware: Arduino Nano 33 BLE Sense
8-
9-
Usage: Follow the prompts in the Serial Monitor and show two objects of different colors to the color sensor onboard the Arduino.
10-
The sketch will train a perceptron using these examples, and then classify objects you show it in the future.
7+
Usage: Follow the prompts in the Serial Monitor and show two objects of different colors to the color sensor onboard the Arduino.
8+
The sketch will train a perceptron using these examples, and then classify objects you show it in the future.
119
1210
*/
1311

1412
#include <Arduino_APDS9960.h>
1513
#include <Arduino_Perceptron.h>
1614

17-
const int NUM_INPUTS = 3; // Classifier has 3 inputs - red, green and blue levels
18-
const int CLASSES = 2; // The perceptron only has 2 possible outputs (-1 and 1)
19-
const int EXAMPLES = 50; // Number of samples for each object
20-
const int MAX_EPOCHS = 250; // Maximum training iterations
21-
const float LEARNING_RATE = 0.001; // Perceptron learning rate
22-
const int THRESHOLD = 5; // Color sensor light threshold
15+
const int NUM_INPUTS = 3; // Classifier input is color sensor data; red, green and blue levels
16+
const int CLASSES = 2; // The perceptron only has 2 possible classes
17+
const int EXAMPLES = 30; // Number of samples for each object
18+
const int MAX_EPOCHS = 100; // Maximum training iterations
19+
const float LEARNING_RATE = 0.001; // Perceptron learning rate
20+
const int THRESHOLD = 5; // Color sensor light threshold
2321

2422
float color[NUM_INPUTS];
2523
String label[CLASSES] = {"object A", "object B"};
2624

2725
Perceptron perceptron(NUM_INPUTS, LEARNING_RATE);
2826

29-
3027
void setup() {
3128
Serial.begin(9600);
3229
while (!Serial);
@@ -38,12 +35,12 @@ void setup() {
3835

3936
Serial.println("Arduino perceptron");
4037

41-
// Get color examples for the two objects
42-
// --------------------------------------
43-
for (int output = -1; output < 2; output += 2) {
38+
// Get color samples for our two objects
39+
// -------------------------------------
40+
for (int output = 0; output < 2; output ++) {
4441

4542
Serial.print("Show me ");
46-
printLabel(output);
43+
Serial.println(label[output]);
4744

4845
// Wait for the object to move away again
4946
while (!APDS.proximityAvailable() || APDS.readProximity() == 0) {}
@@ -64,45 +61,56 @@ void setup() {
6461
int epoch = 0;
6562
float accuracy = 0;
6663

67-
// Iterate until the perceptron is 99% accurate or we hit max epochs
64+
Serial.print("Start weights:");
65+
printWeights();
66+
6867
while (epoch < MAX_EPOCHS && accuracy < 0.99) {
6968
accuracy = perceptron.train();
7069
epoch++;
71-
7270
Serial.print("Accuracy: ");
7371
Serial.println(accuracy);
7472
}
7573

74+
Serial.print("End weights:");
75+
printWeights();
76+
77+
7678
Serial.println("Training complete\n");
7779
}
7880

7981

82+
// Classify objects shown
83+
// ----------------------
8084
void loop() {
85+
8186
int output;
8287

8388
// Wait for the object to move away again
8489
while (!APDS.proximityAvailable() || APDS.readProximity() == 0) {}
90+
8591
Serial.println("Let me guess your object");
8692

8793
// Wait for an object then read its color
8894
readColor(color);
95+
96+
// CLassify the object using the perceptron
8997
output = perceptron.classify(color);
9098

9199
Serial.print("You showed me ");
92-
printLabel(output);
100+
Serial.println(label[output]);
93101
}
94102

95103

96-
void printLabel(int output) {
97-
// Perceptron output can only be -1 or 1
98-
if (output == -1) {
99-
Serial.println(label[0]);
100-
} else {
101-
Serial.println(label[1]);
102-
}
103-
Serial.println();
104-
}
104+
void printWeights() {
105+
float weights[NUM_INPUTS];
106+
perceptron.getWeights(weights);
105107

108+
Serial.print(weights[0]);
109+
Serial.print(",");
110+
Serial.print(weights[1]);
111+
Serial.print(",");
112+
Serial.println(weights[2]);
113+
}
106114

107115
void readColor(float color[]) {
108116
int red, green, blue, proximity, colorTotal = 0;

keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Perceptron KEYWORD1
1313

1414
addExample KEYWORD2
1515
classify KEYWORD2
16+
getWeights KEYWORD2
1617

1718
clearAllClasses KEYWORD2
1819

src/Perceptron.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
#include "Perceptron.h"
2222
#include "utility/PerceptronNode.h"
2323

24-
Perceptron::Perceptron(int inputLength, float learningRate) :
24+
Perceptron::Perceptron(const int inputLength, float learningRate) :
2525
_inputLength(inputLength),
2626
_learningRate(learningRate),
2727
_weights(new float[_inputLength]),
2828
_examples(NULL)
2929
{
3030
for (int i = 0; i < _inputLength; i++) {
31-
_weights[i] = random(-1, 1);
31+
_weights[i] = (2.0*rand()/RAND_MAX)-1;;
3232
}
3333
}
3434

@@ -71,10 +71,16 @@ int Perceptron::classify(const float input[])
7171

7272
// Activation function
7373
if (sum > 0) return 1;
74-
else return -1;
74+
else return 0;
7575

7676
}
7777

78+
void Perceptron::getWeights(float * weightArray){
79+
for (int i = 0; i < _inputLength; i++) {
80+
weightArray[i] = _weights[i];
81+
}
82+
}
83+
7884
float Perceptron::train()
7985
{
8086
float count=0, correct=0;
@@ -86,13 +92,13 @@ float Perceptron::train()
8692

8793
float inputs[_inputLength];
8894

89-
9095
for (int i = 0; i < _inputLength; i++) {
9196
inputs[i] = node->input(i);
9297
}
9398

9499
int guess = classify(inputs);
95100
float error = node->class_() - guess;
101+
96102
if (error==0) {correct++;}
97103

98104
for (int i = 0; i < _inputLength; i++) {

src/Perceptron.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Perceptron {
3434
void addExample(const float input[], int class_);
3535
int classify(const float input[]);
3636
float train();
37-
37+
void getWeights(float * weightArray);
3838

3939
private:
4040
int _inputLength;

0 commit comments

Comments
 (0)