Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
ff6de2c7e4
93
Marcin.md
Normal file
93
Marcin.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# Podprojekt - sieć neuronowa"
|
||||||
|
**Twórca: Marcin Kwapisz**
|
||||||
|
|
||||||
|
**Klawisz F7 uruchamia program**
|
||||||
|
|
||||||
|
Program otrzymuje zdjęcie aktualnego pola i za
|
||||||
|
pomocą sieci neuronowej określa jakie to jest pole
|
||||||
|
i wybiera tryb w jakim ma pracować traktor
|
||||||
|
|
||||||
|
Sieć neuronowa została nauczona przy użyciu modułu darknet. Sieć została użyta po
|
||||||
|
20000 iteracjach treningowych
|
||||||
|
|
||||||
|
**Main**
|
||||||
|
```
|
||||||
|
def main(self):
|
||||||
|
self.pole = self.ui.field_images[self.field.get_value(self.traktor.get_poz())]
|
||||||
|
self.img = pygame.surfarray.array3d(self.pole)
|
||||||
|
self.img = self.img.transpose([1,0,2])
|
||||||
|
self.img = cv2.cvtColor(self.img, cv2.COLOR_RGB2BGR)
|
||||||
|
self.reco = self.mode(self.recognition(self.img))
|
||||||
|
if self.reco == 10:
|
||||||
|
print("Nic nie trzeba robić")
|
||||||
|
else:
|
||||||
|
self.traktor.set_mode(self.reco)
|
||||||
|
```
|
||||||
|
Wywołuje wszystkie pozostałe funkcje programu
|
||||||
|
|
||||||
|
**Get_output_layers**
|
||||||
|
```
|
||||||
|
def get_output_layers(self,net):
|
||||||
|
layer_names = net.getLayerNames()
|
||||||
|
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
|
||||||
|
return output_layers
|
||||||
|
```
|
||||||
|
Zwraca nazwy kolejnych warstw, warstwa wyjściowa nie jest połączona z żadną następną warstwą
|
||||||
|
|
||||||
|
**Recognition**
|
||||||
|
```
|
||||||
|
def recognition(self,photo):
|
||||||
|
image = photo
|
||||||
|
|
||||||
|
Width = image.shape[1]
|
||||||
|
Height = image.shape[0]
|
||||||
|
scale = 0.00392
|
||||||
|
|
||||||
|
with open("si.names", 'r') as f:
|
||||||
|
classes = [line.strip() for line in f.readlines()]
|
||||||
|
|
||||||
|
COLORS = np.random.uniform(0, 255, size=(len(classes), 3))
|
||||||
|
|
||||||
|
net = cv2.dnn.readNet("si_20000.weights", "si.cfg")
|
||||||
|
|
||||||
|
blob = cv2.dnn.blobFromImage(image, scale, (416, 416), (0, 0, 0), True, crop=False)
|
||||||
|
|
||||||
|
net.setInput(blob)
|
||||||
|
|
||||||
|
outs = net.forward(self.get_output_layers(net))
|
||||||
|
|
||||||
|
class_ids = []
|
||||||
|
confidences = []
|
||||||
|
boxes = []
|
||||||
|
conf_threshold = 0.5
|
||||||
|
nms_threshold = 0.4
|
||||||
|
|
||||||
|
for out in outs:
|
||||||
|
for detection in out:
|
||||||
|
scores = detection[5:]
|
||||||
|
class_id = np.argmax(scores)
|
||||||
|
confidence = scores[class_id]
|
||||||
|
if confidence > 0.5:
|
||||||
|
class_ids.append(class_id)
|
||||||
|
return class_ids[0]
|
||||||
|
```
|
||||||
|
Odpowiada za odebranie zdjęcia od funkcji głównej i
|
||||||
|
używa sieci neuronowej do rozpoznania zdjęcia
|
||||||
|
|
||||||
|
**Mode**
|
||||||
|
```
|
||||||
|
def mode(self,mode):
|
||||||
|
self.mode_value = mode
|
||||||
|
if self.mode_value in [0, 1, 2, 3]:
|
||||||
|
return 0
|
||||||
|
elif self.mode_value in [1, 3, 5, 7]:
|
||||||
|
return 1
|
||||||
|
elif self.mode_value in [0, 1, 4, 5]:
|
||||||
|
return 2
|
||||||
|
elif self.mode_value in [8]:
|
||||||
|
return 3
|
||||||
|
elif self.mode_value in [6]:
|
||||||
|
return 10
|
||||||
|
```
|
||||||
|
Na podstawie klasy otrzymanej przez funkcję **recognition** wybiera tryb
|
||||||
|
w jakim ma pracować traktor
|
15
Marcin.py
15
Marcin.py
@ -9,6 +9,7 @@ class main():
|
|||||||
self.field = field
|
self.field = field
|
||||||
self.ui = ui
|
self.ui = ui
|
||||||
self.path = path
|
self.path = path
|
||||||
|
self.mode_value = 0
|
||||||
|
|
||||||
def get_output_layers(self,net):
|
def get_output_layers(self,net):
|
||||||
layer_names = net.getLayerNames()
|
layer_names = net.getLayerNames()
|
||||||
@ -27,7 +28,7 @@ class main():
|
|||||||
|
|
||||||
COLORS = np.random.uniform(0, 255, size=(len(classes), 3))
|
COLORS = np.random.uniform(0, 255, size=(len(classes), 3))
|
||||||
|
|
||||||
net = cv2.dnn.readNet("si_final.weights", "si.cfg")
|
net = cv2.dnn.readNet("si_20000.weights", "si.cfg")
|
||||||
|
|
||||||
blob = cv2.dnn.blobFromImage(image, scale, (416, 416), (0, 0, 0), True, crop=False)
|
blob = cv2.dnn.blobFromImage(image, scale, (416, 416), (0, 0, 0), True, crop=False)
|
||||||
|
|
||||||
@ -48,16 +49,18 @@ class main():
|
|||||||
confidence = scores[class_id]
|
confidence = scores[class_id]
|
||||||
if confidence > 0.5:
|
if confidence > 0.5:
|
||||||
class_ids.append(class_id)
|
class_ids.append(class_id)
|
||||||
print(class_id)
|
return class_ids[0]
|
||||||
print(scores)
|
|
||||||
return class_id
|
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
self.pole = self.ui.field_images[self.field.get_value(self.traktor.get_poz())]
|
self.pole = self.ui.field_images[self.field.get_value(self.traktor.get_poz())]
|
||||||
self.img = pygame.surfarray.array3d(self.pole)
|
self.img = pygame.surfarray.array3d(self.pole)
|
||||||
self.img = self.img.transpose([1,0,2])
|
self.img = self.img.transpose([1,0,2])
|
||||||
self.img = cv2.cvtColor(self.img, cv2.COLOR_RGB2BGR)
|
self.img = cv2.cvtColor(self.img, cv2.COLOR_RGB2BGR)
|
||||||
self.traktor.set_mode(self.mode(self.recognition(self.img)))
|
self.reco = self.mode(self.recognition(self.img))
|
||||||
|
if self.reco == 10:
|
||||||
|
print("Nic nie trzeba robić")
|
||||||
|
else:
|
||||||
|
self.traktor.set_mode(self.reco)
|
||||||
|
|
||||||
def mode(self,mode):
|
def mode(self,mode):
|
||||||
self.mode_value = mode
|
self.mode_value = mode
|
||||||
@ -69,3 +72,5 @@ class main():
|
|||||||
return 2
|
return 2
|
||||||
elif self.mode_value in [8]:
|
elif self.mode_value in [8]:
|
||||||
return 3
|
return 3
|
||||||
|
elif self.mode_value in [6]:
|
||||||
|
return 10
|
||||||
|
119
decisiontree.md
119
decisiontree.md
@ -2,10 +2,125 @@
|
|||||||
|
|
||||||
**Członkowie zespołu:** Marcin Kwapisz, Kamila Matysiak, Piotr Rychlicki, Justyna Zarzycka
|
**Członkowie zespołu:** Marcin Kwapisz, Kamila Matysiak, Piotr Rychlicki, Justyna Zarzycka
|
||||||
|
|
||||||
**Temat podprojektu:** Wybór trybu pracy traktora za pomocą drzewa decyzyjnego
|
|
||||||
|
|
||||||
**Autor podprojektu:** Kamila Matysiak
|
**Autor podprojektu:** Kamila Matysiak
|
||||||
|
|
||||||
|
|
||||||
### Drzewo Decyzyjne
|
### Drzewo Decyzyjne
|
||||||
|
|
||||||
|
Projekt wykorzystuje drzewo decyzyjne do wybrania czynności dla każdego pola, a następnie wysłania traktora do pól zgodnych z obecnie wybranym trybem.
|
||||||
|
|
||||||
|
Projekt używa metody CART (Classification and Regression Tree). Tworzy on drzewo binarne, w którym rozpatruje wszystkie możliwe podziały zbioru wartości cech na dwa rozłączne i uzupełniające się podzbiory dla cech dyskretnych.
|
||||||
|
|
||||||
|
Uruchamia się go za pomocą klawisza **F6**.
|
||||||
|
|
||||||
|
#### Zbiór uczący:
|
||||||
|
|
||||||
|
Zbiorem uczącym jest zestaw danych informujących drzewo jak postępować z polem o danych parametrach.
|
||||||
|
Kolejne cyfry odpowiadają za: nawodnienie pola, obecność chwastów, czy pole jest puste, czy jest do zbioru.
|
||||||
|
|
||||||
|
```
|
||||||
|
training_data = [[0, 0, 1, 0, "Zasadzic"],
|
||||||
|
[0, 1, 1, 0, "Odchwascic"],
|
||||||
|
[0, 0, 0, 0, "Podlac"],
|
||||||
|
[0, 1, 0, 0, "Odchwascic"],
|
||||||
|
[1, 0, 1, 0, "Zasadzic"],
|
||||||
|
[1, 1, 1, 0, "Odchwascic"],
|
||||||
|
[1, 0, 0, 0, "Czekac"],
|
||||||
|
[1, 1, 0, 0, "Odchwascic"],
|
||||||
|
[0, 0, 0, 1, "Zebrac"]]
|
||||||
|
self.tree = build_tree(training_data)
|
||||||
|
print_tree(self.tree)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Algotytm tworzenia drzewa:
|
||||||
|
|
||||||
|
Budowanie drzewa zaczynamy od stworzenia klasy **Question**, w której będziemy tworzyć zapytanie, na podstawie którego będziemy dzielić nasze dane. Następnie tworzymy funkcję **partition**, która na podstawie zapytania dzieli nam dane na spełnione i niespełnione wiersze:
|
||||||
|
|
||||||
|
```
|
||||||
|
# podział danych na spełnione i niespełnione wiersze
|
||||||
|
def partition(rows, question):
|
||||||
|
true_rows, false_rows = [], []
|
||||||
|
for row in rows:
|
||||||
|
if question.match(row):
|
||||||
|
true_rows.append(row)
|
||||||
|
else:
|
||||||
|
false_rows.append(row)
|
||||||
|
return true_rows, false_rows
|
||||||
|
```
|
||||||
|
|
||||||
|
Następnie wyokrzystujemy **Index Gini**, który mierzy jak często losowo wybrany element będzie źle zindentyfikowany. Gdy jest równy 0, oznacza to, że element zostanie właściwie oznaczony.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
# funkcja implementująca indeks gini
|
||||||
|
def gini(rows):
|
||||||
|
counts = class_counts(rows)
|
||||||
|
impurity = 1
|
||||||
|
for lbl in counts:
|
||||||
|
prob_of_lbl = counts[lbl] / float(len(rows))
|
||||||
|
impurity -= prob_of_lbl ** 2
|
||||||
|
return impurity
|
||||||
|
|
||||||
|
def info_gain(left, right, current_uncertainty):
|
||||||
|
p = float(len(left)) / (len(left) + len(right))
|
||||||
|
return current_uncertainty - p * gini(left) - (1 - p) * gini(right)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Następnie na podstawie uzykanych informacji, znajdujemy najlepsze miejsce na podział danych:
|
||||||
|
|
||||||
|
```
|
||||||
|
# znalezienie najlepszego "miejsca" na podział danych
|
||||||
|
def find_best_split(rows):
|
||||||
|
best_gain = 0
|
||||||
|
best_question = None
|
||||||
|
current_uncertainty = gini(rows)
|
||||||
|
n_features = len(rows[0]) - 1
|
||||||
|
for col in range(n_features):
|
||||||
|
values = set([row[col] for row in rows])
|
||||||
|
for val in values:
|
||||||
|
question = Question(col, val)
|
||||||
|
true_rows, false_rows = partition(rows, question)
|
||||||
|
if len(true_rows) == 0 or len(false_rows) == 0:
|
||||||
|
continue
|
||||||
|
gain = info_gain(true_rows, false_rows, current_uncertainty)
|
||||||
|
if gain >= best_gain:
|
||||||
|
best_gain, best_question = gain, question
|
||||||
|
return best_gain, best_question
|
||||||
|
```
|
||||||
|
|
||||||
|
Po stworzeniu klas definiujących liść i węzęł deycyzyjny przechodzimy do właściwej funkcji **build_tree*:
|
||||||
|
```
|
||||||
|
# funkcja budująca drzewo
|
||||||
|
def build_tree(rows):
|
||||||
|
gain, question = find_best_split(rows) # znalezienie najlepszego podziału
|
||||||
|
if gain == 0:
|
||||||
|
return Leaf(rows)
|
||||||
|
true_rows, false_rows = partition(rows, question) # podział danych
|
||||||
|
|
||||||
|
true_branch = build_tree(true_rows)
|
||||||
|
false_branch = build_tree(false_rows) #stworzenie gałęzi prawdy i fałszu
|
||||||
|
|
||||||
|
return DecisionNode(question, true_branch, false_branch)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Integracja:
|
||||||
|
|
||||||
|
Program sczytuje dane z głównego projektu, następnie interpretuje je za pomocą prostej funkcji **translate**, która zwraca informacje o stanie pola. Następnie za pomocą drzewa określamy czynność, jaka powinna zostać wykonana na tym polu. Wykonanie pracy zlecamy klasie **pathfinding**, która za pomocą algorytmu A* wysyła traktor na pola odpowiadające wybranemu trybowi.
|
||||||
|
|
||||||
|
```
|
||||||
|
def search_field(self):
|
||||||
|
matrix = self.field.get_matrix()
|
||||||
|
for i in range(len(matrix)):
|
||||||
|
for j in range(len(matrix[i])):
|
||||||
|
print("Pole (%d,%d) Przewidziania czynnosc: %s"
|
||||||
|
% (i, j, print_leaf(classify(translate(matrix[i][j]), self.tree))))
|
||||||
|
if work[self.traktor.get_mode()] in self.work_field(classify(translate(matrix[i][j]), self.tree)):
|
||||||
|
print("Zgodna z aktualnym trybem, czynnosc wykonywana")
|
||||||
|
self.path.find_path(self.traktor, self.field, self.ui, [j, i])
|
||||||
|
self.ui.update()
|
||||||
|
time.sleep(0.5)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
9
ui.py
9
ui.py
@ -1,5 +1,5 @@
|
|||||||
import pygame
|
import pygame
|
||||||
|
import random
|
||||||
class game_ui():
|
class game_ui():
|
||||||
|
|
||||||
def __init__(self,traktor,field):
|
def __init__(self,traktor,field):
|
||||||
@ -34,8 +34,11 @@ class game_ui():
|
|||||||
self.pole1_surf_rect.y = self.POLE_POZ[1] - 75
|
self.pole1_surf_rect.y = self.POLE_POZ[1] - 75
|
||||||
self.traktor_img = ["traktor_d.png", "traktor_l.png", "traktor_u.png", "traktor_r.png"]
|
self.traktor_img = ["traktor_d.png", "traktor_l.png", "traktor_u.png", "traktor_r.png"]
|
||||||
self.field_images = []
|
self.field_images = []
|
||||||
for i in ['gleba_pix.png','gleba_chwasty_pix.png','sadzonka_suchi_pix.png','sadzonka_chwasty_pix.png','gleba_mokra_pix.png','gleba_mokra_chwasty.png','sadzonka_mokra_pix.png','sadzonka_mokra_chwasty_pix.png','gotowy_burak_pix.png']:
|
# self.field_images_path = []
|
||||||
self.field_images.append(pygame.image.load('images/'+i))
|
# self.random = random.randint(0,99)
|
||||||
|
for i in ['gleba_pix','gleba_chwasty_pix','sadzonka_suchi_pix','sadzonka_chwasty_pix','gleba_mokra_pix','gleba_mokra_chwasty','sadzonka_mokra_pix','sadzonka_mokra_chwasty_pix','gotowy_burak_pix']:
|
||||||
|
# self.field_images_path.append("images/"+i+"/"+i+str(self.random)+".png")
|
||||||
|
self.field_images.append(pygame.image.load("images/"+i+".png"))
|
||||||
|
|
||||||
# Zezwalamy na przechwytywanie klawiszy
|
# Zezwalamy na przechwytywanie klawiszy
|
||||||
pygame.event.pump()
|
pygame.event.pump()
|
||||||
|
Loading…
Reference in New Issue
Block a user