Maschinelles Lernen mit Node.js Verwenden der Tensorflow.js-Bibliothek

Hallo allerseits, Kollegen!

Vielleicht haben sich auch die Fans der Tensorflow-Bibliothek, die dieses Buch bereits in unserer Vorbestellung bemerkt haben, die Möglichkeiten des maschinellen und tiefen Lernens im Browser genau angesehen , zumal Francois Schollet selbst das Thema nicht ignorierte . Wir laden Interessierte ein, wo beschrieben wird, wie die Bibliothek von Tensorflow.js Bilder erkennt.

TensorFlow.js ist eine neue Version der beliebten Open Source-Bibliothek, die JavaScript mit umfassenden Lernfunktionen bereichert. Entwickler können jetzt Modelle mithilfe der übergeordneten Bibliotheks-API definieren, trainieren und ausführen.

Dank vorgefertigter Modelle können Entwickler jetzt komplexe Aufgaben wie Mustererkennung , Musikgenerierung oder die Bestimmung menschlicher Positionen in nur wenigen Zeilen JavaScript problemlos lösen.

Tensorflow.js begann als Front-End-Bibliothek für die Arbeit in einem Browser, aber dieses Jahr wurde die experimentelle Unterstützung für Node.js hinzugefügt. Daher kann TensorFlow.js auch in JavaScript-Backend-Anwendungen verwendet werden, sodass wir nicht mehr auf Python zurückgreifen müssen.

Als ich über diese Bibliothek las, beschloss ich, sie an einer einfachen Aufgabe auszuprobieren ...
Verwenden Sie TensorFlow.js zur visuellen Erkennung von Bildern auf Bildern, wenn Sie JavaScript von Node.js verwenden
Leider beschreiben die Dokumentations- und Codebeispiele hauptsächlich die Verwendung dieser Bibliothek im Browser. Projektdienstprogramme , die das Laden und Verwenden von vorab trainierten Modellen zum Zeitpunkt des Schreibens vereinfachen sollten, unterstützten Node.js nicht. Ich musste viel Zeit damit verbringen, Typoskript-Quellen für diese Bibliothek gut zu lesen.

Nach ein paar Tagen des Austauschs habe ich es trotzdem getan! Hurra!

Bevor wir mit einer detaillierten Analyse des Codes fortfahren, wollen wir uns mit anderen Implementierungen der TensorFlow-Bibliothek befassen.

Tensorflow

TensorFlow ist eine kostenlose Softwarebibliothek für maschinelles Lernen. Mit TensorFlow können neuronale Netze erstellt und andere Deep-Learning-Algorithmen implementiert werden.

Dies ist eine Bibliothek, die im November 2015 von Google veröffentlicht wurde und ursprünglich in Python geschrieben wurde . Für das Training und die Bewertung der erstellten Modelle werden Berechnungen auf einer CPU oder GPU verwendet. Ursprünglich wurde diese Bibliothek für die Arbeit auf Hochleistungsservern mit ressourcenintensiven GPUs erstellt.

Dank der jüngsten Aktualisierungen konnte diese Bibliothek optimiert und in Umgebungen mit begrenzten Ressourcen verwendet werden - beispielsweise auf Mobilgeräten und Webbrowsern.

TensorFlow Lite

Tensorflow Lite , die Lite-Version dieser Bibliothek für mobile Geräte und eingebettete Systeme, wurde im Mai 2017 veröffentlicht. Zusammen mit diesem wird ein neuer Satz vorgefertigter Tiefenmodelle für Aufgaben im Zusammenhang mit der Mustererkennung bereitgestellt. Diese Sammlung heißt MobileNet . MobileNet-Modelle wurden speziell für den effizienten Betrieb in Umgebungen mit begrenzten Ressourcen wie mobilen Geräten entwickelt.

TensorFlow.js

Nach Tensorflow Lite wurde TensorFlow.js im März 2018 angekündigt . Diese Version der Bibliothek kann in einem Browser ausgeführt werden und basiert auf einem früheren Projekt namens deeplearn.js . WebGL bietet GPU-Zugriff auf die Bibliothek. Entwickler verwenden die JavaScript-API, um Modelle zu trainieren, zu laden und auszuführen.

Später wurde TensorFlow.js erweitert, um mit Node.js zu arbeiten. tfjs-node wird das tfjs-node die tfjs-node verwendet.

Importieren Sie vorhandene Modelle in TensorFlow.js

Mit der Bibliothek TensorFlow.js können vorgefertigte TensorFlow- und Keras-Modelle ausgeführt werden. Bevor Sie das Modell ausführen, müssen Sie mit diesem Tool in ein neues Format konvertieren. Auf Github stehen vorab trainierte und transformierte Modelle zum Klassifizieren von Bildern, Definieren von Posen und Erkennen von k-nächsten Nachbarn zur Verfügung .

Verwenden von TensorFlow.js mit Node.js

Installieren Sie die TensorFlow-Bibliotheken

TensorFlow.js kann über die NPM-Registrierung installiert werden .


 npm install @tensorflow/tfjs @tensorflow/tfjs-node // ... npm install @tensorflow/tfjs @tensorflow/tfjs-node-gpu 

Beide Erweiterungen für Node.js verwenden native Abhängigkeiten, die bei Bedarf kompiliert werden.

Laden Sie die TensorFlow-Bibliotheken herunter

Die JavaScript-API für Tensorflow wird aus der Kernbibliothek bereitgestellt. In Erweiterungsmodulen, die Node.js unterstützen, werden keine Erweiterungs-APIs bereitgestellt.

  const tf = require('@tensorflow/tfjs') //   ( CPU) require('@tensorflow/tfjs-node') //    ( GPU) require('@tensorflow/tfjs-node-gpu') 

Laden Sie TensorFlow Models herunter

TensorFlow.js bietet eine NPM-Bibliothek ( tfjs-models ), die das Laden von vorab trainierten und transformierten Modellen zum Klassifizieren von Bildern , Definieren von Posen und Erkennen von k-nächsten Nachbarn vereinfacht.

Das Bildklassifizierungsmodell von MobileNet ist ein tiefes neuronales Netzwerk, das darauf trainiert ist, zwischen 1000 verschiedenen Bildklassen zu unterscheiden.

In der README-Datei für das Projekt als Beispiel wird der folgende Code zum Laden des Modells verwendet.

 import * as mobilenet from '@tensorflow-models/mobilenet'; //   const model = await mobilenet.load(); 

Eines der ersten Probleme, auf das ich zufällig gestoßen bin, ist, dass dieser Code nicht mit Node.js funktioniert.

 Error: browserHTTPRequest is not supported outside the web browser. 

Nach Prüfung des Quellcodes sehen wir, dass die Mobilet-Bibliothek ein Wrapper für die tf.Model Klasse ist. Beim Aufruf lädt die load() -Methode automatisch die erforderlichen Modelldateien herunter, die sich an einer externen HTTP-Adresse befinden, und instanziiert das TensorFlow-Modell.

Die Erweiterung Node.js unterstützte zum Zeitpunkt des Schreibens noch keine HTTP-Anforderungen für das Abrufen dynamischer Modelle. Alles, was blieb, war das manuelle Laden der Modelle in das Dateisystem.

Nachdem ich jedoch den Quellcode der Bibliothek gelesen hatte, fand ich eine Problemumgehung ...

Modelle aus dem Dateisystem herunterladen

Wenn die MobileNet-Klasse manuell erstellt wird, können Sie die Lademethode des Moduls nicht aufrufen, sondern den automatisch generierten Variablenpfad mit der HTTP-Adresse des Modells neu schreiben und diese Adresse durch den lokalen Pfad im Dateisystem ersetzen. Wenn danach die load in der Klasseninstanz aufgerufen wird, wird die Loader- Klasse des Dateisystems ausgelöst . In diesem Fall lehnen wir die Verwendung eines browserbasierten HTTP-Downloaders ab.

 const path = "mobilenet/model.json" const mn = new mobilenet.MobileNet(1, 1); mn.path = `file://${path}` await mn.load() 

Cool, alles funktioniert!

Aber woher kommen die Modelldateien?

MobileNet-Modelle

Modelle für TensorFlow.js bestehen aus zwei Dateitypen: einer im JSON-Format gespeicherten Modellkonfigurationsdatei und im Binärformat gespeicherten Modellgewichten. Modellgewichte werden häufig in viele Teile fragmentiert, um das Browser-Caching zu optimieren.

Nachdem wir den automatischen Download-Code für MobileNet-Modelle berücksichtigt haben, sehen wir, dass die Modelle, ihre Konfigurationen und Gewichtsfragmente unter der folgenden Adresse aus dem öffentlichen Container extrahiert werden.

 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v${version}_${alpha}_${size}/ 

Die Vorlagenparameter in der URL beschreiben die hier aufgeführten Modellversionen. Die resultierende Klassifizierungsgenauigkeit wird ebenfalls auf derselben Seite angezeigt.

Der Quellcode gibt an, dass nur Modelle von MobileNet v1 mit der tensorflow-models/mobilenet heruntergeladen werden können.

Der HTTP-Extraktionscode lädt die Datei model.json vom Speicherort herunter und wählt dann rekursiv alle Fragmente von Modellen mit referenzierten Gewichten aus. Dies sind Dateien im Format groupX-shard1of1 .

Manuelles Herunterladen von Modellen

Wenn Sie alle Modelldateien im Dateisystem speichern möchten, können Sie Folgendes tun: Extrahieren Sie die Konfigurationsdatei des Modells, analysieren Sie die Syntax aller gewichteten Dateien, auf die in der Konfigurationsdatei verwiesen wird, und laden Sie dann jede gewichtete Datei manuell herunter.
Ich wollte das MobileNet V1-Modul mit einem Alpha-Wert von 1,0 und einem Bild von 224 Pixel verwenden . Daher erhalte ich die folgende URL für die Modellkonfigurationsdatei.

 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_1.0_224/model.json 

Sobald diese Datei lokal heruntergeladen wurde, können Sie mit dem jq Tool die Namen aller gewichteten Dateien analysieren.

 $ cat model.json | jq -r ".weightsManifest[].paths[0]" group1-shard1of1 group2-shard1of1 group3-shard1of1 ... 

Mit dem sed Tool können Sie dem Namen jedes HTTP-Elements eine URL voranstellen, um eine URL für jede Gewichtungsdatei zu generieren.

 $ cat model.json | jq -r ".weightsManifest[].paths[0]" | sed 's/^/https:\/\/storage.googleapis.com\/tfjs-models\/tfjs\/mobilenet_v1_1.0_224\//' https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_1.0_224/group1-shard1of1 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_1.0_224/group2-shard1of1 https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_1.0_224/group3-shard1of1 ... 

Mit den Befehlen parallel und curl können Sie dann alle diese Dateien in mein lokales Verzeichnis herunterladen.

 cat model.json | jq -r ".weightsManifest[].paths[0]" | sed 's/^/https:\/\/storage.googleapis.com\/tfjs-models\/tfjs\/mobilenet_v1_1.0_224\//' | parallel curl -O 

Bildklassifizierung

Dieser mit TensorFlow.js bereitgestellte Beispielcode zeigt, wie das Ergebnis der Bildklassifizierung zurückgegeben wird.

 const img = document.getElementById('img'); //   const predictions = await model.classify(img); 

Dies funktioniert in Node.js aufgrund mangelnder DOM-Unterstützung nicht.

Die classify akzeptiert verschiedene DOM-Elemente ( canvas , video , image ) und extrahiert und konvertiert automatisch die "Bild" tf.Tensor3D aus diesen Elementen in die Klasse tf.Tensor3D , die als Modelleingabe verwendet wird. Alternativ tf.Tensor3D direkt übertragen werden.

Ich habe beschlossen, nicht zu versuchen, ein externes Paket zu verwenden, um ein DOM-Element manuell zu simulieren, habe jedoch festgestellt, dass tf.Tensor3D einfacher manuell zusammenzusetzen ist .

Wir erzeugen Tensor3D aus dem Bild

Beim Lesen des Quellcodes der Methode zum Konvertieren von DOM-Elementen in Tensor3D-Klassen stellen wir fest, dass die folgenden Eingabeparameter zum Generieren der Tensor3D-Klasse verwendet werden.

 const values = new Int32Array(image.height * image.width * numChannels); //     ,    const outShape = [image.height, image.width, numChannels]; const input = tf.tensor3d(values, outShape, 'int32'); 

pixels ist ein zweidimensionales Array vom Typ (Int32Array) das eine sequentielle Liste von (Int32Array) für jedes Pixel enthält. numChannels ist die Anzahl der numChannels pro Pixel.

Eingabewerte für JPEG erstellen

Die jpeg-js Bibliothek ist ein JPEG-Encoder / Decoder für Node.js, der in reinem JavaScript geschrieben ist. Mit dieser Bibliothek können Sie RGB-Werte für jedes Pixel extrahieren.

 const pixels = jpeg.decode(buffer, true); 

Als Ergebnis erhalten wir ein Uint8Array mit vier Kanalwerten ( RGBA ) für jedes Pixel ( width * height ). Das MobileNet-Modell verwendet nur drei Farbkanäle ( RGB ) zur Klassifizierung, der Alphakanal wird ignoriert. Dieser Code konvertiert ein Vier-Kanal-Array in eine echte Drei-Kanal-Version.

  const numChannels = 3; const numPixels = image.width * image.height; const values = new Int32Array(numPixels * numChannels); for (let i = 0; i < numPixels; i++) { for (let channel = 0; channel < numChannels; ++channel) { values[i * numChannels + channel] = pixels[i * 4 + channel]; } } 

Eingabeanforderungen für MobileNet-Modelle

Das hier verwendete MobileNet-Modell klassifiziert Bilder mit einer Höhe von 224 Pixel und einer Breite. Eingangstensoren müssen Gleitkommawerte im Bereich von -1 bis 1 für jeden der drei Kanalwerte jedes Pixels enthalten.

Eingabewerte für Bilder mit einer anderen Dimension müssen vor der Klassifizierung in die richtige Größe konvertiert werden. Außerdem liegen die vom JPEG-Decoder erhaltenen Pixelwerte im Bereich von 0 bis 255 und nicht von -1 bis 1. Diese Werte müssen vor der Klassifizierung ebenfalls konvertiert werden.

TensorFlow.js verfügt über Bibliotheksmethoden, um diesen Prozess zu vereinfachen. Noch besser ist jedoch, dass es eine spezielle tfjs-models/mobilenet , die dieses Problem automatisch löst !

Der Entwickler kann Eingabe-Tensor3Ds vom Typ int32 sowie verschiedene Dimensionen an die classify , die die Eingabewerte vor der Klassifizierung in das richtige Format übersetzt. Das heißt, wir haben hier nichts zu tun. Großartig!

Vorhersagen erhalten

Die MobileNet-Modelle von Tensorflow lernen, Objekte aus den 1000 wichtigsten Klassen aus dem ImageNet- Datensatz zu erkennen . Geben Sie am Ausgang des Modells Wahrscheinlichkeitswerte an, die die Chancen charakterisieren, diese Objekte im klassifizierten Bild zu finden.

Eine vollständige Liste der trainierten Klassen für das verwendete Modell befindet sich in dieser Datei .

Die tfjs-models/mobilenet bietet die classify in der MobileNet Klasse, die das Top-X der wahrscheinlichsten Klassen basierend auf den in der Abbildung gezeigten tfjs-models/mobilenet zurückgibt.

 const predictions = await mn_model.classify(input, 10); 

predictions ist ein Array von X-Klassen und Wahrscheinlichkeiten im folgenden Format.

  { className: 'panda', probability: 0.9993536472320557 } 

Beispiel

Wir haben also herausgefunden, wie die TensorFlow.js-Bibliothek und die MobileNet-Modelle in Node.js verwendet werden, und überlegen nun, wie dieses Skript das als Befehlszeilenargument angegebene Bild klassifiziert.

Quellcode

Speichern Sie diese Skriptdatei und den Paketdeskriptor in lokalen Dateien.

 { "name": "tf-js", "version": "1.0.0", "main": "script.js", "license": "MIT", "dependencies": { "@tensorflow-models/mobilenet": "^0.2.2", "@tensorflow/tfjs": "^0.12.3", "@tensorflow/tfjs-node": "^0.1.9", "jpeg-js": "^0.3.4" } } 

 const tf = require('@tensorflow/tfjs') const mobilenet = require('@tensorflow-models/mobilenet'); require('@tensorflow/tfjs-node') const fs = require('fs'); const jpeg = require('jpeg-js'); const NUMBER_OF_CHANNELS = 3 const readImage = path => { const buf = fs.readFileSync(path) const pixels = jpeg.decode(buf, true) return pixels } const imageByteArray = (image, numChannels) => { const pixels = image.data const numPixels = image.width * image.height; const values = new Int32Array(numPixels * numChannels); for (let i = 0; i < numPixels; i++) { for (let channel = 0; channel < numChannels; ++channel) { values[i * numChannels + channel] = pixels[i * 4 + channel]; } } return values } const imageToInput = (image, numChannels) => { const values = imageByteArray(image, numChannels) const outShape = [image.height, image.width, numChannels]; const input = tf.tensor3d(values, outShape, 'int32'); return input } const loadModel = async path => { const mn = new mobilenet.MobileNet(1, 1); mn.path = `file://${path}` await mn.load() return mn } const classify = async (model, path) => { const image = readImage(path) const input = imageToInput(image, NUMBER_OF_CHANNELS) const mn_model = await loadModel(model) const predictions = await mn_model.classify(input) console.log('classification results:', predictions) } if (process.argv.length !== 4) throw new Error('incorrect arguments: node script.js <MODEL> <IMAGE_FILE>') classify(process.argv[2], process.argv[3]) 

Testen

Laden Sie die Modelldateien gemäß den obigen Anweisungen in das mobileet-Verzeichnis herunter.
Festlegen von Projektabhängigkeiten mithilfe von NPM

npm install

Laden Sie die JPEG-Beispieldatei zur Klassifizierung herunter

wget http://bit.ly/2JYSal9 -O panda.jpg



Führen Sie das Skript aus, dessen Argumente die Modelldatei und das Eingabebild sind.

node script.js mobilenet/model.json panda.jpg

Wenn alles richtig funktioniert hat, sollte die folgende Ausgabe in der Konsole angezeigt werden.

  classification results: [ { className: 'giant panda, panda, panda bear, coon bear', probability: 0.9993536472320557 } ] 

Das Bild ist korrekt als Panda mit einer Wahrscheinlichkeit von 99,93% klassifiziert!

Fazit

Die TensorFlow.js-Bibliothek eröffnet JavaScript-Entwicklern umfassende Lernmöglichkeiten. Durch die Verwendung vorgefertigter Modelle mit der Bibliothek TensorFlow.js können Sie auf einfache Weise neue Funktionen in JavaScript-Anwendungen einbauen, um komplexe Probleme des maschinellen Lernens mit minimalem Aufwand und präzisem Code zu lösen.

Die TensorFlow.js-Bibliothek wurde ausschließlich für die Arbeit in einem Browser erstellt. Jetzt interagiert sie mit Node.js, obwohl nicht alle Tools und Dienstprogramme diese neue Laufzeit unterstützen. Nachdem ich einige Tage an der Bibliothek herumgebastelt hatte, lernte ich, sie mit MobileNet-Modellen zur visuellen Erkennung von Bildern aus einer lokalen Datei zu verwenden.

Source: https://habr.com/ru/post/de432984/


All Articles