diff --git a/Reinforcement_Learning/Perceptrons.py b/Reinforcement_Learning/Perceptrons.py
index c9468354efa5906523d30c9aeaff57ef0f8ed596..30a297463d8a8eae59120cd81d6ba190322d67f2 100644
--- a/Reinforcement_Learning/Perceptrons.py
+++ b/Reinforcement_Learning/Perceptrons.py
@@ -2,10 +2,10 @@ import numpy as np
 import Training_data
 
 rng = np.random.default_rng(123)
-TEACHDATA = 10000
+TEACHDATA = 100000
 TESTDATA = 1000
 # ETA = 0.5
-T_NUMBER = 0
+T_NUMBER = 1  # Number to be detected 0-6
 
 
 def sigmoid(val):
@@ -13,6 +13,8 @@ def sigmoid(val):
 
 
 def linear_act(val):
+
+    # there is the option to make it linear in the valid range and make it constant otherwise
     return val
 
 
@@ -20,34 +22,79 @@ def threshold(val):
     return 1 if val > 0 else 0
 
 
-class Perceptron:
-    def __init__(self, input_count, activation=threshold):
+class Neuron:
+    test_data = Training_data.make_testset(TESTDATA)
+    teach_data = Training_data.make_testset(TEACHDATA)
+
+    def __init__(self, input_count, activation):
         self.input_count = input_count
         self.activation = activation
         self.weights = rng.random(input_count + 1)
 
-    def train_thres(self, ETA):
-        teach_data = Training_data.make_testset(TEACHDATA)
+    def test(self):
+        res = [0 for _ in range(len(Neuron.test_data))]
+        for number in range(len(Neuron.test_data)):
+            for sample in Neuron.test_data[number]:
+                ix = np.insert(sample.ravel(), 0, 1)
+                res[number] = res[number] + (self.activation(ix.dot(self.weights)))
+        return res
+
+
+class ThresholdPerceptron(Neuron):
+    def __init__(self, input_count, activation=threshold):
+        super().__init__(input_count, activation)
+
+    def train(self, ETA):
         for i in range(TEACHDATA):
             old_weights = np.copy(self.weights)
-            for j in rng.permutation(len(teach_data)):
+            for j in rng.permutation(len(Neuron.teach_data)):
                 T = 1 if j == T_NUMBER else 0
-                ix = np.insert(teach_data[j][i].ravel(), 0, 1)
+                ix = np.insert(Neuron.teach_data[j][i].ravel(), 0, 1)
                 RI = self.activation(ix.dot(self.weights))
                 if RI != T:
                     delta = ETA * \
-                        (T - self.activation(ix.dot(self.weights))) * ix
+                            (T - self.activation(ix.dot(self.weights))) * ix
                     self.weights = self.weights + delta
             if np.linalg.norm(old_weights - self.weights) == 0.00:
                 return self.weights
         return self.weights
 
-    def test(self):
-        test_data = Training_data.make_testset(TESTDATA)
-        res = [0 for _ in range(len(test_data))]
-        for number in range(len(test_data)):
-            for sample in test_data[number]:
-                ix = np.insert(sample.ravel(), 0, 1)
-                res[number] = res[number] + \
-                    (self.activation(ix.dot(self.weights)))
-        return res
+
+class SGDPerceptron(Neuron):
+    def __init__(self, input_count, activation=sigmoid):
+        super().__init__(input_count, activation)
+
+    def train(self, ETA):
+
+        for i in range(TEACHDATA):
+            old_weights = np.copy(self.weights)
+            delta = [0 for _ in range(len(old_weights))]
+            for j in rng.choice(rng.permutation(len(Neuron.teach_data)),3):
+                T = (j == T_NUMBER)
+                ix = np.insert(Neuron.teach_data[j][i].ravel(), 0, 1)
+                z = ix.dot(self.weights)
+                RI = self.activation(z)
+                delta = ETA * (T - RI) * RI * (1 - RI) * ix
+            self.weights += delta
+        return self.weights
+
+
+class LinearPerceptron(Neuron):
+    def __init__(self, input_count, activation=linear_act):
+        super().__init__(input_count, activation)
+
+    def train(self, ETA):
+        for i in range(TEACHDATA):
+            old_weights = np.copy(self.weights)
+            delta = [0 for _ in range(len(old_weights))]
+            for j in rng.permutation(len(Neuron.teach_data)):
+                T = (j == T_NUMBER)
+                ix = np.insert(Neuron.teach_data[j][i].ravel(), 0, 1)
+                delta += ETA * (T - self.activation(ix.dot(self.weights))) * ix
+            self.weights = self.weights + delta
+            if np.linalg.norm(old_weights - self.weights) == 0.00:
+                return self.weights
+        return self.weights
+
+
+
diff --git a/Reinforcement_Learning/Solution_Testing_1.py b/Reinforcement_Learning/Solution_Testing_1.py
index a308778f62f65ec507015c6ee25fff68328a3e33..1153878984efc74e3b346d96ee2f21d743c23ae2 100644
--- a/Reinforcement_Learning/Solution_Testing_1.py
+++ b/Reinforcement_Learning/Solution_Testing_1.py
@@ -1,20 +1,30 @@
+import numpy as np
+
 import Perceptrons
 import PerceptronsSGD
 
 
-def test_function(ETA):
-    input_count = 20
-
+def test_function(ETA, p):
     results = []
-    p = Perceptrons.Perceptron(input_count)
-    p.train_thres(ETA)
-    output = p.test()
+    output = np.round(p.test())
     results.append((ETA, output))
     return results
 
 
 for ETA in ([0.05, 0.1, 0.2, 0.4, 0.75, 1, 2, 5]):  # the list of values for ETA
-    for i in range(1):
-        res = test_function(ETA)
-        print(res)  # print the results list
+    w = Perceptrons.ThresholdPerceptron(20)
+    w.train(ETA)
+    x = Perceptrons.LinearPerceptron(20)
+    x.train(ETA/200)
+    y = Perceptrons.SGDPerceptron(20)
+    y.train(ETA)
+    for i in range(10):
+        res = test_function(ETA, w)
+        print("Thres", res)  # print the results list
+    for i in range(10):
+        res = test_function(ETA/200, x)
+        print("Lin", res)  # print the results list
+    for i in range(10):
+        res = test_function(ETA, y)
+        print("sgd", res)  # print the results list
     print("\n\n")
diff --git a/Reinforcement_Learning/Training_data.py b/Reinforcement_Learning/Training_data.py
index c88a47210a571897e5f6c5331b3d8fb738903f15..88da7d33e151fdeb22f65af1595fdfa0538fa80d 100644
--- a/Reinforcement_Learning/Training_data.py
+++ b/Reinforcement_Learning/Training_data.py
@@ -53,6 +53,8 @@ def make_testset(set_size):
         if set_size > 1:
             data[number].append(value)
         for _ in range(set_size):
+            # scale is the standard deviation affecting the "spread" plays a role int eh results
+            # new_digit = ideal[number] + rng.normal(loc=0, scale=0.3, size=(5, 4))
             new_digit = ideal[number] + rng.normal(loc=0, scale=0.1, size=(5, 4))
             data[number].append(new_digit)
     return data