Compare commits

...

105 Commits

Author SHA1 Message Date
c42a1038bc Update 'final-evaluation.md' 2020-06-15 13:26:55 +00:00
8ec7efaafa Zaktualizuj 'final-evaluation.md' 2020-06-15 13:22:05 +00:00
jonspacz
500f051946 Neural Network raport 2020-06-15 15:07:53 +02:00
Michał Czekański
5aaba17b2e Add printing tree decision to console 2020-06-15 14:59:37 +02:00
Michał Czekański
c5497ff291 Add proper death message when food recognition failed 2020-06-15 14:52:55 +02:00
Michał Czekański
e132a1ceaf Add beginning of final-evaluation and information about Decision Tree usage 2020-06-15 14:24:04 +02:00
Michał Czekański
7f6cec3107 Add empty final-evaluation file 2020-06-15 14:18:17 +02:00
Michał Czekański
096934f547 Neural network mygraph.png file 2020-06-15 14:15:05 +02:00
jonspacz
00bf015951 Neural Network 2020-06-08 14:52:37 +02:00
Mateusz
7e4f180bb6 Add run instruction to raport on beginning 2020-06-01 16:06:24 +02:00
Mateusz
f7c5deafda Finishing raport 2020-06-01 01:20:16 +02:00
Mateusz
9dc60c7062 Describe changes, and raport progress 2020-05-31 19:54:27 +02:00
Mateusz
2fdbf014aa my traveling raport init 2020-05-30 20:31:10 +02:00
Mateusz
1b71fe886b check entities list instead of entitiesRawData list 2020-05-30 20:30:46 +02:00
Mateusz
f6fa3b461b some refactor 2020-05-30 20:30:25 +02:00
Mateusz
c8557f3de6 good console messages 2020-05-30 20:30:09 +02:00
Mateusz
5c8a48e30d print message to console when agent take the herb works 2020-05-29 00:47:11 +02:00
Mateusz
14850cd230 random first population - herbs random spawn works 2020-05-28 23:57:27 +02:00
Mateusz
cf0a4be82f algorithm and movement work 2020-05-27 00:57:53 +02:00
Mateusz
80c72f1ba0 method that return travel as correct list work 2020-05-27 00:23:56 +02:00
Mateusz
b63be724f5 run by ga_travel parametr in game work 2020-05-26 23:50:31 +02:00
Mateusz
80b7e32f47 generate list of traveling by GA 2020-05-26 23:44:56 +02:00
Mateusz
d363120ef4 GA skelethon 2020-05-26 21:33:36 +02:00
Mateusz
87a341744c spawn 10 transparent herbs 2020-05-26 13:23:13 +02:00
Mateusz
1eb62c3382 when player pickup all herbs, his statistics reset 2020-05-26 12:31:55 +02:00
Michał Czekański
51d50f7cd6 Use added images in DT report 2020-05-25 15:28:05 +02:00
Michał Czekański
068eb3dfed Add images to DT report 2020-05-25 15:20:31 +02:00
Michał Czekański
7906524047 Fix displaying code on github 2020-05-25 15:06:53 +02:00
Michał Czekański
d9d67388e5 DT Report alpha version 2020-05-25 04:28:12 +02:00
Michał Czekański
3229d9405a Add decision tree dsc in report 2020-05-25 03:04:38 +02:00
Michał Czekański
f57bc6463b Add missing file with DT testing function 2020-05-25 02:46:23 +02:00
Michał Czekański
b17221c7c2 Add specifying training set size when testing DT 2020-05-25 02:45:13 +02:00
Michał Czekański
a256fc1cfe Fix too many newlines at end of dt examples file 2020-05-25 02:21:59 +02:00
Michał Czekański
63b1d36c36 Add function testing decision tree and game mode to use it 2020-05-25 02:21:18 +02:00
Michał Czekański
c1b12883f8 Fix calculating distance between two dt interactables 2020-05-25 01:41:23 +02:00
Michał Czekański
f0c77a154b Add more dt examples 2020-05-25 01:24:47 +02:00
Michał Czekański
04e3b29c21 If there are is no food left, then make decision tree return water. 2020-05-25 01:24:17 +02:00
Michał Czekański
29ba3d23c0 Add more dt examples. 2020-05-25 00:45:13 +02:00
Michał Czekański
d383fdefc4 Add printing score after dt run end. 2020-05-25 00:44:58 +02:00
Michał Czekański
939c3f9072 Add entity picking being adjustable for pure dt run and ga with dt run
In pure dt mode player can choose the same object like water any times in a row.
In dt with ga mode player can't choose same object two times in a row.
2020-05-24 23:40:13 +02:00
Michał Czekański
1e4b44558c Add more dt examples 2020-05-24 23:25:17 +02:00
Michał Czekański
994c509831 Fix calculating dst from player in dt objects 2020-05-24 22:58:41 +02:00
Michał Czekański
326551ad1c Add dt attribute - distance between water and food and some examples 2020-05-24 22:56:00 +02:00
Michał Czekański
e7cd571d95 Add method returning dt distance between two dt interactables 2020-05-24 22:32:42 +02:00
Michał Czekański
da119fca37 Add new field for accurate dst from player in dt interactable class
This will be used to sort foods more precisely when looking for nearest food, water, etc.
2020-05-24 22:21:10 +02:00
Michał Czekański
9825cd9b7d Add more dt examples 2020-05-24 19:44:29 +02:00
Michał Czekański
597a709224 Fix running game in pure dt mode 2020-05-24 19:29:29 +02:00
Michał Czekański
34eb74d980 Add game mode for generating dt examples and delete unnecessary class
This class was storing dt examples. Now they are generated to file and read from it to be used.
2020-05-24 19:19:56 +02:00
Michał Czekański
3f2e5550c7 Make prints done by method gen dt exmpls readable 2020-05-24 19:10:45 +02:00
Michał Czekański
6969a81616 Add method generating dt examples 2020-05-24 18:48:53 +02:00
Michał Czekański
f025df0381 Fix method writing dt examples to file
Method wasn't removing trailing new line chars.
2020-05-24 18:48:30 +02:00
Michał Czekański
f73ae6290f Change resolution to smaller in mainConfig.json
It won't fit on my screen without window adjusting.
2020-05-24 18:39:36 +02:00
Michał Czekański
df70b321ae Adjust project after new enum value addition 2020-05-24 18:38:55 +02:00
Michał Czekański
48560fb3a1 Add >= 15 value in dist from object enum 2020-05-24 18:37:46 +02:00
Michał Czekański
873bfd0d8e Add method returning description of dt survival example 2020-05-24 18:26:10 +02:00
Michał Czekański
98f692a6d8 Add method comparing survival dt examples attributes
This will be used to check for duplicates when generating decision tree's examples.
2020-05-24 17:48:11 +02:00
Michał Czekański
ed58517b82 Fix method reading from and adding examples to file 2020-05-24 17:12:35 +02:00
Michał Czekański
8e9d0c1267 Add method appending examples to file 2020-05-24 17:07:34 +02:00
Michał Czekański
9dc74bc599 Add file with for dt examples and manager capable of reading them 2020-05-24 17:02:35 +02:00
Michał Czekański
b8d2a4f379 Add decision tree pause mode 2020-05-24 15:57:49 +02:00
Michał Czekański
2c2d865d7f Fix wrong argument being passed to method 2020-05-24 15:51:15 +02:00
Michał Czekański
7b6a46188b Remove wrong DT examples, leave them empty for now. 2020-05-24 15:48:32 +02:00
Michał Czekański
02df6e01c6 Remove duplicate of pickEntity() in GA_With_DT and SurvivalDT classes 2020-05-24 15:47:56 +02:00
Michał Czekański
45345cabd8 Add method returning description of DT interactable 2020-05-24 15:46:25 +02:00
Michał Czekański
80946a4246 Add possibility of running GA with decision tree
Decision tree will be used to give player movement targets.
2020-05-24 14:04:10 +02:00
Michał Czekański
c88965de38 Add pausing decision tree run 2020-05-24 13:58:33 +02:00
Michał Czekański
5f7cd0dce7 Add decision tree run game mode 2020-05-24 13:48:05 +02:00
Michał Czekański
7d12c9f59e Add class picking movement target for player with dt 2020-05-24 13:30:50 +02:00
Michał Czekański
3fafade1e9 Add examples class which will contain learning examples for decision tree 2020-05-24 00:38:54 +02:00
Michał Czekański
0d6b3e4e84 Default indent fix in decision tree print 2020-05-24 00:38:12 +02:00
Michał Czekański
2fbc877141 Fix circular import between decision tree and dt branch 2020-05-23 23:49:06 +02:00
Michał Czekański
93839b3580 Add field for associated interactable in dt interactable class 2020-05-23 23:48:10 +02:00
Michał Czekański
05d28c4f5b Remove commas from decision tree's enums
Commas were causing enum values to be tuples instead of integers.
2020-05-23 23:47:36 +02:00
Michał Czekański
c4809373a0 Add method converting interactable to object representing it that can be used in dt 2020-05-23 22:20:14 +02:00
Michał Czekański
3e3fd259dd Rename dt class
Class was named ...Entity but it should be ...Interactable, because entities do not have classifiers.
2020-05-23 22:13:24 +02:00
Michał Czekański
94ec3c273e Remove unnecessary DTEntities and add classification in general class 2020-05-23 22:10:05 +02:00
Michał Czekański
f0af76520b Add method converting pl statistics to those that can be used in dt 2020-05-23 21:57:43 +02:00
Michał Czekański
1f99669d29 Add classes which will represent environment and will be usable in decision trees
Classes to represent player statistics, food objects etc...
2020-05-23 21:42:10 +02:00
Michał Czekański
c347c68958 Comment classes 2020-05-23 17:23:50 +02:00
Michał Czekański
052516540f Add survival dt example class
It will be used to create decision tree examples with project specific attributes like hunger, distance from food etc...
2020-05-23 17:20:18 +02:00
Michał Czekański
8bc292f06d Create survival dt attributes definitions
Definitions like hungerAttribute etc...
2020-05-23 17:16:28 +02:00
Michał Czekański
8d4cde8eb0 Add enum for classifying dt survival examples.
This enum will be used in decision tree learning. For example food classification will mean that player should go for food.
2020-05-23 17:15:44 +02:00
Michał Czekański
c4d4d6bb52 Add enum for player distance from objects like food
This enum will be used in decision tree learning.
2020-05-23 17:14:29 +02:00
Michał Czekański
479137ce74 Add enum for player stats amount
This enum will be used in decision tree learning when creating examples.
2020-05-23 17:14:06 +02:00
Michał Czekański
b0d8872c15 Add inductive decision tree learning set of functions
To build decision tree use inductiveDecisionTreeLearning function.
2020-05-22 14:21:52 +02:00
Michał Czekański
43b654a6a5 Add static method printing decision tree 2020-05-21 17:01:27 +02:00
Michał Czekański
44419b5f28 Add method making decision in DecisionTree class
This method takes an instance of DecisionTreeExample and returns what it "decided".
2020-05-21 17:00:59 +02:00
Michał Czekański
9d1299b162 Add method adding branch to decision tree 2020-05-21 16:58:28 +02:00
Michał Czekański
fd54303dba Change type of branch field in DecisionTree class
Type was Any, now it is DecisionTreeBranch.
2020-05-21 16:57:33 +02:00
Michał Czekański
a3d47b4320 Add DecisionTreeBranch class 2020-05-21 16:56:20 +02:00
Michał Czekański
fbd76f31e7 Add DecisionTree class with just init 2020-05-21 16:56:01 +02:00
Michał Czekański
bdba45de08 Add DecisionTreeExample class
This class will be used in decision trees.
2020-05-21 16:52:48 +02:00
Michał Czekański
ad791a299e Add Attribute class
This class will be used in decision trees.
2020-05-21 16:50:46 +02:00
Michał Czekański
38ce217db4 Add AttributeDefinition class
This class will be used in decision trees.
2020-05-21 16:50:07 +02:00
ee9769db6e Updated gif URL 2020-05-18 13:15:56 +00:00
c5ff411eba Added simulation example 2020-05-18 15:14:59 +02:00
2f018eae2f Updated training values 2020-05-18 15:03:23 +02:00
f67a9748f6 Updated plot 2020-05-18 15:01:54 +02:00
a0da920e39 Changed seed 2020-05-18 14:58:44 +02:00
b20ac9c356 Removed stepCount (bugged) 2020-05-18 14:58:31 +02:00
ded03f5a3b Removed redundant import 2020-05-18 14:29:39 +02:00
3e4f10236d Removed redundant pickWeightedAffinity function 2020-05-18 14:29:26 +02:00
dc5dc756cb Removed randomness from entity picking 2020-05-18 14:28:48 +02:00
de68c5e991 GA raport done 2020-05-17 18:13:24 +02:00
2ff0ce1ddf Added new info 2020-05-17 12:06:43 +02:00
175 changed files with 2754 additions and 41 deletions

214
DecisionTree.md Normal file
View File

@ -0,0 +1,214 @@
# DSZI_Survival - Drzewa Decyzyjne
### Autor: Michał Czekański
## Cel zastosowania w projekcie
W projekcie DSZI_Survival drzewo decyzyjne użyte jest do podejmowania decyzji przez agenta, rozbitka na bezludnej wyspie,
jaką czynność wykonać w danej chwili.
Czy:
* zdobyć pożywienie
* udać się do źródła wody
* odpocząć przy ognisku
## Opis drzewa decyzyjnego
* **Drzewo decyzyjne** to drzewo reprezentujące jakąś funkcję, Boolowską w najprostszym przypadku.
* Drzewo decyzyjne jako **argument** przyjmuje obiekt - sytuację opisaną za pomocą zestawu **atrybutów**
* **Wierzchołek** drzewa decyzyjnego odpowiada testowi jednego z atrybutów (np. IsMonday)
* Każda **gałąź** wychodząca z wierzchołka jest oznaczona możliwą wartością testu z wierzchołka (np. True)
* **Liść** zawiera wartość do zwrócenia (**decyzję, wybór**), gdy liść ten zostanie osiągnięty (np. ShopType.Grocery)
## Metoda uczenia - Algorytm ID3
Metoda użyta do uczenia drzewa decyzyjnego to metoda **indukcyjnego uczenia drzewa decyzyjnego**.
### Działanie ID3
* Definiujemy atrybuty, które będą posiadały przykłady służące do uczenia drzewa (**atrybuty**)
```python
class AttributeDefinition:
def __init__(self, id, name: str, values: List):
self.id = id
self.name = name
self.values = values
class Attribute:
def __init__(self, attributeDefinition: AttributeDefinition, value):
self.attributeDefinition = attributeDefinition
self.value = value
```
* Tworzymy przykłady z wykorzystaniem atrybutów (**przykłady**)
```python
class DecisionTreeExample:
def __init__(self, classification, attributes: List[Attribute]):
self.attributes = attributes
self.classification = classification
```
* Ustalamy domyślną wartość do zwrócenia przez drzewo - **klasa domyślna**
* Następnie postępujemy indukcyjnie:
* Jeżeli liczba przykładów == 0: zwracamy wierzchołek oznaczony klasą domyślną
* Jeżeli wszystkie przykłady są tak samo sklasyfikowane: zwracamy wierzchołek oznacz. tą klasą
* Jeżeli liczba atrybutów == 0: zwracamy wierzchołek oznacz. klasą, którą posiada większość przykładów
* W przeciwnym wypadku **wybieramy atrybut** A (o wyborze atrybutu poniżej) i czynimy go korzeniem drzewa T
* **nowa_klasa_domyślna** = wierzchołek oznaczony klasą, która jest przypisana największej liczbie przykładów
* Dla każdej wartości W atrybutu A:
* nowe_przykłady = przykłady, dla których atrybut A przyjmuje wartość W
* Dodajemy do T krawędź oznaczoną przez wartość W, która prowadzi do wierzchołka zwróconego przez wywołanie indukcyjne:
*treelearn(nowe_przykłady, atrybutyA, nowa_klasa_domyślna)*
* Zwróć drzewo T
```python
class DecisionTree(object):
def __init__(self, root):
self.root = root
self.branches = []
self.branchesNum = 0
```
### Wybór atrybutu
W trakcie uczenia drzewa decyzyjnego chcemy wybrać jak najlepszy atrybut, dzięki któremu możliwie jak najszybciej będziemy mogli sklasyfikować podane przykłady.
Miarą porównawczą atrybutów będzie **zysk informacji** dla danego atrybutu (**information gain**).
Atrybut o największym zysku zostanie wybrany.
**Implementacja**
```python
def chooseAttribute(attributes: List[AttributeDefinition], examples: List[DecisionTreeExample], classifications):
bestAttribute = None
bestAttributeGain = -1
for attribute in attributes:
attrInformationGain = calculateInformationGain(attribute, classifications, examples)
if attrInformationGain > bestAttributeGain:
bestAttribute = attribute
bestAttributeGain = attrInformationGain
return bestAttribute
```
#### Obliczanie zysku informacji
(Wszelkie obliczenia wedle wzorów podanych na zajęciach)
* I(C) - Obliczamy zawartość informacji dla zbioru możliwych klasyfikacji
![fig](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/raw/master/data/images/reportImages/DT/I%28C%29.png)
* E(A) - Obliczamy ilość informacji potrzebną do zakończenia klasyfikacji po sprawdzeniu atrybutu
![fig](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/raw/master/data/images/reportImages/DT/E%28A%29.png)
* **G(A)** - **Przyrost informacji dla atrybutu A** = I(C) - E(A)
**Implementacja**
```python
def calculateInformationGain(attribute: AttributeDefinition, classifications, examples: List[DecisionTreeExample]):
return calculateEntropy(classifications, examples) - calculateRemainder(attribute, examples, classifications)
```
## Opis implementacji
### Definicje atrybutów:
* Głód: **[0, 1/4); [1/4, 1/2); [1/2, 3/4); [3/4, 1]**
* Pragnienie: **[0, 1/4); [1/4, 1/2); [1/2, 3/4); [3/4, 1]**
* Energia: **[0, 1/4); [1/4, 1/2); [1/2, 3/4); [3/4, 1]**
* Odległość od jedzenia: **[0, 3); [3, 8); [8, 15); [15, max)**
* Odległość od źródła wody: **[0, 3); [3, 8); [8, 15); [15, max)**
* Odległość od miejsca spoczynku: **[0, 3); [3, 8); [8, 15); [15, max)**
* Odległość pomiędzy wodą a jedzeniem: **[0, 3); [3, 8); [8, 15); [15, max)**
```python
class PlayerStatsValue(Enum):
ZERO_TO_QUARTER = 0
QUARTER_TO_HALF = 1
HALF_TO_THREE_QUARTERS = 2
THREE_QUARTERS_TO_FULL = 3
class DistFromObject(Enum):
LT_3 = 0
GE_3_LT_8 = 1
GE_8_LT_15 = 2
GE_15 = 3
```
### Uczenie drzewa
```python
def inductiveDecisionTreeLearning(examples: List[DecisionTreeExample], attributes: List[AttributeDefinition], default,
classifications)
```
### Zwracanie decyzji przez drzewo
```python
def giveAnswer(self, example: DecisionTreeExample):
if self.branchesNum == 0:
return self.root
for attr in example.attributes:
if attr.attributeDefinition.id == self.root.id:
for branch in self.branches:
if branch.label == attr.value:
return branch.subtree.giveAnswer(example)
```
### Wybór celu dla agenta
```python
def pickEntity(self, player, map, pickForGa=False):
foods = map.getInteractablesByClassifier(Classifiers.FOOD)
waters = map.getInteractablesByClassifier(Classifiers.WATER)
rests = map.getInteractablesByClassifier(Classifiers.REST)
playerStats = DTPlayerStats.dtStatsFromPlayerStats(player.statistics)
# Get waters sorted by distance from player
dtWaters: List[DTSurvivalInteractable] = []
for water in waters:
dtWater = DTSurvivalInteractable.dtInteractableFromInteractable(water, player.x, player.y)
dtWaters.append(dtWater)
dtWaters.sort(key=lambda x: x.accurateDistanceFromPlayer)
nearestDtWater = dtWaters[0]
# Get foods sorted by distance from player
dtFoods: List[DTSurvivalInteractable] = []
for food in foods:
dtFood = DTSurvivalInteractable.dtInteractableFromInteractable(food, player.x, player.y)
dtFoods.append(dtFood)
dtFoods.sort(key=lambda x: x.accurateDistanceFromPlayer)
# If there is no food on map return nearest water.
try:
nearestDtFood = dtFoods[0]
except IndexError:
return nearestDtWater.interactable
# Get rest places sorted by distance from player
dtRestPlaces: List[DTSurvivalInteractable] = []
for rest in rests:
dtRest = DTSurvivalInteractable.dtInteractableFromInteractable(rest, player.x, player.y)
dtRestPlaces.append(dtRest)
dtRestPlaces.sort(key=lambda x: x.accurateDistanceFromPlayer)
nearestDtRest = dtRestPlaces[0]
currentSituation = SurvivalDTExample(None, playerStats.hungerAmount, playerStats.thirstAmount,
playerStats.staminaAmount,
nearestDtFood.dtDistanceFromPlayer, nearestDtWater.dtDistanceFromPlayer,
nearestDtRest.dtDistanceFromPlayer,
nearestDtFood.getDtDistanceFromOtherInteractable(nearestDtWater.interactable))
treeDecision, choice = self.__pickEntityAfterTreeDecision__(currentSituation,
dtFoods,
dtRestPlaces,
dtWaters)
return choice.interactable
```
## Zestaw uczący, zestaw testowy
### Zestaw uczący
Zestaw uczący był generowany poprzez tworzenie losowych przykładów i zapytanie użytkownika o klasyfikację, a następnie zapisywany do pliku.
### Zestaw testowy
Przy testowaniu drzewa podajemy ile procent wszystkich, wcześniej wygenerowanych przykładów mają być przykłady testowe.

173
GeneticAlgorithm.md Normal file
View File

@ -0,0 +1,173 @@
# Algorythm Genetyczny w projekcie DSZI_Survival
**Autor:** Marcin Kostrzewski
---
## Cel
Celem algorytmu jest znalezienie czterech optymalnych wartości, według których
agent podejmuje decyzję, co zrobić dalej. Te cztery cechy to:
* Priorytet (chęć) zaspokajania głodu,
* Zaspokajanie pragnienia,
* Odpoczynek,
* Jak odległość od obiektu wpływa na podjętą decyzję.
Zestaw tych cech reprezentuje klasa-struktura **[*Affinities*](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/src/master/src/AI/Affinities.py)**:
```python
class Affinities:
def __init__(self, food, water, rest, walking):
"""
Create a container of affinities. Affinities describe, what type of entities a player prioritizes.
:param food: Food affinity
:param water: Freshwater affinity
:param rest: Firepit affinity
:param walking: How distances determine choices
"""
self.food = food
self.water = water
self.rest = rest
self.walking = walking
```
Oczywiście agent (gracz) posiada w swojej klasie pole ``self.affinities``.
## Podejmowanie decyzji
Gracz podejmuje decyzję o wyborze celu według następującej formuły:
```python
typeWeight / (distance / walkingAffinity) * affectedStat * multiplier
```
gdzie:
* *typeWeight* - wartość cechy odpowiadającej typowi celu,
* *distance* - odległość od celu,
* *walkingAffinity* - waga odległości,
* *affectedStat* - aktualna wartość odpowiadającej statystyki agenta,
* *multiplier* - mnożnik redukujący wpływ obecnych statystyk na wybór.
Implementacja w **[*GA.py/pickEntity()*](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/src/master/src/AI/GA.py)** (przykładowo dla jedzenia):
```python
watersWeights = []
thirst = player.statistics.thirst
for water in waters:
typeWeight = weights[1]
distance = abs(player.x - water.x) + abs(player.x - water.y)
watersWeights.append(typeWeight / (distance * walkingAffinity) * thirst * 0.01)
```
Dla każdego obiektu, z którym agent może podjąć interakcję wyliczana jest ta wartość
i wybierany jest obiekt, dla którego jest największa.
## Implementacja algorytmu genetycznego
Za realizację algorytmu odpowiada funkcja *geneticAlgorithm()* w **[*GA.py*](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/src/master/src/AI/GA.py)** (Skrócona wersja):
```python
def geneticAlgorithm(map, iter, solutions, mutationAmount=0.05):
# Based on 4 weights, that are affinities tied to the player
weightsCount = 4
# Initialize the first population with random values
initialPopulation = numpy.random.uniform(low=0.0, high=1.0, size=(solutions, weightsCount))
population = initialPopulation
for i in range(iter):
fitness = []
for player in population:
fitness.append(doSimulation(player, map))
parents = selectMatingPool(population, fitness, int(solutions / 2))
offspring = mating(parents, solutions, mutationAmount)
population = offspring
```
#### Omówienie:
##### Pierwsza populacja
Pierwsza populacja inicjalizowana jest losowymi wartościami. Szukamy
czterech najlepszych wag; każdy osobnik z gatunku jest reprezentowany przez
listę 4-elementową wag.
```python
initialPopulation = numpy.random.uniform(low=0.0, high=1.0, size=(solutions, weightsCount))
```
Rozpoczyna się pętla, która stworzy tyle generacji, ile sprecyzujemy w parametrze.
##### Symulacja i *fitness*
Dla każdego osobnika z populacji uruchamiana jest symulacja. Symulacja dzieje się w tle,
żeby zminimializować czas potrzebny do wykonania pełnej symulacji. Jej koniec następuje w momencie,
gdy agent umrze.
```python
fitness.append(doSimulation(player, map))
```
Wartością zwracaną przez funkcję symulacji jest tzw. *fitness*. W tym wypadku,
wartością tą jest ilość kroków, jakie pokonał agent przez cykl życia.
##### Wybór rodziców
Rodzice dla dzieci przyszłego pokolenia wybierani są na podstawie wartości
*fitness*. W tym wypadku wybirana jest połowa populacji z najwyższymi wartościami przeżywalności.
```python
parents = selectMatingPool(population, fitness, int(solutions / 2))
```
##### Potomstwo, czyli rozmnażanie i mutacje
Za wyliczanie wartości dla nowego pokolenia odpowiada funkcja ``mating``. Przekazujemy do niej rodziców, ilość potomstwa
i siłę mutacji. Z **[*GA.py/mating()*](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/src/master/src/AI/GA.py)**:
```python
for i in range(offspringCount):
parent1 = i % len(parents)
parent2 = (i + 1) % len(parents)
offspring.append(crossover(parents[parent1], parents[parent2]))
```
Do stworzenia potomstwa używana jest funkcja ``crossover``, która wylicza wartości, jakie przyjmie nowe potomstwo.
Wartośc ta to mediana wartości obu rodziców. Z **[*GA.py/crossover()*](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/src/master/src/AI/GA.py)**:
```python
for gene1, gene2 in zip(genes1, genes2):
result.append((gene1 + gene2) / 2)
```
Po zastosowaniu krzyżówki, jeden losowo wybrany gen jest alterowany o niewielką wartość (mutacja). Z **[*GA.py/mutation()*](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/src/master/src/AI/GA.py)**:
```python
for player in offspring:
randomGeneIdx = random.randrange(0, len(player))
player[randomGeneIdx] = player[randomGeneIdx] + random.uniform(-1.0, 1.0) * mutationAmount
```
Nowe potomstwo zastępuje obecną populacje i algorytm wchodzi w kolejną pętle:
```python
population = offspring
```
## Skuteczność algorytmu
Zastosowanie algorytmu przynosi niezbyt spektakularne, lecz oczekiwane wyniki. Po uruchomieniu symulacji
dla 1000 generacji:
* Wykres wartości fitness od generacji:
![fig](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/raw/master/data/images/exampleFitness.png)
* Najlepsze / najgorsze fitness:
```
Best Fitness: 186
Worst Fitness: 71
```
* Zestaw najlepszych / najgorszych wartości
```
Best:
Affinities: food=0.9659207331357987, water=1.06794833921562, rest=0.4224083038045297, walking=0.26676612275274836
Worst:
Affinities: food=0.3927852322929111, water=0.6888704071372844, rest=0.625376993269597, walking=0.5415515638814266
```
### Przykład symulacji dla najlepszego osobnika:
![gif](https://git.wmi.amu.edu.pl/s444409/DSZI_Survival/raw/master/data/images/screenshots/bestFitnessRunExample.gif)
## Zastosowanie w całości projektu
Dzięki wyliczonym przez algorytm wagom, gracz poruszający się w środowisku będzie znał swoje priorytety i będzie w stanie
przeżyć jak najdłużej. Obecnie, wybór obiektu jest dość statyczny i niezbyt "mądry", został napisany jedynie
na potrzeby tego projektu. W przyszłości algorytm może być trenowany według inteligentnych wyborów obiektów np. poprzez zastosowanie
drzewa decyzyjnego. Każdy obiekt ma zdefiniowany swój skutek, czyli gracz z góry wie, czym jest dany obiekt. W przyszłości
gracz może nie znać informacji o obiektach, może być do tego używany jakiś inny algorytm, który oceni,
czym jest dany obiekt.

70
NeuralNetwork.md Normal file
View File

@ -0,0 +1,70 @@
# DSZI_Survival - Sieć Neuronowa
### Autor: Jonathan Spaczyński
## Cel zastosowania w projekcie
W projekcie DSZI_Survival sieć neuronowa użyta jest do podejmowania decyzji przez agenta.
Decyzja polega na rozpoznawaniu zdjęć owoców (jabłka i gruszki). W przypadku nie rozpoznania owocu przez
agenta, dochodzi do zatrucia i agent umiera/przegrywa.
## Przygotowanie danych
* **Krok 1** Przechowywane zdjęcia owoców muszą przejść przez proces zamiany zdjęcia (.jpg) na dane, które
mogą być wykorzystane przez sieć neuronową.
```python
CATEGORIES = ["Apple", "Pear"]
IMG_SIZE = 64
training_data = []
def create_training_data():
for category in CATEGORIES:
path = os.path.join(DATADIR, category)
class_num = CATEGORIES.index(category)
for img in os.listdir(path):
try:
img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE))
training_data.append([new_array, class_num])
except Exception as e:
pass
```
zdjęcia są przechowywane w tablicy training_data wraz z klasyfikacją (class_num) odpowiadającą jakim typem owocu jest zdjęcie
* **Krok 2** Bardzo ważnym krokiem jest pomieszanie danych. W przeciwnym wypadku nasz model po ciągłym otrzymywanie danych
reprezentujących tylko jedną kategorię owoców mógłby się wyuczyć, aby tylko zgadywać tą kategorię.
```python
random.shuffle(training_data)
```
* **Krok 3** Ostatnim krokiem jest zaktualizowanie danych w taki sposób żeby były z przedziału
od 0 d 255 (reprezentacja koloru danego pixela)
```python
X = X / 255.0
```
## Kilka słów na temat danych
* **Ilość Danych** Do trenowania modelu wykorzystałem 8568 zdjęć gruszek i jabłek
z czego mniej więcej połowa danych była jednym z typów ww. owoców, a druga połowa
reprezentowała pozostałą kategorią
* **Dane wykorzystane do obliczenia skutecznośći** stanowiły małą i oddzielną część danych wykorzystanych do trenowania.
## Model
* **Dane wejściowe:** Dane o kształcie 64x64 reprezentujące pixele w zdjęciach owoców
* **Warstwa ukryta:** Składająca się z 128 "neuronów" wykorzystującą sigmoid jako funkcję aktywacyjną
* **Warstwa wyjściowa:** Składająca się z 2 "neuronów" reprezentujących gruszkę i jabłko
* **Stała ucząca:** 0.001
```python
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(64, 64)),
tf.keras.layers.Dense(128, activation=tf.nn.sigmoid),
tf.keras.layers.Dense(2, activation=tf.nn.sigmoid)
])
model.compile(tf.keras.optimizers.Adam(lr=0.001),
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
```
## Osiągniecia modelu
* **Trafność:** 86.4%
* **Strata:** 0.312

View File

@ -13,8 +13,13 @@ Python 3.x
pygame: 1.9.x
```
## Uruchomienie
Projekt można uruchomić w dwóch trybach, które podajemy jako parametry:
* test: Wizualne środowisko agenta, którym możemy sami prouszać
* ga: Uruchomienie algorytmu genetycznego w tle. Musimy dodatkowo jako kolejny
parametr podać ilość iteracji dla algorytmu. Możemy dodać -t, jeżeli
chcemy uruchomić algorytm w wielu wątkach (Nie działa zbyt dobrze)
```
$ python Run.py
$ python Run.py {test|ga} [iter] [-t]
```
## Konfiguracja
Plik z konfiguracją znajduje w ```data/config/mainConfig.json```.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Some files were not shown because too many files have changed in this diff Show More