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.TensorflowTensorFlow 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 LiteTensorflow 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.jsMit 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.jsInstallieren 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 herunterDie 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')
Laden Sie TensorFlow Models herunterTensorFlow.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';
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 herunterladenWenn 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-ModelleModelle 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 ModellenWenn 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:
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
BildklassifizierungDieser mit TensorFlow.js bereitgestellte
Beispielcode zeigt, wie das Ergebnis der Bildklassifizierung zurückgegeben wird.
const img = document.getElementById('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 BildBeim 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);
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 erstellenDie 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-ModelleDas 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 erhaltenDie 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 }
BeispielWir 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.
QuellcodeSpeichern 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])
TestenLaden 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!
FazitDie 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.