From c6243c84c7c2541753531970c49dd73bb6858ab1 Mon Sep 17 00:00:00 2001
From: Michael Mutote <130656746+mr1Michael@users.noreply.github.com>
Date: Wed, 15 Nov 2023 23:29:30 +0100
Subject: [PATCH] 22202956 - First Perceptron. varying ETA values, smaller ETA
 VALUES ARE NOT GOOD! but works reliably, Nest update will have more dest data

---
 Reinforcement_Learning/Perceptrons.py   | 60 +++++++++++++++++++++++++
 Reinforcement_Learning/Training_data.py | 58 ++++++++++++++++++++++++
 2 files changed, 118 insertions(+)
 create mode 100644 Reinforcement_Learning/Perceptrons.py
 create mode 100644 Reinforcement_Learning/Training_data.py

diff --git a/Reinforcement_Learning/Perceptrons.py b/Reinforcement_Learning/Perceptrons.py
new file mode 100644
index 0000000..76aeb17
--- /dev/null
+++ b/Reinforcement_Learning/Perceptrons.py
@@ -0,0 +1,60 @@
+import numpy as np
+import Training_data
+
+rng = np.random.default_rng(123)
+TEACHDATA = 90000
+TESTDATA = 1
+# ETA = 0.5
+T_NUMBER = 3
+
+
+def threshold(val):
+    return 1 if val > 0 else 0
+
+
+class Perceptron:
+    def __init__(self, input_count, activation=threshold):
+        self.input_count = input_count
+        self.activation = activation
+        self.weights = rng.random(input_count + 1) * 0.3
+
+    def train(self, ETA):
+        teach_data = Training_data.make_testset(TEACHDATA)
+        for i in rng.permutation(TEACHDATA):
+            old_weights = np.copy(self.weights)
+            for j in rng.permutation(len(teach_data)):
+                T = 1 if j == T_NUMBER else 0
+                ix = np.insert(teach_data[j][i].ravel(), 0, 1)
+                # for wx in rng.permutation(len(ix)):
+                RI = self.activation(ix.dot(self.weights))
+                if not RI == T:
+                    delta = ETA * (T - self.activation(ix.dot(self.weights))) * ix
+                    self.weights = self.weights + delta
+            if np.linalg.norm(old_weights - self.weights) <= 0.00000000001:
+                return self.weights
+        return self.weights
+
+    def test(self):
+        test_data = Training_data.make_testset(TESTDATA)
+        # print(test_data)
+        res = []
+        for number in test_data:
+            # print(number[0])
+            ix = np.insert(number[0].ravel(), 0, 1)
+            res.append(self.activation(ix.dot(self.weights)))
+        return res
+
+
+def test_function():
+    input_count = 20  # the number of elements in each input array
+    ETA_list = [0.0001, 0.001, 0.01, 0.1, 0.5, 1, 1.5, 2]  # the list of values for ETA
+    results = []  # the list of results for each ETA value
+    for ETA in ETA_list:
+        p = Perceptron(input_count)  # create a perceptron instance
+        p.train(ETA)  # train the perceptron with the given ETA value
+        output = p.test()  # test the perceptron on a single test pattern
+        results.append((ETA, output))  # append the ETA value and the output to the results list
+    return results  # return the results list
+
+
+print(test_function())  # print the results list
diff --git a/Reinforcement_Learning/Training_data.py b/Reinforcement_Learning/Training_data.py
new file mode 100644
index 0000000..c88a472
--- /dev/null
+++ b/Reinforcement_Learning/Training_data.py
@@ -0,0 +1,58 @@
+import numpy as np
+import copy
+
+ideal = dict([])
+
+ideal[0] = np.array([[0, 1, 1, 0],
+                     [1, 0, 0, 1],
+                     [1, 0, 0, 1],
+                     [1, 0, 0, 1],
+                     [0, 1, 1, 0]])
+
+ideal[1] = np.array([[0, 0, 1, 0],
+                     [0, 1, 1, 0],
+                     [0, 0, 1, 0],
+                     [0, 0, 1, 0],
+                     [0, 0, 1, 0]])
+
+ideal[2] = np.array([[0, 1, 1, 0],
+                     [1, 0, 0, 1],
+                     [0, 0, 1, 0],
+                     [0, 1, 0, 0],
+                     [1, 1, 1, 1]])
+
+ideal[3] = np.array([[0, 1, 1, 0],
+                     [1, 0, 0, 1],
+                     [0, 0, 1, 0],
+                     [1, 0, 0, 1],
+                     [0, 1, 1, 0]])
+
+ideal[4] = np.array([[0, 0, 1, 0],
+                     [0, 1, 1, 0],
+                     [1, 0, 1, 0],
+                     [1, 1, 1, 1],
+                     [0, 0, 1, 0]])
+
+ideal[5] = np.array([[1, 1, 1, 1],
+                     [1, 0, 0, 0],
+                     [1, 1, 1, 0],
+                     [0, 0, 0, 1],
+                     [1, 1, 1, 0]])
+
+ideal[6] = np.array([[0, 1, 1, 0],
+                     [1, 0, 0, 0],
+                     [1, 1, 1, 0],
+                     [1, 0, 0, 1],
+                     [0, 1, 1, 0]])
+
+
+def make_testset(set_size):
+    data = [[] for _ in range(len(ideal))]
+    rng = np.random.default_rng(123)
+    for number, value in ideal.items():
+        if set_size > 1:
+            data[number].append(value)
+        for _ in range(set_size):
+            new_digit = ideal[number] + rng.normal(loc=0, scale=0.1, size=(5, 4))
+            data[number].append(new_digit)
+    return data
-- 
GitLab