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

Commit 6a937cc

Browse files
authored
Initial version
0 parents  commit 6a937cc

10 files changed

+981
-0
lines changed

LICENSE

Lines changed: 504 additions & 0 deletions
Large diffs are not rendered by default.

README.adoc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
= Perceptron Library for Arduino =
2+
3+
Arduino library for the Perceptron algorithm.
4+
5+
== License ==
6+
7+
Copyright (c) 2020 Arduino SA. All rights reserved.
8+
9+
This library is free software; you can redistribute it and/or
10+
modify it under the terms of the GNU Lesser General Public
11+
License as published by the Free Software Foundation; either
12+
version 2.1 of the License, or (at your option) any later version.
13+
14+
This library is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
Lesser General Public License for more details.
18+
19+
You should have received a copy of the GNU Lesser General Public
20+
License along with this library; if not, write to the Free Software
21+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
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 (-1 and 1)
17+
const int EXAMPLES = 50; // Number of samples for each object
18+
const int MAX_EPOCHS = 250; // 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 examples for the two possible outputs, -1 and 1
39+
// ---------------------------------------------------
40+
for (int output = -1; output < 2; output += 2) {
41+
42+
Serial.print("Show me ");
43+
printLabel(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+
while (epoch < MAX_EPOCHS && accuracy < 0.99) {
65+
accuracy = perceptron.train();
66+
epoch++;
67+
68+
Serial.print("Accuracy: ");
69+
Serial.println(accuracy);
70+
}
71+
72+
Serial.println("Training complete\n");
73+
}
74+
75+
76+
void loop() {
77+
78+
int output;
79+
80+
// Wait for the object to move away again
81+
while (!APDS.proximityAvailable() || APDS.readProximity() == 0) {}
82+
83+
Serial.println("Let me guess your object");
84+
85+
// Wait for an object then read its color
86+
readColor(color);
87+
88+
output = perceptron.classify(color);
89+
90+
Serial.print("You showed me ");
91+
printLabel(output);
92+
}
93+
94+
void printLabel(int output) {
95+
if (output == -1) {
96+
Serial.println(label[0]);
97+
} else {
98+
Serial.println(label[1]);
99+
}
100+
Serial.println();
101+
}
102+
103+
void readColor(float color[]) {
104+
int red, green, blue, proximity, colorTotal = 0;
105+
106+
// Wait until we have a color bright enough
107+
while (colorTotal < THRESHOLD) {
108+
109+
// Sample if color is available and object is close
110+
if (APDS.colorAvailable() && APDS.proximityAvailable() && APDS.readProximity() == 0) {
111+
112+
// Read color and proximity
113+
APDS.readColor(red, green, blue);
114+
colorTotal = (red + green + blue);
115+
}
116+
}
117+
118+
// Normalise the color sample data and put it in the classifier input array
119+
color[0] = (float)red / colorTotal;
120+
color[1] = (float)green / colorTotal;
121+
color[2] = (float)blue / colorTotal;
122+
123+
// Print the red, green and blue values
124+
Serial.print(color[0]);
125+
Serial.print(",");
126+
Serial.print(color[1]);
127+
Serial.print(",");
128+
Serial.println(color[2]);
129+
}

keywords.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#######################################
2+
# Syntax Coloring Map For Arduino_Perceptron
3+
#######################################
4+
# Class
5+
#######################################
6+
7+
Arduino_Perceptron KEYWORD1
8+
Perceptron KEYWORD1
9+
10+
#######################################
11+
# Methods and Functions
12+
#######################################
13+
14+
addExample KEYWORD2
15+
classify KEYWORD2
16+
17+
clearAllClasses KEYWORD2
18+
19+
#######################################
20+
# Constants
21+
#######################################

library.properties

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=Arduino_Perceptron
2+
version=0.0.0
3+
author=Arduino
4+
maintainer=Arduino <info@arduino.cc>
5+
sentence=[BETA]
6+
paragraph=
7+
category=Data Processing
8+
url=
9+
architectures=*

src/Arduino_Perceptron.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
This file is part of the Arduino_Perceptron library.
3+
Copyright (c) 2020 Arduino SA. All rights reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#ifndef _ARDUINO_PERCEPTRON_H_
21+
#define _ARDUINO_PERCEPTRON_H_
22+
23+
#include "Perceptron.h"
24+
25+
#endif

src/Perceptron.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
This file is part of the Arduino_Perceptron library.
3+
Copyright (c) 2020 Arduino SA. All rights reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#include <float.h>
21+
#include "Perceptron.h"
22+
#include "utility/PerceptronNode.h"
23+
24+
Perceptron::Perceptron(int inputLength, float learningRate) :
25+
_inputLength(inputLength),
26+
_learningRate(learningRate),
27+
_weights(new float[_inputLength]),
28+
_examples(NULL)
29+
{
30+
for (int i = 0; i < _inputLength; i++) {
31+
_weights[i] = random(-1, 1);
32+
}
33+
}
34+
35+
Perceptron::~Perceptron()
36+
{
37+
clearAllClasses();
38+
}
39+
40+
void Perceptron::addExample(const float input[], int class_)
41+
{
42+
// create new node
43+
PerceptronNode* newNode = new PerceptronNode(input, _inputLength, class_);
44+
45+
// add new node to examples list
46+
if (_examples == NULL) {
47+
_examples = newNode;
48+
} else {
49+
PerceptronNode* node = _examples;
50+
51+
while (1) {
52+
PerceptronNode* next = node->next();
53+
54+
if (next == NULL) {
55+
node->setNext(newNode);
56+
57+
break;
58+
}
59+
60+
node = next;
61+
}
62+
}
63+
}
64+
65+
int Perceptron::classify(const float input[])
66+
{
67+
float sum = 0;
68+
for (int i = 0; i < _inputLength; i++) {
69+
sum += input[i] * _weights[i];
70+
}
71+
72+
// Activation function
73+
if (sum > 0) return 1;
74+
else return -1;
75+
76+
}
77+
78+
float Perceptron::train()
79+
{
80+
float count=0, correct=0;
81+
82+
PerceptronNode* node = _examples;
83+
84+
while (node != NULL) {
85+
count++;
86+
87+
float inputs[_inputLength];
88+
89+
90+
for (int i = 0; i < _inputLength; i++) {
91+
inputs[i] = node->input(i);
92+
}
93+
94+
int guess = classify(inputs);
95+
float error = node->class_() - guess;
96+
if (error==0) {correct++;}
97+
98+
for (int i = 0; i < _inputLength; i++) {
99+
_weights[i] += _learningRate * error * inputs[i];
100+
}
101+
node = node->next();
102+
}
103+
104+
return correct/count;
105+
}
106+
107+
void Perceptron::clearAllClasses()
108+
{
109+
PerceptronNode* node = _examples;
110+
111+
while (node != NULL) {
112+
PerceptronNode* next = node->next();
113+
114+
delete node;
115+
116+
node = next;
117+
}
118+
119+
_examples = NULL;
120+
}

src/Perceptron.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
This file is part of the Arduino_Perceptron library.
3+
Copyright (c) 2020 Arduino SA. All rights reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#ifndef _PERCEPTRON_H_
21+
#define _PERCEPTRON_H_
22+
23+
#include <Arduino.h>
24+
25+
26+
class PerceptronNode;
27+
28+
class Perceptron {
29+
public:
30+
Perceptron(int inputLength, float learningRate);
31+
virtual ~Perceptron();
32+
33+
void clearAllClasses();
34+
void addExample(const float input[], int class_);
35+
int classify(const float input[]);
36+
float train();
37+
38+
39+
private:
40+
int _inputLength;
41+
float _learningRate;
42+
float* _weights;
43+
PerceptronNode* _examples;
44+
};
45+
46+
#endif

0 commit comments

Comments
 (0)