SARAH gagne quelques Neurones (2/2)


Cet article fait suite à l’article précédent SARAH gagne quelques Neurones (1/2)

Eedomus 2.0

Pour interroger le capteur de luminosité j’ai mis à jour le plugin Eedomus en v2.0. Il est maintenant possible de lire ou modifier des périphériques de la box.

[crayon]
exports.action = function(data, callback, config, SARAH){

SARAH.call(‘eedomus’, { ‘periphId’ : LUMENS}, function(options){
var lumens = options.json.last_value;

scenario(state, callback, SARAH);
});
}
[/crayon]

La méthode SARAH.call est une version simplifiée de SARAH.run qui sera disponible en v2.9

Algorithmique

Le plugin scenario peut prendre 2 états: 1 Allumer et 0 Éteindre les lampes de la pièce.

[crayon]
var scenario= function(state, callback, SARAH){
var tts =  »;

if (state == 1){
lights(BUREAU, true, SARAH);
lights(SALON, true, SARAH);
tts = ‘Bonjour’;
}
else {
lights(BUREAU, false, SARAH);
lights(SALON, false, SARAH);
tts = ‘Aurevoir’;
}

callback({‘tts’: tts});
}
[/crayon]

Learn

Le plugin scenario peut être appelé avec un paramètre learn pour apprendre le comportement.

  • Calendrier: learn=false
  • Mouvement: learn=false
  • Reconnaissance vocale: learn=true
  • QR Code: learn=true

Subtilités

1. Les ordres d’éteindre sont toujours exécutés indépendamment de la luminosité:

  • Je vais me coucher: c’est explicite on va pas négocier
  • Je ne suis pas là: il faut faire des économies d’énergie

2. Le temps est très important ! On peut éteindre ou allumer pour des raisons de luminosité mais aussi d’heure de la journée.

[crayon]
set.push({‘input’: {l: lum/100, t: minutes() }, ‘output’: {s: state}});
[/crayon]

Typiquement je vais me coucher, j’éteint explicitement, le réseau apprends mais ce n’est pas lié à la luminosité.

Code

Le code s’initialise avec un set de valeurs prédéterminées.

[crayon]
var brain = require(‘./lib/brain’);
var set = [{‘input’: {l: 100/100, t: 0}, ‘output’: {s: 0}},
{‘input’: {l: 0/100, t: 0}, ‘output’: {s: 1}}];

var net = new brain.NeuralNetwork();
net.train(set);
[/crayon]

La fonction compute() se charge d’améliorer le set et relancer l’apprentissage.
La librairie brain.js impose de refaire tout l’apprentissage. Cela pourrait poser des problèmes de perfs à terme.

[crayon]
var compute = function(learn, state, lum){
if (learn){
set.push({‘input’: {l: lum/100, t: minutes() }, ‘output’: {s: state}});
net.train(set);
return state;
}

// Guess only for switch ‘on’. Not ‘off’
if (state == 1){
return Math.round(net.run({l: lum/100, t: minutes() }).s);
}
return state;
}
[/crayon]

La fonction minutes() retourne le nombre de minutes écoulées dans la journée.

Sauvegarde du réseau

Au moment de l’apprentissage il faut enregistrer l’ensemble des données:
[crayon]
if (learn){
fs.writeFileSync(file, JSON.stringify(set), ‘utf8′);
}
[/crayon]

Au chargement du plugin il faut relire le réseau:
[crayon]
if (fs.existsSync(file)){
set = JSON.parse(fs.readFileSync(file,’utf8’));
}
net.train(set);
[/crayon]

 

Conclusion

Lors d’un mouvement, l’algo détermine en fonction de l’heure et de la luminosité si il faut vraiment allumer les lampes.

Action Apprendre ? Raisonner ?
Mouvement Non Oui
Plus de Mvt Non Non
Vocale On Oui Non
Vocale Off Oui Non

Si SARAH allume alors que ce n’est pas nécessaire. Pour lui apprendre je dois éteindre explicitement.

Mais comme le remarque Giom, SARAH va apprendre qu’il faut éteindre pour (Luminosité + Lampe) alors qu’elle devrait apprendre de ne pas allumer pour (Luminosité)

Il faudra peut-être mémoriser l’état N-1 pendant X minutes. Le code est ici: http://jsfiddle.net/jpencausse/Ukj3t/

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.