Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DÉCOUVRIR LA NEUROÉVOLUTION EN CRÉANT UNE VOITU...

DÉCOUVRIR LA NEUROÉVOLUTION EN CRÉANT UNE VOITURE AUTONOME DANS SON NAVIGATEUR

Quoi de mieux que d'apprendre par le jeu, me suis-je dit. Quelques heures plus tard, me voilà à créer un jeu de voitures rudimentaire dans mon navigateur afin de tenter de comprendre la neuroévolution. Je vous propose de refaire ensemble ce parcours initiatique.

On passera d'abord la première en mettant en place la boucle de jeu avec la physique et le dessin dans un canvas, la seconde, en équipant notre voiture de lidars, puis la troisième en lui greffant un cerveau à base de réseau de neurones artificiels. Et enfin on mettra le turbo, en lui donnant les moyens d'apprendre à se déplacer grâce à la neuroévolution.

Ce talk cherche à démocratiser au plus grand nombre, les principes de la neuroévolution et des algorithmes génétiques, mais aussi de vous faire découvrir des techniques de gamedev, comme le raycasting, le tout en JavaScript, dans le navigateur.

Christope Camicas

October 01, 2019
Tweet

Other Decks in Technology

Transcript

  1. Complexité Collecter les données Développement long Entrainement trèèès long function

    getPositions() marioX = memory.read_s16_le(0x94) marioY = memory.read_s16_le(0x96) local layer1x = memory.read_s16_le(0x1A); local layer1y = memory.read_s16_le(0x1C); screenX = marioX-layer1x screenY = marioY-layer1y
  2. Navigateur ? JavaScript is the new BASIC Intelligence @ Edge

    - alléger l'infra (les coûts) - utiliser la puissance de calcul locale - GPU / NPU - sécurisation des données
  3. class Car { constructor(pos) { this.pos = pos.copy() this.vel =

    createVector(0, 0) this.acc = createVector(0, 0) this.heading = 0 } }
  4. M P O OP = OM + MP Arrivée -

    Départ MP = OP - OM
  5. draw() { stroke(0, 148, 255) // I'm blue strokeWeight(8) point(this.pos.x,

    this.pos.y) strokeWeight(4) let h = p5.Vector.fromAngle(this.heading) h.setMag(10) h.add(this.pos) line(this.pos.x, this.pos.y, h.x, h.y) }
  6. class Car { constructor(pos) { this.pos = pos.copy() this.vel =

    createVector(0, 0) this.acc = createVector(0, 0) this.heading = 0 } }
  7. accelerate() { this.acc = p5.Vector.fromAngle(this.heading) this.acc.mult(0.1) } decelerate() { this.acc

    = p5.Vector.fromAngle(this.heading) this.acc.mult(-0.1) } rotate(offset) { this.heading += offset this.acc.rotate(offset) this.vel.rotate(offset) }
  8. class Wall { constructor(x1, y1, x2, y2) { this.start =

    createVector(x1, y1) this.end = createVector(x2, y2) } }
  9. class Car { constructor(...) { this.lidar = [] for (let

    angle = 0; angle < TWO_PI; angle += TWO_PI / 8) { this.lidar.push(new Ray(angle)) } } }
  10. function cross2d(v1, v2) { return v1.x * v2.y - v2.x

    * v1.y } const s = p5.Vector.sub(w.end, w.start) const t = cross2d(p5.Vector.sub(w.start, this.start), s) / cross2d(r, s) const u = cross2d(p5.Vector.sub(this.start, w.start), r) / cross2d(s, r)
  11. Distance Ray1 Distance Ray2 ... Input Layer Hidden Layer Output

    Layer Accelerate Decelerate Turn left Turn right Where the magic happens
  12. Distance Ray1 Distance Ray2 ... Input Layer Hidden Layer Output

    Layer Accelerate Decelerate Turn left Turn right
  13. Distance Ray1 Distance Ray2 ... Input Layer Hidden Layer Output

    Layer Accelerate Decelerate Turn left Turn right
  14. Distance Ray1 Distance Ray2 ... Input Layer Hidden Layer Output

    Layer Accelerate Decelerate Turn left Turn right
  15. Distance Ray1 Distance Ray2 ... Input Layer Hidden Layer Output

    Layer Accelerate Decelerate Turn left Turn right w1 … w8
  16. Distance Ray1 Distance Ray2 ... Input Layer Hidden Layer Output

    Layer Accelerate Decelerate Turn left Turn right w1 … w8 w’1 … w’8 w”1 … w”8 …
  17. Distance Ray1 Distance Ray2 ... Input Layer Hidden Layer Output

    Layer Accelerate Decelerate Turn left Turn right w 8x8 Tensor !
  18. Distance Ray1 Distance Ray2 ... Input Layer Hidden Layer Output

    Layer Accelerate Decelerate Turn left Turn right w 8x8 Tensor ! w 4x8 Tensor !
  19. let model = tf.sequential() // hidden layer model.add(tf.layers.dense({ units: 8,

    // 8 neurons inputShape: [8], // 8 inputs / lidars activation: 'relu6' }))
  20. let model = tf.sequential() // hidden layer model.add(tf.layers.dense({ units: 8,

    // 8 neurons inputShape: [8], // 8 inputs / lidars activation: 'relu6' })) // 1. convert all scores to probabilities // 2. sum of all probabilities is 1 model.add(tf.layers.dense({ units: 4, // 4 outputs ⬅➡⬆⬇ activation: 'softmax' }))
  21. • Population ensemble de solutions possibles • Individu une des

    solutions • Chromosome ensemble des caractéristiques • Gène codage d’une caractéristique
  22. cars = [] for (let i = 0; i <

    POPULATION_SIZE; i++) { let car = new Car() cars.push(car) } Population
  23. function roulettePick(parents, pick) { let current = 0 for (const

    parent of parents) { current += parent.currentScore if (current > pick) { return parent } } } let pickA = random(0, totalFitness) let pickB = random(0, totalFitness) let parentA = roulettePick(bestCars, pickA) let parentB = roulettePick(bestCars, pickB)
  24. const myWeights = this.model.getWeights() const otherWeights = otherBrain.model.getWeights() for (let

    i = 0; i < myWeights.length; i++) { let myTensor = myWeights[i] let otherTensor = otherWeights[i] let myValues = myTensor.dataSync().slice() let otherValues = otherTensor.dataSync().slice() for (let j = 0; j < myValues.length; j++) { if (j % 2 === 0) myValues[j] = otherValues[j] }
  25. for (let i = 0; i < weights.length; i++) {

    let tensor = weights[i] let values = tensor.dataSync().slice() for (let j = 0; j < values.length; j++) { if (random(1) < rate) { let w = values[j] //actual mutation values[j] = randomGaussian() } }
  26. Ça sert à quoi ? • Ordonnancement de tâches •

    Collecte et distribution • Problème du voyageur de commerce • Motorola : tests automatisés ◦ Non régression ◦ Couverture de code • Sony Aibo
  27. Et le reste ? • Reinforcement Learning Q-Learning, DDPG, …

    • NEAT : Neuroevolution of Augmenting Topologies