v2 / examples / flappylearning / modules / neuroevolution / neuronevolution.v
287 lines · 260 sloc · 5.27 KB · c51d30bf5309653c6b573ec815268e69a78ea8cc
Raw
1module neuroevolution
2
3import rand
4import math
5
6fn random_clamped() f64 {
7 return rand.f64() * 2 - 1
8}
9
10pub fn activation(a f64) f64 {
11 ap := (-a) / 1
12 return 1 / (1 + math.exp(ap))
13}
14
15fn round(a int, b f64) int {
16 return int(math.round(f64(a) * b))
17}
18
19struct Neuron {
20mut:
21 value f64
22 weights []f64
23}
24
25fn (mut n Neuron) populate(nb int) {
26 for _ in 0 .. nb {
27 n.weights << random_clamped()
28 }
29}
30
31struct Layer {
32 id int
33mut:
34 neurons []Neuron
35}
36
37fn (mut l Layer) populate(nb_neurons int, nb_inputs int) {
38 for _ in 0 .. nb_neurons {
39 mut n := Neuron{}
40 n.populate(nb_inputs)
41 l.neurons << n
42 }
43}
44
45pub struct Network {
46mut:
47 layers []Layer
48}
49
50fn (mut n Network) populate(network []int) {
51 assert network.len >= 2
52 input := network[0]
53 hiddens := network[1..network.len - 1]
54 output := network[network.len - 1]
55 mut index := 0
56 mut previous_neurons := 0
57 mut input_layer := Layer{
58 id: index
59 }
60 input_layer.populate(input, previous_neurons)
61 n.layers << input_layer
62 previous_neurons = input
63 index++
64 for hidden in hiddens {
65 mut hidden_layer := Layer{
66 id: index
67 }
68 hidden_layer.populate(hidden, previous_neurons)
69 previous_neurons = hidden
70 n.layers << hidden_layer
71 index++
72 }
73 mut output_layer := Layer{
74 id: index
75 }
76 output_layer.populate(output, previous_neurons)
77 n.layers << output_layer
78}
79
80fn (n Network) get_save() Save {
81 mut save := Save{}
82 for layer in n.layers {
83 save.neurons << layer.neurons.len
84 for neuron in layer.neurons {
85 for weight in neuron.weights {
86 save.weights << weight
87 }
88 }
89 }
90 return save
91}
92
93fn (mut n Network) set_save(save Save) {
94 mut previous_neurons := 0
95 mut index := 0
96 mut index_weights := 0
97 n.layers = []
98 for save_neuron in save.neurons {
99 mut layer := Layer{
100 id: index
101 }
102 layer.populate(save_neuron, previous_neurons)
103 for mut neuron in layer.neurons {
104 for i in 0 .. neuron.weights.len {
105 neuron.weights[i] = save.weights[index_weights]
106 index_weights++
107 }
108 }
109 previous_neurons = save_neuron
110 index++
111 n.layers << layer
112 }
113}
114
115pub fn (mut n Network) compute(inputs []f64) []f64 {
116 assert n.layers.len > 0
117 assert inputs.len == n.layers[0].neurons.len
118 for i, input in inputs {
119 n.layers[0].neurons[i].value = input
120 }
121 mut prev_layer := n.layers[0]
122 for i in 1 .. n.layers.len {
123 for j, neuron in n.layers[i].neurons {
124 mut sum := f64(0)
125 for k, prev_layer_neuron in prev_layer.neurons {
126 sum += prev_layer_neuron.value * neuron.weights[k]
127 }
128 n.layers[i].neurons[j].value = activation(sum)
129 }
130 prev_layer = n.layers[i]
131 }
132 mut outputs := []f64{}
133 mut last_layer := n.layers[n.layers.len - 1]
134 for neuron in last_layer.neurons {
135 outputs << neuron.value
136 }
137 return outputs
138}
139
140struct Save {
141mut:
142 neurons []int
143 weights []f64
144}
145
146fn (s Save) clone() Save {
147 mut save := Save{}
148 save.neurons << s.neurons
149 save.weights << s.weights
150 return save
151}
152
153struct Genome {
154 score int
155 network Save
156}
157
158struct Generation {
159mut:
160 genomes []Genome
161}
162
163fn (mut g Generation) add_genome(genome Genome) {
164 mut i := 0
165 for gg in g.genomes {
166 if genome.score > gg.score {
167 break
168 }
169 i++
170 }
171 g.genomes.insert(i, genome)
172}
173
174fn (g1 Genome) breed(g2 Genome, nb_child int) []Save {
175 mut datas := []Save{}
176 for _ in 0 .. nb_child {
177 mut data := g1.network.clone()
178 for i, weight in g2.network.weights {
179 if rand.f64() <= 0.5 {
180 data.weights[i] = weight
181 }
182 }
183 for i, _ in data.weights {
184 if rand.f64() <= 0.1 {
185 data.weights[i] += (rand.f64() * 2 - 1) * 0.5
186 }
187 }
188 datas << data
189 }
190 return datas
191}
192
193fn (g Generation) next(population int) []Save {
194 mut nexts := []Save{}
195 if population == 0 {
196 return nexts
197 }
198 keep := round(population, 0.2)
199 for i in 0 .. keep {
200 if nexts.len < population {
201 nexts << g.genomes[i].network.clone()
202 }
203 }
204 random := round(population, 0.2)
205 for _ in 0 .. random {
206 if nexts.len < population {
207 mut n := g.genomes[0].network.clone()
208 for k, _ in n.weights {
209 n.weights[k] = random_clamped()
210 }
211 nexts << n
212 }
213 }
214 mut max := 0
215 out: for {
216 for i in 0 .. max {
217 mut childs := g.genomes[i].breed(g.genomes[max], 1)
218 for c in childs {
219 nexts << c
220 if nexts.len >= population {
221 break out
222 }
223 }
224 }
225 max++
226 if max >= g.genomes.len - 1 {
227 max = 0
228 }
229 }
230 return nexts
231}
232
233pub struct Generations {
234pub:
235 population int
236 network []int
237mut:
238 generations []Generation
239}
240
241fn (mut gs Generations) first() []Save {
242 mut out := []Save{}
243 for _ in 0 .. gs.population {
244 mut nn := Network{}
245 nn.populate(gs.network)
246 out << nn.get_save()
247 }
248 gs.generations << Generation{}
249 return out
250}
251
252fn (mut gs Generations) next() []Save {
253 assert gs.generations.len > 0
254 gen := gs.generations[gs.generations.len - 1].next(gs.population)
255 gs.generations << Generation{}
256 return gen
257}
258
259fn (mut gs Generations) add_genome(genome Genome) {
260 assert gs.generations.len > 0
261 gs.generations[gs.generations.len - 1].add_genome(genome)
262}
263
264fn (mut gs Generations) restart() {
265 gs.generations = []
266}
267
268pub fn (mut gs Generations) generate() []Network {
269 saves := if gs.generations.len == 0 { gs.first() } else { gs.next() }
270 mut nns := []Network{}
271 for save in saves {
272 mut nn := Network{}
273 nn.set_save(save)
274 nns << nn
275 }
276 if gs.generations.len >= 2 {
277 gs.generations.delete(0)
278 }
279 return nns
280}
281
282pub fn (mut gs Generations) network_score(network Network, score int) {
283 gs.add_genome(Genome{
284 score: score
285 network: network.get_save()
286 })
287}
288