Added neuronal network

This commit is contained in:
Denys Seredenko
2024-11-13 08:33:11 +01:00
parent 4fe180d8bf
commit 5eea061dc5
7 changed files with 1947 additions and 1746 deletions

View File

@@ -24,4 +24,4 @@ class Concept(Enum):
case 'RECHTS_VOR_LINKS':
return Concept.RECHTS_VOR_LINKS
case _:
return Concept.UNKNOWN
return Concept.UNKNOWN

View File

@@ -0,0 +1,120 @@
from typing import Self
import numpy as np
import random
from collections.abc import MutableSequence
from classes.feature_vector import FeatureVector
from classes.neural.neuron import Neuron
from classes.concept import Concept
class NeuralNetwork:
def __init__(self, neurons: MutableSequence[Neuron] = None) -> None:
if neurons is None:
list_neurons = []
list_neurons.append(Neuron())
list_neurons.append(Neuron())
list_neurons.append(Neuron())
self.neurons = list_neurons
else:
self.neurons = neurons
def classify(self, feature_vector: FeatureVector) -> bool:
result = []
for neuron in self.neurons:
result.append(neuron.classify(feature_vector))
interpritated : Concept = self.interpritate(result)
if (interpritated != feature_vector.concept):
return [interpritated, False]
else:
return [interpritated, True]
# takes feature vectors to train and generates weights
def learn(self, training_set: list[FeatureVector]):
correct_amount = 0
false_amount = 0
for i in range(len(training_set)*30):
fv_to_train = random.choice(training_set)
classified_concept, correct = self.classify(fv_to_train)
if not correct:
false_amount += 1
self.update_weights(self.neurons, fv_to_train, fv_to_train.get_concept(), classified_concept)
else:
correct_amount += 1
print(f"{i}: {(correct_amount/(correct_amount + false_amount)) * 100}%")
pass
# for a sequence of 3 neurons interpretate their meaning
def interpritate(self, res: MutableSequence[int]) -> Concept:
if res == [0, 0, 0]:
return Concept.STOP
elif res == [0, 0, 1]:
return Concept.RECHTS_VOR_LINKS
elif res == [0, 1, 0]:
return Concept.LINKS_ABBIEGEN
elif res == [0, 1, 1]:
return Concept.RECHTS_ABBIEGEN
elif res == [1, 0, 0]:
return Concept.VORFAHRT_GEWAEHREN
elif res == [1, 0, 1]:
return Concept.VORFAHRT_STRASSE
else:
return Concept.UNKNOWN
def interpritate_other_way(self, c: Concept) -> Concept:
if c == Concept.STOP:
return [0, 0, 0]
elif c == Concept.RECHTS_VOR_LINKS:
return [0, 0, 1]
elif c == Concept.LINKS_ABBIEGEN:
return [0, 1, 0]
elif c == Concept.RECHTS_ABBIEGEN:
return [0, 1, 1]
elif c == Concept.VORFAHRT_GEWAEHREN:
return [1, 0, 0]
elif c == Concept.VORFAHRT_STRASSE:
return [1, 0, 1]
else:
return [1, 1, 0]
# def learn(self, training_set: list[FeatureVector]):
#
# correct_amount = 0
# false_amount = 0
# for i in range(0, 15000):
# for j in training_set:
# fv_to_train = j
# classified_concept, correct = self.classify(fv_to_train)
# if not correct:
# false_amount += 1
# self.update_weights(self.neurons, fv_to_train, fv_to_train.get_concept(), classified_concept)
# else:
# correct_amount += 1
# print(f"{i}: {(correct_amount/(correct_amount + false_amount)) * 100}%")
# pass
def update_weights(self, neuorns: MutableSequence[Neuron], x: FeatureVector, expected: Concept, computed: Concept) -> Concept:
learn_rate = 1
x.get_vector().append(1)
t = self.interpritate_other_way(expected) #[1, 1, 1]
y = self.interpritate_other_way(computed) #[1, 1, 1]
for i, neuron in enumerate(neuorns):
sigma = learn_rate * np.array(x.get_vector()) * (t[i]-y[i])
neuron.add(sigma)
x.get_vector().pop()
def print_weights(neuorns: MutableSequence[int]):
for i, neuron in neuorns:
print(f"{i} and {neuron.get_weights()}")

View File

@@ -0,0 +1,35 @@
from typing import Self
import numpy as np
from collections.abc import MutableSequence
from classes.feature_vector import FeatureVector
from classes.concept import Concept
class Neuron:
def __init__(self, weights: MutableSequence[float] = None) -> None:
if weights is None:
self.weights: np.ndarray = np.random.uniform(low=0, high=1, size=(106,))
else:
self.weights = np.asarray(weights, dtype=float)
def classify(self, feature_vector: FeatureVector) -> int:
x: list[float] = feature_vector.get_vector()
x.append(1) # adding bias
multiplication = np.dot(x, self.weights)
if (multiplication > 0):
x.pop()
return 1
else:
x.pop()
return 0
def add(self, sigma: float):
self.weights = np.add(self.weights, sigma)
def get_weights(self):
return self.weights