6.3 KiB
Raport przygotował: Dawid Korybalski
Raportowany okres: 29 kwietnia - 12 maja 2020
Niniejszy raport poświęcony jest przekazaniu informacji na temat stanu podprojektu indywidualnego w ramach projektu grupowego realizowanego na przedmiot Sztuczna Inteligencja w roku akademickim 2019/2020.
Tematem realizowanego projektu indywidualnego jest stworzenie sztucznej inteligencji rozpoznającej z podanych pparametrów, czy śmieci wsytawione są wielkogabarytowe, czy nie (ocenia to w 4-wartościowej skali - 0 - nie są to śmieci wielkogabarytowe, 1 - raczej nie są to śmieci wielkogabarytowe, 2 - raczej są to śmieci wielkogabarytowe i 3 - są to śmieci wielkogabarytowe). Do osiągnięcia celu wykorzystałem wartwowe sieci neuronowe (MLP) oraz następujące biblioteki:
- scikit - learn
- joblib
- matplotlib
Uczenie modelu
Dane wejściowe:
Do utworzenia modelu wykorzzystałem losowo stworzoną tablicę zawierającą krotki z następującymi danymi:
- budżet (od $300 do $1000);
- populacje danego domu (ilu jest w nim mieszkańców - od 2 do 7);
- przychody danej rodziny (od 2000 do 11000);
- ilość dzieci w domu (od 2 do 4);
- wskazanie rozmiaru śmieci (czy są wielkogabarytowe)
Proces uczenia:
Na początku dane są tworzone w pętli:
data = []
for size in range(4):
for x in range(40000):
if size == 0:
budget = random.randint(300, 450)
population = random.randint(2, 4)
income = random.randint(2000, 3000)
children = random.randint(0, 2)
elif size == 1:
budget = random.randint(400, 600)
population = random.randint(3, 5)
income = random.randint(3000, 5000)
children = random.randint(0, 3)
elif size == 2:
budget = random.randint(550, 800)
population = random.randint(4, 6)
income = random.randint(4500, 7000)
children = random.randint(0, 4)
else:
budget = random.randint(700, 1000)
population = random.randint(4, 7)
income = random.randint(6800, 11000)
children = random.randint(1, 4)
data.append([
budget,
population,
income,
children,
size
])
Następnie dane dziele na zestaw cech (data) i zestaw posiadający wielkość śmieci zapisaną (labels):
labels = [x[4] for x in data]
for x in range(len(data)):
del data[x][4]
Następnie definuje sieć neuronową. Zbiory utworzone przed chwilą, przy wykorzystaniu funkcji train_test_split z biblioteki scikat-learn, są dzielone na zestawy do uczenia się i testowania (x_train, x_test, y_train, y_test). test_size = 0.3 oznacza, że zbiór danych testowych składa się z 30% krotek zestawu początkowego:
mlp = MLPClassifier()
X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.3)
W następnej lini ładuję do naszej sieci neuronowej załadowane wcześniej zbiory danych:
mlp.fit(X_train, y_train)
Następnie model zostaje poddany testowi i obliczony jest wskażnik trafności (precyzji) wygenerowanych wyników na zbiorze testowym. Wskaźnik ten, dla liczby 40000 utworzonych wyników zwraca wynik ponad 95% trafności:
pred = mlp.predict(X_test)
print(accuracy_score(y_test, pred))
Wkonałem test dla 20 zbiorów po 40000 tysięcy wyników w każdym "size" i średnia trafności to 96,2%.
Biblioteka z której korzystam (sklearn) umożliwia stworzenie macierzy, która pokazuje nam trafność uczenia się z faktycznym stanem. Poniżej jest macierz, która przestawia wyniki uczenia się dla 1 miliona rezultatów w każym size(czyli przeprowadzono nauke dla 300k wyników w każdym size)
Tutaj macierz dla naszych danych wejściowych, czyli dla 40k rezultatów w każdym size (czyli przeprowadzono naukę dla 12k wyników w każdym z 4. rozmiarów śmieci)
Integracja z projektem
Po urucchomieniu programu, należy nacisnąć klawisz d na klawiaturze, dzięki czemu zostanie uruchomiony następujący kod w main.py
if event.key == pygame.K_d:
if DQN_ENV.is_done(__gc__=GC, draw_items=DRAW_ITEMS):
print('Ukończono prace agenta. Abu użyć wybranego algorytmu, zresetruj program.')
else:
messagebox.showinfo("Powitanie", "Witaj. Zaraz rozpocznie się uczenie programu do zbierania śmieci wielkogabarytowych, a potem mniejszych śmieci. Prosimy o cierpliwość")
HOUSES, _ = __a_star__.houses_with_trash()
predictions = predict_houses([house.data for house in HOUSES])
for x in range(len(HOUSES)):
HOUSES[x].size = predictions[x]
messagebox.showinfo("Koniec nauki", "Zakończono nauke. Teraz wykorzystując zmodyfikowany algorytm A* śmieciarka zbierze śmieci")
RUN_D = True
Idąc od góry, sprawdzamy, czy znajdują się jeszcze jakieś śmieci na mapie. Jeśli nie, to informujemy o tym w terminalu, jeśli tak, to wyświetlamy okienko z powitaniem, następnie wykorzystuje zdefiniowaną wcześniej (w algorytmie a_star) funkcję do zapisywania wszystkich domów w tablicy, a następnie funkcja predict_houses wywołuje uczenie się. Zdefiniowana jest ona w dawid.py
W funkcji tej, początkowo dzieje się to samo co opisałem wyżej w uczeniu się. Potem natomiast jest taka linijka, która jest dla nas bardzo istotna:
pred = mlp.predict(houses_data)
Wyznaczamy wynik proponowany przez nauczone sieci neuronowe dla naszej tablicy z houses_data. Jest to tablica, która jest przyjmowana jako parametr naszej funkcji predict_houses. A jej wartość ustawiana jest w model/house.py W terminalu wyświetlany jest zawsze procent skuteczności naszego modelu.
Następnie ustawiamy zmienną RUN_D na True, dzięki czemu możemy wywołać zmpdyfikowany algorytm A* dla tego modelu i zebrać śmieci potencjalnie największe (względem gabarytu), czyli dla których nasz uczący się program, przypisał wartość 2 lub 3.