很久以前微信流行过一个小游戏:打飞机,这个游戏简单又无聊。在2017年来临之际,我就实现一个超级弱智的人工智能(AI),这货可以躲避从屏幕上方飞来的飞机。本帖只使用纯Python实现,不依赖任何高级库。
本文的AI基于neuro-evolution,首先简单科普一下neuro-evolution。从neuro-evolution这个名字就可以看出它由两部分组成-neuro and evolution,它是使用进化算法(遗传算法是进化算法的一种)提升人工神经网络的机器学习技术,其实就是用进化算法改进并选出最优的神经网络。如果你觉得这篇文章看起来稍微还有些吃力,或者想要更系统地学习人工智能,那么推荐你去看床长人工智能教程。非常棒的大神之作,我也被圈粉了。教程不仅通俗易懂,而且很风趣幽默。点击这里可以查看教程。
neuro-evolution
定义一些变量:
-
import math
-
import random
-
-
# 神经网络3层, 1个隐藏层; 4个input和1个output
-
network = [
4, [
16],
1]
-
# 遗传算法相关
-
population =
50
-
elitism =
0.2
-
random_behaviour =
0.1
-
mutation_rate =
0.5
-
mutation_range =
2
-
historic =
0
-
low_historic =
False
-
score_sort =
-1
-
n_child =
1
- 1
定义神经网络:
-
# 激活函数
-
def sigmoid(z):
-
return
1.0/(
1.0+math.exp(-z))
-
# random number
-
def random_clamped():
-
return random.random()*
2
-1
-
-
# "神经元"
-
class Neuron():
-
def __init__(self):
-
self.biase =
0
-
self.weights = []
-
-
def init_weights(self, n):
-
self.weights = []
-
for i
in range(n):
-
self.weights.append(random_clamped())
-
def __repr__(self):
-
return
'Neuron weight size:{} biase value:{}'.format(len(self.weights), self.biase)
-
-
# 层
-
class Layer():
-
def __init__(self, index):
-
self.index = index
-
self.neurons = []
-
-
def init_neurons(self, n_neuron, n_input):
-
self.neurons = []
-
for i
in range(n_neuron):
-
neuron = Neuron()
-
neuron.init_weights(n_input)
-
self.neurons.append(neuron)
-
-
def __repr__(self):
-
return
'Layer ID:{} Layer neuron size:{}'.format(self.index, len(self.neurons))
-
-
# 神经网络
-
class NeuroNetwork():
-
def __init__(self):
-
self.layers = []
-
-
# input:输入层神经元数 hiddens:隐藏层 output:输出层神经元数
-
def init_neuro_network(self, input, hiddens , output):
-
index =
0
-
previous_neurons =
0
-
# input
-
layer = Layer(index)
-
layer.init_neurons(input, previous_neurons)
-
previous_neurons = input
-
self.layers.append(layer)
-
index +=
1
-
# hiddens
-
for i
in range(len(hiddens)):
-
layer = Layer(index)
-
layer.init_neurons(hiddens[i], previous_neurons)
-
previous_neurons = hiddens[i]
-
self.layers.append(layer)
-
index +=
1
-
# output
-
layer = Layer(index)
-
layer.init_neurons(output, previous_neurons)
-
self.layers.append(layer)
-
-
def get_weights(self):
-
data = {
'network':[],
'weights':[] }
-
for layer
in self.layers:
-
data[
'network'].append(len(layer.neurons))
-
for neuron
in layer.neurons:
-
for weight
in neuron.weights:
-