Итак, я построил эволюционный алгоритм нейронной сети, который воспроизводит версию " Flappy Bird " в стиле barebone.
Все работает, и оно сходится к "идеальному" решению НЕМЕДЛЕННО ...слишком идеально ... Так что у меня есть гипотеза о том, почему он изучает оптимальную политику практически без поколений (я упомяну об этом в конце, так как сначала я хотел бы сначала показать вам свои результаты).
Вотдемонстрация:
Опять же ... это сразу после инициализации веса.
ПРИМЕЧАНИЕ: модель зафиксирована на 3 входных слоях, 2 скрытых, 1 выходной (прыгать или не прыгать).
Поскольку это такая простая проблема, я отказался от использования специального метода init, такого как glorot, и просто извлек его из равномерного распределения.
Метод инициализации:
def randomize_net(self):
self.layer_weights = []
for i in range(len(NET_DIMS)-1):
self.layer_weights.append(
np.random.uniform(
size=(NET_DIMS[i], NET_DIMS[i+1])
)
)
Функции ввода: (Примечание: они не нормированы.)
def look(self, pipe: Pipe):
# Get distance from the pipe's X
x_dist = pipe.pos[0] - self.pos[0]
if x_dist < 0:
x_dist = 0
# Get distance from pipe's upper bound
y_upper_dist = (pipe.pos[1] + HALF_GAP) - self.pos[1]
# Get distance from pipe's lower bound
y_lower_dist = (pipe.pos[1] - HALF_GAP) - self.pos[1]
self.vision = [
x_dist,
y_upper_dist,
y_lower_dist
]
Расчет вывода:
def think(self):
# Calculate the network's output.
output = self.vision
l = len(self.layer_weights)-1
for i, weight_layer in enumerate(self.layer_weights):
output = np.matmul(output, weight_layer)
# Activate all layer outputs EXCEPT output layer.
if i != l:
self.activate_layer(output)
self.net_outputs = output
Я ожидаю, что птицы будут учиться послехотя бы несколько поколений проб и ошибок, чкак бы они ни реагировали идеально в первый раз.
Причина, по которой я привожу это в StackOverflow, состоит в том, чтобы посмотреть, не испортилась ли моя модель, но просто удается работать из-за особого случая.
Гипотеза:
Я полагаю, что это может быть связано с умножением на 0 для расстояний Y.Если вес умножить на расстояние Y, равное 0, он может просто распространиться вперед и привести к выходу менее 0,5 (мой порог), несмотря на значения веса.
Я мог бы быть далеко, ядаже не уверен, что имеет большой смысл.Тем не менее, я хотел бы взглянуть на посторонних, поэтому, пожалуйста, поделитесь своими мыслями.
Исходный код:
Кстати, это с открытым исходным кодом, так что если вы хотите запустить его самостоятельно вот оно .