Skip to content

Commit 332e170

Browse files
author
=
committed
yay_ or nay_ achieved 80 % accuracy
1 parent 4979ea0 commit 332e170

23 files changed

+851
-23
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ __pycache__/
22
target/*
33
.idea/*
44
tensorflow/screenshots/*
5-
labels.txt
6-
tensorflow/dataset
5+
tensorflow/dataset/samples/*
76
.zip

gym/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://www.youtube.com/watch?v=3zeg7H6cAJw

gym/try_gym.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import gym
2+
import random
3+
import numpy as np
4+
import tflearn
5+
from tflearn.layers.core import input_data, dropout, fully_connected
6+
from tflearn.layers.estimator import regression
7+
from statistics import mean, median
8+
from collections import Counter
9+
10+
# learning rate
11+
LR = 1e-3
12+
env = gym.make('CartPole-v0')
13+
env.reset()
14+
goal_steps = 500
15+
score_requirement = 50
16+
initial_games = 10000
17+
18+
def some_random_games_first():
19+
for episode in range(5):
20+
env.reset()
21+
for t in range(goal_steps):
22+
env.render()
23+
action = env.action_space.sample()
24+
observation, reward, done, info = env.step(action)
25+
if done:
26+
break
27+
28+
#some_random_games_first()

snake_game/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://towardsdatascience.com/today-im-going-to-talk-about-a-small-practical-example-of-using-neural-networks-training-one-to-6b2cbd6efdb3?gi=cb32f92347a5

snake_game/checkpoint

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
model_checkpoint_path: "D:\\work\\LearnANN\\snake_game\\snake_nn_2.tflearn"
2+
all_model_checkpoint_paths: "D:\\work\\LearnANN\\snake_game\\snake_nn_2.tflearn"
Binary file not shown.
Binary file not shown.

snake_game/nn_1.py

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
from snake_game import SnakeGame
2+
from random import randint
3+
import numpy as np
4+
import tflearn
5+
import math
6+
from tflearn.layers.core import input_data, fully_connected
7+
from tflearn.layers.estimator import regression
8+
from statistics import mean
9+
from collections import Counter
10+
11+
class SnakeNN:
12+
def __init__(self, initial_games = 100, test_games = 100, goal_steps = 100, lr = 1e-2, filename = 'snake_nn.tflearn'):
13+
self.initial_games = initial_games
14+
self.test_games = test_games
15+
self.goal_steps = goal_steps
16+
self.lr = lr
17+
self.filename = filename
18+
self.vectors_and_keys = [
19+
[[-1, 0], 0],
20+
[[0, 1], 1],
21+
[[1, 0], 2],
22+
[[0, -1], 3]
23+
]
24+
25+
def initial_population(self):
26+
training_data = []
27+
for _ in range(self.initial_games):
28+
game = SnakeGame()
29+
_, _, snake, _ = game.start()
30+
prev_observation = self.generate_observation(snake)
31+
for _ in range(self.goal_steps):
32+
action, game_action = self.generate_action(snake)
33+
done, _, snake, _ = game.step(game_action)
34+
if done:
35+
training_data.append([self.add_action_to_observation(prev_observation, action), 0])
36+
break
37+
else:
38+
training_data.append([self.add_action_to_observation(prev_observation, action), 1])
39+
prev_observation = self.generate_observation(snake)
40+
print(len(training_data))
41+
return training_data
42+
43+
def generate_action(self, snake):
44+
action = randint(0,2) - 1
45+
return action, self.get_game_action(snake, action)
46+
47+
def get_game_action(self, snake, action):
48+
snake_direction = self.get_snake_direction_vector(snake)
49+
new_direction = snake_direction
50+
if action == -1:
51+
new_direction = self.turn_vector_to_the_left(snake_direction)
52+
elif action == 1:
53+
new_direction = self.turn_vector_to_the_right(snake_direction)
54+
for pair in self.vectors_and_keys:
55+
if pair[0] == new_direction.tolist():
56+
game_action = pair[1]
57+
return game_action
58+
59+
def generate_observation(self, snake):
60+
snake_direction = self.get_snake_direction_vector(snake)
61+
barrier_left = self.is_direction_blocked(snake, self.turn_vector_to_the_left(snake_direction))
62+
barrier_front = self.is_direction_blocked(snake, snake_direction)
63+
barrier_right = self.is_direction_blocked(snake, self.turn_vector_to_the_right(snake_direction))
64+
return np.array([int(barrier_left), int(barrier_front), int(barrier_right)])
65+
66+
def add_action_to_observation(self, observation, action):
67+
return np.append([action], observation)
68+
69+
def get_snake_direction_vector(self, snake):
70+
return np.array(snake[0]) - np.array(snake[1])
71+
72+
def is_direction_blocked(self, snake, direction):
73+
point = np.array(snake[0]) + np.array(direction)
74+
return point.tolist() in snake[:-1] or point[0] == 0 or point[1] == 0 or point[0] == 21 or point[1] == 21
75+
76+
def turn_vector_to_the_left(self, vector):
77+
return np.array([-vector[1], vector[0]])
78+
79+
def turn_vector_to_the_right(self, vector):
80+
return np.array([vector[1], -vector[0]])
81+
82+
def model(self):
83+
network = input_data(shape=[None, 4, 1], name='input')
84+
network = fully_connected(network, 1, activation='linear')
85+
network = regression(network, optimizer='adam', learning_rate=self.lr, loss='mean_square', name='target')
86+
model = tflearn.DNN(network, tensorboard_dir='log')
87+
return model
88+
89+
def train_model(self, training_data, model):
90+
X = np.array([i[0] for i in training_data]).reshape(-1, 4, 1)
91+
y = np.array([i[1] for i in training_data]).reshape(-1, 1)
92+
model.fit(X,y, n_epoch = 1, shuffle = True, run_id = self.filename)
93+
model.save(self.filename)
94+
return model
95+
96+
def test_model(self, model):
97+
steps_arr = []
98+
for _ in range(self.test_games):
99+
steps = 0
100+
game_memory = []
101+
game = SnakeGame()
102+
_, _, snake, _ = game.start()
103+
prev_observation = self.generate_observation(snake)
104+
for _ in range(self.goal_steps):
105+
predictions = []
106+
for action in range(-1, 2):
107+
predictions.append(model.predict(self.add_action_to_observation(prev_observation, action).reshape(-1, 4, 1)))
108+
action = np.argmax(np.array(predictions))
109+
game_action = self.get_game_action(snake, action - 1)
110+
done, _, snake, _ = game.step(game_action)
111+
game_memory.append([prev_observation, action])
112+
if done:
113+
break
114+
else:
115+
prev_observation = self.generate_observation(snake)
116+
steps += 1
117+
steps_arr.append(steps)
118+
print('Average steps:',mean(steps_arr))
119+
print(Counter(steps_arr))
120+
121+
def visualise_game(self, model):
122+
game = SnakeGame(gui = True)
123+
_, _, snake, _ = game.start()
124+
prev_observation = self.generate_observation(snake)
125+
for _ in range(self.goal_steps):
126+
predictions = []
127+
for action in range(-1, 2):
128+
predictions.append(model.predict(self.add_action_to_observation(prev_observation, action).reshape(-1, 4, 1)))
129+
action = np.argmax(np.array(predictions))
130+
game_action = self.get_game_action(snake, action - 1)
131+
done, _, snake, _ = game.step(game_action)
132+
if done:
133+
break
134+
else:
135+
prev_observation = self.generate_observation(snake)
136+
137+
def train(self):
138+
training_data = self.initial_population()
139+
nn_model = self.model()
140+
nn_model = self.train_model(training_data, nn_model)
141+
self.test_model(nn_model)
142+
143+
def visualise(self):
144+
nn_model = self.model()
145+
nn_model.load(self.filename)
146+
self.visualise_game(nn_model)
147+
148+
def test(self):
149+
nn_model = self.model()
150+
nn_model.load(self.filename)
151+
self.test_model(nn_model)
152+
153+
if __name__ == "__main__":
154+
SnakeNN().train()

snake_game/nn_2.py

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
from snake_game import SnakeGame
2+
from random import randint
3+
import numpy as np
4+
import tflearn
5+
import math
6+
from tflearn.layers.core import input_data, fully_connected
7+
from tflearn.layers.estimator import regression
8+
from statistics import mean
9+
from collections import Counter
10+
11+
class SnakeNN:
12+
def __init__(self, initial_games = 10000, test_games = 1000, goal_steps = 2000, lr = 1e-2, filename = 'snake_nn_2.tflearn'):
13+
self.initial_games = initial_games
14+
self.test_games = test_games
15+
self.goal_steps = goal_steps
16+
self.lr = lr
17+
self.filename = filename
18+
self.vectors_and_keys = [
19+
[[-1, 0], 0],
20+
[[0, 1], 1],
21+
[[1, 0], 2],
22+
[[0, -1], 3]
23+
]
24+
25+
def initial_population(self):
26+
training_data = []
27+
for _ in range(self.initial_games):
28+
game = SnakeGame()
29+
_, prev_score, snake, food = game.start()
30+
prev_observation = self.generate_observation(snake, food)
31+
prev_food_distance = self.get_food_distance(snake, food)
32+
for _ in range(self.goal_steps):
33+
action, game_action = self.generate_action(snake)
34+
done, score, snake, food = game.step(game_action)
35+
if done:
36+
training_data.append([self.add_action_to_observation(prev_observation, action), -1])
37+
break
38+
else:
39+
food_distance = self.get_food_distance(snake, food)
40+
if score > prev_score or food_distance < prev_food_distance:
41+
training_data.append([self.add_action_to_observation(prev_observation, action), 1])
42+
else:
43+
training_data.append([self.add_action_to_observation(prev_observation, action), 0])
44+
prev_observation = self.generate_observation(snake, food)
45+
prev_food_distance = food_distance
46+
return training_data
47+
48+
def generate_action(self, snake):
49+
action = randint(0,2) - 1
50+
return action, self.get_game_action(snake, action)
51+
52+
def get_game_action(self, snake, action):
53+
snake_direction = self.get_snake_direction_vector(snake)
54+
new_direction = snake_direction
55+
if action == -1:
56+
new_direction = self.turn_vector_to_the_left(snake_direction)
57+
elif action == 1:
58+
new_direction = self.turn_vector_to_the_right(snake_direction)
59+
for pair in self.vectors_and_keys:
60+
if pair[0] == new_direction.tolist():
61+
game_action = pair[1]
62+
return game_action
63+
64+
def generate_observation(self, snake, food):
65+
snake_direction = self.get_snake_direction_vector(snake)
66+
food_direction = self.get_food_direction_vector(snake, food)
67+
barrier_left = self.is_direction_blocked(snake, self.turn_vector_to_the_left(snake_direction))
68+
barrier_front = self.is_direction_blocked(snake, snake_direction)
69+
barrier_right = self.is_direction_blocked(snake, self.turn_vector_to_the_right(snake_direction))
70+
angle = self.get_angle(snake_direction, food_direction)
71+
return np.array([int(barrier_left), int(barrier_front), int(barrier_right), angle])
72+
73+
def add_action_to_observation(self, observation, action):
74+
return np.append([action], observation)
75+
76+
def get_snake_direction_vector(self, snake):
77+
return np.array(snake[0]) - np.array(snake[1])
78+
79+
def get_food_direction_vector(self, snake, food):
80+
return np.array(food) - np.array(snake[0])
81+
82+
def normalize_vector(self, vector):
83+
return vector / np.linalg.norm(vector)
84+
85+
def get_food_distance(self, snake, food):
86+
return np.linalg.norm(self.get_food_direction_vector(snake, food))
87+
88+
def is_direction_blocked(self, snake, direction):
89+
point = np.array(snake[0]) + np.array(direction)
90+
return point.tolist() in snake[:-1] or point[0] == 0 or point[1] == 0 or point[0] == 21 or point[1] == 21
91+
92+
def turn_vector_to_the_left(self, vector):
93+
return np.array([-vector[1], vector[0]])
94+
95+
def turn_vector_to_the_right(self, vector):
96+
return np.array([vector[1], -vector[0]])
97+
98+
def get_angle(self, a, b):
99+
a = self.normalize_vector(a)
100+
b = self.normalize_vector(b)
101+
return math.atan2(a[0] * b[1] - a[1] * b[0], a[0] * b[0] + a[1] * b[1]) / math.pi
102+
103+
def model(self):
104+
network = input_data(shape=[None, 5, 1], name='input')
105+
network = fully_connected(network, 25, activation='relu')
106+
network = fully_connected(network, 1, activation='linear')
107+
network = regression(network, optimizer='adam', learning_rate=self.lr, loss='mean_square', name='target')
108+
model = tflearn.DNN(network, tensorboard_dir='log')
109+
return model
110+
111+
def train_model(self, training_data, model):
112+
X = np.array([i[0] for i in training_data]).reshape(-1, 5, 1)
113+
y = np.array([i[1] for i in training_data]).reshape(-1, 1)
114+
model.fit(X,y, n_epoch = 3, shuffle = True, run_id = self.filename)
115+
model.save(self.filename)
116+
return model
117+
118+
def test_model(self, model):
119+
steps_arr = []
120+
scores_arr = []
121+
for _ in range(self.test_games):
122+
steps = 0
123+
game_memory = []
124+
game = SnakeGame()
125+
_, score, snake, food = game.start()
126+
prev_observation = self.generate_observation(snake, food)
127+
for _ in range(self.goal_steps):
128+
predictions = []
129+
for action in range(-1, 2):
130+
predictions.append(model.predict(self.add_action_to_observation(prev_observation, action).reshape(-1, 5, 1)))
131+
action = np.argmax(np.array(predictions))
132+
game_action = self.get_game_action(snake, action - 1)
133+
done, score, snake, food = game.step(game_action)
134+
game_memory.append([prev_observation, action])
135+
if done:
136+
print('-----')
137+
print(steps)
138+
print(snake)
139+
print(food)
140+
print(prev_observation)
141+
print(predictions)
142+
break
143+
else:
144+
prev_observation = self.generate_observation(snake, food)
145+
steps += 1
146+
steps_arr.append(steps)
147+
scores_arr.append(score)
148+
print('Average steps:',mean(steps_arr))
149+
print(Counter(steps_arr))
150+
print('Average score:',mean(scores_arr))
151+
print(Counter(scores_arr))
152+
153+
def visualise_game(self, model):
154+
game = SnakeGame(gui = True)
155+
_, _, snake, food = game.start()
156+
prev_observation = self.generate_observation(snake, food)
157+
for _ in range(self.goal_steps):
158+
precictions = []
159+
for action in range(-1, 2):
160+
precictions.append(model.predict(self.add_action_to_observation(prev_observation, action).reshape(-1, 5, 1)))
161+
action = np.argmax(np.array(precictions))
162+
game_action = self.get_game_action(snake, action - 1)
163+
done, _, snake, food = game.step(game_action)
164+
if done:
165+
break
166+
else:
167+
prev_observation = self.generate_observation(snake, food)
168+
169+
def train(self):
170+
training_data = self.initial_population()
171+
nn_model = self.model()
172+
nn_model = self.train_model(training_data, nn_model)
173+
self.test_model(nn_model)
174+
175+
def visualise(self):
176+
nn_model = self.model()
177+
nn_model.load(self.filename)
178+
self.visualise_game(nn_model)
179+
180+
def test(self):
181+
nn_model = self.model()
182+
nn_model.load(self.filename)
183+
self.test_model(nn_model)
184+
185+
if __name__ == "__main__":
186+
SnakeNN().train()

0 commit comments

Comments
 (0)