|
Het MobileNet model trainen, transfer learning met classificeren terug naar de inleiding
In dit voorbeeld kan je het MobileNet model trainen voor 3 objecten met de labels "rood" , "groen" en "blauw"
De set van training afbeeldingen worden gemaakt door het object in verschillende standen en voor de webcam te houden
en telkens op een label knop te klikken.
Na het aanmaken van de afbeeldingen wordt door op de "trainer" knop te klikken het model getraind.
Om een nieuwe training te starten moet je de pagina verversen.
transfer learning
In regel 14 wordt het MobileNet model als featureExtractor geladen dat oa geschikt is om kenmerken (de gewichten)
en het aantal outputneuronen (labels) te veranderen.
In regel 15 krijgt het model 3 labels (rood, groen en blauw).
Door op de knopjes te klikken worden afbeeldingen met deze labels aan de classifier toegevoegd.
Als er voldoende afbeeldingen aan de classifier zijn toegevoegd wordt met de trainer knop de train methode uitgevoerd (regel 36)
Als de trainiing compleet is wordt de classify methode (regel 56) gestart en via de callback de toonResult functie gestart.
De toonResult functie is een loop, dit tgv de toonResult callback in regel 68.
De labels en confidence van de eerste cel van het array worden aan de draw() functie gegeven.
Het getrainde model kan worden gedownload als model.json (is de structuur van het netwerk) en model.weights.bin, met de gewichten ingesteld tijdens de training.
anonymous functions
Als argument in mousePressed (regel 21, 25, 29, 34 en 39) staat een functie, deze functies hebben geen naam vandaar anonymous.
Zie deze introductie over anonymous functions
let featureExtractor;
let classifier;
let video;
let labels = '';
let conf = '';
function setup() {
createCanvas(540, 380);
video = createCapture(VIDEO);
video.hide();
background(0);
//Het model laden dat geschikt is om kenmerken te veranderen
featureExtractor = ml5.featureExtractor('MobileNet', modelGeladen);
const options = { numLabels: 3 }; //Het model krijgt 3 outputlabels
classifier = featureExtractor.classification(video, options, videoReady);
//het aanmaken van de knoppen
//Via het mousePressed argument wordt een functie aangemaakt die een image
//met de labels "rood","groen" en "blauw" aan de classifier toevoegd
roodKnop = createButton('rood');
roodKnop.mousePressed(function() {
classifier.addImage('rood')});
groenKnop = createButton('groen');
groenKnop.mousePressed(function() {
classifier.addImage('groen')});
blauwKnop = createButton('blauw');
blauwKnop.mousePressed(function() {
classifier.addImage('blauw')});
//Als er voldoende afbeeldingen aan de classifier zijn toegevoegd
//wordt met de trainer knop de train methode uitgevoerd.
trainknop = createButton('trainer');
trainknop.mousePressed(function() {
//via de callback "training" volgt de training functie de voortgang van de training
classifier.train(training);});
//Door de opslaanknop wordt model.json en model.weights.bin gedownload
opslaanknop = createButton('model downloaden');
opslaanknop.mousePressed(function() {
classifier.save();});
}
function modelGeladen(){
console.log('het model is geladen');
}
function videoReady() {
console.log('De video is klaar');
}
//Als de training compleet is wordt de classifier gestart en de toonResult functie uitgevoerd
//de loss functie berekend de error
function training(loss){
if (loss == null) {
console.log('training complete');
classifier.classify(toonResult);
} else {
console.log(loss);
}
}
//toonResult is een loop die de videobeelden classificeert
function toonResult(error, result) {
if (error){
console.error(error);
} else {
labels = result[0].label;
conf = result[0].confidence;
classifier.classify(toonResult);
}
}
function draw(){
background(0);
//de afbeelding is korter dan het canvas zo verschijnt de tekst in een zwarte band
image(video,0,0,540,340);
fill(255);
textSize(20);
text("dit is ",10, height-15);
text(labels,60, height-15);
//de betrouwbaarheid
conf = conf*100; //geeft 2 cijfers voor de komma
conf = round(conf, 2); //twee cijfers achter de komma
text("betrouwbaarheid = ",150, height-15);
text(conf,330, height-15);
text("%",400, height-15);
}