|
objecten classificeren met 3 opnieuw getrained modellen. terug naar de inleiding
De modellen zijn aangemaak en gedownload in de schets "het MobileNet model trainen".
Het model bestaat uit de bestanden "model.json" met de structuur van het netwerk en het bestand "model.weights.bin" met de getrainde gewichten.
Een model wordt, door op een van de knopjes te klikken, geladen met de load methode, een objectmethode van featureExtractor.
Het mobileNet featureExtractor model wordt ook geladen (regel 15). Ik begrijp niet goed waarom dat nodig is
Na het laden van een model duurt het in mijn computer 10 tot 20 seconde tot het model goed werkt.
De 3 getrainde modellen: model 1, harten 2, 4 en 6 , model 2 klaver 3 , 7 en 10 , model 3 met een rode, groene en grijze ruit.
De modellen hebben natuurlijk "rood", "groen" en "blauw" als label
foutmeldingen
1) ml5.min.js:35 GET http://127.0.0.1:3000/model.weights.bin 404 (Not Found)
Deze fout verholpen door, classifier.load('model.json', eigenModelGeladen); te vervangen door classifier.load('./model.json', eigenModelGeladen);
mogelijke verklaring: De pad aanduiding in model.json naar model.weights.bin start met ./ , op het internet geen verklaring gevonden
2) sketch.js:40 Error: pixels passed to tf.browser.fromPixels() can not be null
Deze fout ontstaat als de video output eerder is geladen dan model.weights.bin van het eigen model.
De video stuurt data naar het nog niet geladen model. zie github issue 241.
In onderstaande schets dit verholpen door de modellen te laden door op een knopje te klikken. (regel 21, 27 en 33)
let featureExtractor;
let classifier;
let video;
let labels = '';
let conf = '';
let model ='er is nog geen model geladen';
function setup() {
createCanvas(540, 410);
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);
model1Knop = createButton('model 1 laden');
model1Knop.mousePressed(function() {
classifier.load('model1/model.json', eigenModelGeladen);
model = 'model 1 is geladen';
console.log('model 1 is geladen')});
model2Knop = createButton('model 2 laden');
model2Knop.mousePressed(function() {
classifier.load('model2/model.json', eigenModelGeladen);
model = 'model 2 is geladen';
console.log('model 2 is geladen')});
model3Knop = createButton('model 3 laden');
model3Knop.mousePressed(function() {
classifier.load('model3/model.json', eigenModelGeladen);
model = 'model 3 is geladen';
console.log('model 3 is geladen')});
}
function modelGeladen(){
console.log('het MobileNet model is geladen');
}
function eigenModelGeladen() {
classifier.classify(toonResult);
}
function videoReady() {
console.log('De video is klaar');
console.log('ml5 version:', ml5.version);
}
//toonResult is een loop die de videobeelden classifceert
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-40);
text(labels,60, height-40);
//de betrouwbaarheid
conf = conf*100; //geeft 2 cijfers voor de komma
conf = round(conf, 2); //twee cijfers achter de komma
text("betrouwbaarheid = ",150, height-40);
text(conf,330, height-40);
text("%",400, height-40);
text(model,10, height-15);
}